int main()
{
do
{
srand(time(NULL));
int n = 0;
menu();
printf("请输入你要选的数字1或者2\n");
scanf("%d", &n);
switch (n)
{
case(1):
game();
break;
case(2):
printf("退出游戏了\n");
case(3):
printf("选择错误\n");
}
} while (1);
}
首先是菜单,menu函数实现
然后根据菜单输入数字,进入游戏或者是退出游戏。
switch语句选择1后进入游戏,接下来就是设计菜单和game函数。
void menu()
{
printf("************************************\n");
printf("************************************\n");
printf("*********1.play 2.exit***********\n");
printf("************************************\n");
printf("************************************\n");
}
void game()
{
char board[ROW][COL] = { 0 };
initboard(board, ROW, COL);
displayboard(board, ROW, COL);
char k = 0;
while (1) {
playermove(board, ROW, COL);
displayboard(board, ROW, COL);
k = judge(board, ROW, COL);
if (k != 'c')
break;
computermove(board, ROW, COL);
displayboard(board, ROW, COL);
if (k == 'Y')
break;
}
if (k != 'c')
printf("玩家赢了\n");
else if (k == '#')
printf("电脑赢了\n");
else
printf("平局\n");
}
可以看见游戏函数的逻辑是,先初始化棋盘,再打印棋盘,然后玩家走一步,打印一次棋盘,然后判断一下游戏情况;电脑走一步,打印一次棋盘,然后判断一下游戏情况。
下面开始分装不同的函数。
这里要说一下,刚刚主函数和菜单以及game的函数是在第一个c文件里面实现的,其次我们要实现game函数里面的具体函数的内容,最好的方式是额外再创建一个文件,并且创建头文件声明一下那些函数。(在公司里面不是一堆人公用一个文件来编写代码的)
void initboard(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
board[i][j] = ' ';
}
}
这是利用2个循环,初始化棋盘为空格
void displayboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
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 playermove(char board[ROW][COL], int row, int col)
{
printf("请输入你要走的坐标");
int a = 0;
int b = 0;
printf("你下棋了\n");
while(1){
scanf("%d %d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col) {
if (board[a - 1][b - 1] == ' ')
board[a - 1][b - 1] = '*';
break;
}
else
printf("下错位置了\n");
}
}
这里需要注意的是,对玩家落子的判断有2个,1判断是否输入坐标超越边界,2判断该坐标是否为空子。
void computermove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋了\n");
int x = 0;
int y = 0;
while (1)
{ x = rand() % row;
y = rand() % col;
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
这里电脑下棋,电脑需要随机下棋,最需要注意的是电脑下棋的时候,rand需要放在循环体内,否则报错。
char judge(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
char flag = 0;
//判断行
for(i=0;i<row;i++)
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][0]!= ' ')
{
return board[i][0];
}
//判断列
for(j=0;j<col;j++)
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
{
return board[0][j];
}
//判断对角线2条
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[2][0] != ' ')
return board[1][1];
//判断平局
//满了返回1,不满返回0
int ret = Draw(board, row, col);
if (ret == 1)
{
return 'Y';
}
return 'c';
}
这里需要注意的是平局判断,顺便把都没有赢且棋盘没满的情况封装在里面,平局函数为draw
int Draw(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{if(board[i][j] == ' ')
return 0;
}
}
return 1;
意思是棋盘满了返回1,没满返回0
如果棋盘没满,那就返回N表示没有输赢情况,且需要继续下棋。
void game()
```c
{
char board[ROW][COL] = { 0 };
initboard(board, ROW, COL);
displayboard(board, ROW, COL);
char k = 0;
while (1) {
playermove(board, ROW, COL);
displayboard(board, ROW, COL);
k = judge(board, ROW, COL);
if (k != 'c')
break;
computermove(board, ROW, COL);
displayboard(board, ROW, COL);
if (k == 'Y')
break;
}
if (k != '*')
printf("玩家赢了\n");
else if (k == '#')
printf("电脑赢了\n");
else
printf("平局\n");}
这里可以看到一条语句if(k !='c‘);跟上面联系起来,如果!=c,表示游戏停止,就要开始判断了。
因为如果不是玩家或者电脑赢也不是平局,就会返回c,所以如果不等于c,就要跳出循环判断一次。