一:问题描述
用c语言实现三子棋游戏
二:基本流程
分析三子棋游戏逻辑:
1.菜单界面选择开始或者退出游戏。 2.创建棋盘并初始化。 3.打印棋盘。 4.玩家落子(玩家输入行列坐标的方式来落子),’*'表示玩家落子。 5.判定胜负关系(输,赢,和棋),‘Q’表示和棋。 6.电脑落子(随机位置落子) ,’#'表示电脑落子。 7.判定胜负关系。 8.回到 步骤2 继续执行。
三:代码模块
3.1菜单界面
void menu ( )
{
printf ( "**************************\n" ) ;
printf ( "*********1.play***********\n" ) ;
printf ( "*********0.exit***********\n" ) ;
printf ( "**************************\n" ) ;
}
3.2创建棋盘
棋盘:使用三行三列二维数组来表示,元素类型是char
使用宏定义: (1)提高代码的可读性,方便理解含义 (2)提高项目的扩展性,方便未来修改棋盘尺寸
# define ROW 3
# define COL 3
char ret = 0 ;
char board[ ROW] [ COL] = { 0 } ;
3.3棋盘初始化
void InitBoard ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
board[ i] [ j] = ' ' ;
}
}
}
3.4打印棋盘
void DisplayBoard ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
printf ( " %c " , board[ i] [ j] ) ;
if ( j < col - 1 ) printf ( "|" ) ;
}
printf ( "\n" ) ;
if ( i < row - 1 )
{
for ( j = 0 ; j < col; j++ )
{
printf ( "___" ) ;
if ( j < col - 1 ) printf ( "|" ) ;
}
printf ( "\n" ) ;
}
}
}
3.5玩家下棋
玩家输入行列坐标(1~3)表示落子,使用’*'表示玩家落子。 注意: 1.玩家落子需要在棋盘范围内。 2.玩家只能在棋盘上空的地方落子。 3.如果输入的坐标不满足要提示坐标非法,重新输入。
void Player_move ( char board[ ROW] [ COL] , int row, int col)
{
int x = 0 ;
int y = 0 ;
printf ( "玩家下棋\n" ) ;
while ( 1 )
{
printf ( "请输入坐标:>" ) ;
scanf ( "%d %d" , & x, & y) ;
if ( x >= 1 && x <= row && y >= 1 && y <= col)
{
if ( board[ x - 1 ] [ y - 1 ] == ' ' )
{
board[ x - 1 ] [ y - 1 ] = '*' ;
break ;
}
else
{
printf ( "该坐标被占用,请重新输入\n" ) ;
}
}
else
{
printf ( "坐标非法,请重新输入\n" ) ;
}
}
}
3.6电脑下棋
采用时间戳,电脑随机产生行列坐标,’#'表示电脑落子。 注意: 1.要在主函数中使用srand((unsigned int)time(null)) 将时间作为随机数种子,确保得到的行列坐标是真随机。 2.要在棋盘上空的地方下棋。 3.注意添加头文件stdlib.h和time.h
void Computer_move ( char board[ ROW] [ COL] , int row, int col)
{
int x = 0 ;
int y = 0 ;
printf ( "电脑下棋:>\n" ) ;
while ( 1 )
{
x = rand ( ) % row;
y = rand ( ) % col;
if ( board[ x] [ y] == ' ' )
{
board[ x] [ y] = '#' ;
break ;
}
}
}
3.7判断输赢
玩家、电脑每下一步棋均需要判断输赢 此处约定返回结果的含义: (1)‘*’ 表示玩家获胜 (2)‘#’ 表示电脑获胜 (3)‘C’ 表示胜负未分 (4) ‘Q’ 表示和棋
1.判定电脑\玩家胜利 (1)判定所有的行 (2)判定所有的列 (3)判定两条对角线 2.判定是否和棋 (1)自定义并调用is_full函数。 (2)如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。 (3)如果棋盘满了未分出胜负,和棋。
static int is_full ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
if ( board[ i] [ j] == ' ' )
{
return 0 ;
}
}
}
return 1 ;
}
char is_win ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
if ( board[ i] [ 0 ] == board[ i] [ 1 ] && board[ i] [ 1 ] == board[ i] [ 2 ] && board[ i] [ 1 ] != ' ' )
{
return board[ i] [ 1 ] ;
}
}
for ( i = 0 ; i < col; i++ )
{
if ( board[ 0 ] [ i] == board[ 1 ] [ i] && board[ 1 ] [ i] == board[ 2 ] [ i] && board[ 1 ] [ i] != ' ' )
{
return board[ 1 ] [ i] ;
}
}
if ( board[ 0 ] [ 0 ] == board[ 1 ] [ 1 ] && board[ 1 ] [ 1 ] == board[ 2 ] [ 2 ] && board[ 1 ] [ 1 ] != ' ' )
{
return board[ 1 ] [ 1 ] ;
}
if ( board[ 0 ] [ 2 ] == board[ 1 ] [ 1 ] && board[ 1 ] [ 1 ] == board[ 2 ] [ 0 ] && board[ 1 ] [ 1 ] != ' ' )
{
return board[ 1 ] [ 1 ] ;
}
if ( is_full ( board, row, col) == 1 )
{
return 'Q' ;
}
return 'C' ;
}
四:结果演示
4.1玩家胜利
4.2电脑胜利
4.3和棋
五:项目源码
# define _CRT_SECURE_NO_WARNINGS 1
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define ROW 3
# define COL 3
void InitBoard ( char board[ ROW] [ COL] , int row, int col) ;
void DisplayBoard ( char board[ ROW] [ COL] , int row, int col) ;
void Player_move ( char board[ ROW] [ COL] , int row, int col) ;
void Computer_move ( char board[ ROW] [ COL] , int row, int col) ;
char is_win ( char board[ ROW] [ COL] , int row, int col) ;
void InitBoard ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
board[ i] [ j] = ' ' ;
}
}
}
void DisplayBoard ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
printf ( " %c " , board[ i] [ j] ) ;
if ( j < col - 1 ) printf ( "|" ) ;
}
printf ( "\n" ) ;
if ( i < row - 1 )
{
for ( j = 0 ; j < col; j++ )
{
printf ( "___" ) ;
if ( j < col - 1 ) printf ( "|" ) ;
}
printf ( "\n" ) ;
}
}
}
void Player_move ( char board[ ROW] [ COL] , int row, int col)
{
int x = 0 ;
int y = 0 ;
printf ( "玩家下棋\n" ) ;
while ( 1 )
{
printf ( "请输入坐标:>" ) ;
scanf ( "%d %d" , & x, & y) ;
if ( x >= 1 && x <= row && y >= 1 && y <= col)
{
if ( board[ x - 1 ] [ y - 1 ] == ' ' )
{
board[ x - 1 ] [ y - 1 ] = '*' ;
break ;
}
else
{
printf ( "该坐标被占用,请重新输入\n" ) ;
}
}
else
{
printf ( "坐标非法,请重新输入\n" ) ;
}
}
}
void Computer_move ( char board[ ROW] [ COL] , int row, int col)
{
int x = 0 ;
int y = 0 ;
printf ( "电脑下棋:>\n" ) ;
while ( 1 )
{
x = rand ( ) % row;
y = rand ( ) % col;
if ( board[ x] [ y] == ' ' )
{
board[ x] [ y] = '#' ;
break ;
}
}
}
static int is_full ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
int j = 0 ;
for ( j = 0 ; j < col; j++ )
{
if ( board[ i] [ j] == ' ' )
{
return 0 ;
}
}
}
return 1 ;
}
char is_win ( char board[ ROW] [ COL] , int row, int col)
{
int i = 0 ;
for ( i = 0 ; i < row; i++ )
{
if ( board[ i] [ 0 ] == board[ i] [ 1 ] && board[ i] [ 1 ] == board[ i] [ 2 ] && board[ i] [ 1 ] != ' ' )
{
return board[ i] [ 1 ] ;
}
}
for ( i = 0 ; i < col; i++ )
{
if ( board[ 0 ] [ i] == board[ 1 ] [ i] && board[ 1 ] [ i] == board[ 2 ] [ i] && board[ 1 ] [ i] != ' ' )
{
return board[ 1 ] [ i] ;
}
}
if ( board[ 0 ] [ 0 ] == board[ 1 ] [ 1 ] && board[ 1 ] [ 1 ] == board[ 2 ] [ 2 ] && board[ 1 ] [ 1 ] != ' ' )
{
return board[ 1 ] [ 1 ] ;
}
if ( board[ 0 ] [ 2 ] == board[ 1 ] [ 1 ] && board[ 1 ] [ 1 ] == board[ 2 ] [ 0 ] && board[ 1 ] [ 1 ] != ' ' )
{
return board[ 1 ] [ 1 ] ;
}
if ( is_full ( board, row, col) == 1 )
{
return 'Q' ;
}
return 'C' ;
}
void play ( )
{
char ret = 0 ;
char board[ ROW] [ COL] = { 0 } ;
InitBoard ( board, ROW, COL) ;
DisplayBoard ( board, ROW, COL) ;
while ( 1 )
{
Player_move ( board, ROW, COL) ;
DisplayBoard ( board, ROW, COL) ;
ret = is_win ( board, ROW, COL) ;
if ( ret != 'C' )
{
break ;
}
Computer_move ( board, ROW, COL) ;
DisplayBoard ( board, ROW, COL) ;
ret = is_win ( board, ROW, COL) ;
if ( ret != 'C' )
{
break ;
}
}
if ( ret == '*' )
{
printf ( "玩家赢\n" ) ;
}
else if ( ret == '#' )
{
printf ( "电脑赢\n" ) ;
}
else
{
printf ( "平局\n" ) ;
}
}
void menu ( )
{
printf ( "**************************\n" ) ;
printf ( "*********1.play***********\n" ) ;
printf ( "*********0.exit***********\n" ) ;
printf ( "**************************\n" ) ;
}
void test ( )
{
int input = 0 ;
srand ( ( unsigned int ) time ( NULL ) ) ;
do
{
menu ( ) ;
printf ( "请选择:>" ) ;
scanf ( "%d" , & input) ;
switch ( input)
{
case 1 :
play ( ) ;
break ;
case 0 :
printf ( "退出游戏\n" ) ;
break ;
default :
printf ( "选择错误\n" ) ;
break ;
}
} while ( input) ;
}
int main ( )
{
test ( ) ;
return 0 ;
}