今天的内容是如何敲打一份简要的三子棋代码
这是声命部分,可以自行以一一对应
#pragma once
#define ROW 3
#define COL 3
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void InitBoard(char board[ROW][COL],int row ,int col );
void Desk(char boaed[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
char Is_Win(char board[ROW][COL], int row, int col);
int Is_Full(char board[ROW][COL], int row, int col);
首先创建一个main函数,打印出三子棋游戏的菜单
void menu()
{
printf("***********************************\n");
printf("******** 1.play ********\n");
printf("******** 0.over ********\n");
printf("***********************************\n");
}
菜单给出了两个选项,1或者0.
于是我们使用Switch函数,分别列出来了如下种情况,而while循环可以让我们在一轮游戏结束后选择是否继续游戏,同时也明示了为什么上述菜单的两个选项是“1”和“0”
int input = 1;
while (input)
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("三子棋\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
}
此时我们打印“0”,会退出游戏,结果如下
而选择“1”,则会进入游戏,即game函数。
首先我们需要一个棋盘,这里使用到了二维数组
char board[ROW][COL] = { 0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//显示棋盘
Desk(board, ROW, 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 Desk(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)
{
int j = 0;
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 i = 0;
int j = 0;
while (1)
{
scanf("%d %d", &i, &j);
if (i >= 1 && i <= row && j >= 1 && j <= col)
{
if (board[i - 1][j - 1] == ' ')
{
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("坐标非法,请重新输入坐标\n");
}
}
else
{
printf("坐标非法,请重新输入坐标\n");
}
}
}
值得注意的是我们所选择的坐标必须是“空格”,即没有被下过子的位置,否则就会被要求重新选择位置。为什么这里“i”和“j”要减去1?因为就玩家而言,玩家并不知道数组的下标是从0开始,考虑的普适性,这里i和j的范围是1,2,3.
下面是电脑下棋,值得注意的是,电脑并不需要上述所说的普适性,所以就不必减一
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋\n");
while (1)
{
srand((unsigned int)time(NULL));
int i = rand() % ROW;
int j = rand() % COL;
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
每落一个子,我们都要进行进行输赢的判断
三子棋的赢,无非是从三个角度来判断,即三行,三列,交叉
下面是三行
//三行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&&board[i][0]!=' ')
{
if (board[i][0] == '*')
{
return '*';
}
else if (board[i][0] == '#')
{
return '#';
}
}
}
下面是三列
//三列
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[i][0] != ' ')
{
if (board[i][1] == '*')
{
return '*';
}
else if (board[i][1] == '#')
{
return '#';
}
}
}
交叉
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[i][0] != ' ')
{
if (board[1][1] == '*')
{
return '*';
}
else if (board[1][1] == '#')
{
return '#';
}
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[i][0] != ' ')
{
if (board[0][2] == '*')
{
return '*';
}
else if (board[0][2] == '#')
{
return '#';
}
}
至于返回值的利用,我们暂且不谈,就当是埋一个伏笔,后面再说明
在这个代码中,判断的结果有四种:胜,负,平,以及继续下棋
上面我们讲了胜负,那么平局呢?
int Is_Full(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;
}
这里我们运用另一个函数,如上,我们遍历了棋盘上的每一个位置,根据不同的结果,分别反回了不同的值,返回值有什么用呢?
//判断是否平局
if (Is_Full(board,row,col))
{
return 'd';
}
为了这么一段小小的代码,
上述的判断输赢的代码其实可以放在一个Is_Win()函数中,而在最后,如若前面的代码都不能返回一个值,我们就返回“c”。
通过上述函数,我们可能会得到四个返回值中的一个 * ,# ,d ,c。
if (ret == '*')
{
printf("玩家赢\n");
}
else if(ret=='#')
{
printf("电脑赢");
}
else if (ret == 'd')
{
printf("平局");
}
于是我们可以在game函数中的最后安排上这么一段函数,貌似没有出现c?
那我们不妨看看我们神秘的game函数
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
//显示棋盘
Desk(board, ROW, COL);
//判断输赢
ret=Is_Win(board, ROW, COL);
if (ret != 'c')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
//显示棋盘
Desk(board, ROW, COL);
//判断输赢
ret = Is_Win(board, ROW, COL);
if (ret != 'c')
{
break;
}
c------“continue”的首字母,意味着继续我们的棋局。
以上,我们的关于三子棋的代码便完成了。不过本篇文章只交代了三子棋代码的思路,其中的代码
并不完整,还望清楚。