引言: 完成一个三子棋游戏,这其实也算一个小项目。因此需要 分文件 书写。 test.c用于测试 game.c用于实现游戏里面的函数。 game.h用于包含所有的头文件。 其余test.c和game.c只需要引用
引言:
完成一个三子棋游戏,这其实也算一个小项目。因此需要分文件书写。
test.c用于测试
game.c用于实现游戏里面的函数。
game.h用于包含所有的头文件。
其余test.c和game.c只需要引用 #include "game.h" 一步到位即可。
一、大致的游戏框架。
先是一个菜单,输入1/0,1表示开始游戏,0表示结束游戏。
1/0表达式不仅方便我们等会在switch 语句中放入整数,也便于我们跳出循环while()的判断。
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
game();
break;
case 0:
printf("结束游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
二、接着最主要的就是实现game()函数。
我们做的游戏是一个三子棋。所以肯定先有一个空白的棋盘。
1、第一步就是如何实现空白的棋盘
这是我们目标的棋盘。
第一行循环打印空格、字符、空格、|,然后循环最后一下条件判断,不打印 | 即可。
第二行循环打印---|,然后循环最后一下条件判断,不打印 | 即可
最后把这两行放到一个循环里面,最后循环条件判断不打印第二行。
void DisplayBoard(char board[ROW][COL])
{
for (int j=0;j<ROW;j++)
{
for (int i = 0; i < COL; i++)
{
if (i < COL - 1)
printf(" %c |", board[j][i]);
if (i == COL - 1)
printf(" %c ", board[j][i]);
}
printf("\n");
if (j == ROW - 1)
break;
for (int i = 0; i < COL; i++)
{
if (i < COL - 1)
printf("---|");
if (i == COL - 1)
printf("---");
}
printf("\n");
}
}
2、实现玩家落子
考虑到玩家不是程序员,所以不能用数组的下标去要求,数组就是从0开始。
玩家落子也要防止下标不合法,或者被占用的情况
void PlayerMove(char board[ROW][COL])
{
int x = 0;
int y = 0;
while (1)
{
printf("请玩家落子,中间以空格区分\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= ROW && y >= 1 && y <= ROW)
{
board[x - 1][y - 1] = '#';
break;
}
else
printf("输入非法,请重新输入\n");
}
}
3、实现电脑落子
电脑落子就是一个随机值的体现。注意srand((unsigned int) time(NULL))放到主函数里面,只需要调用一次。
然后在电脑落子里面调用rand()函数即可。
void ComputerMove(char board[ROW][COL])
{
int x = 0;
int y = 0;
printf("电脑落子\n");
while (1)
{
x = rand() % ROW;//x就属于0~ROW-1
y = rand() % COL;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
}
}
4、判断输赢
判断输赢主要含有是否连成3个(包含横行、竖行、对角线),然后就是平局,如果都不满足,那就是游戏继续。
注意判断赢时,采用通解的方法,即适用任何棋盘,不仅仅适用于三子。
因为判断输赢,所以需要一个返回值,方便主函数进行判断。
char IsWin(char board[ROW][COL])
{
//判断行
for (int i=0;i<ROW;i++)
{
int count = 0;
int j = 0;
for (j=0;j<COL-1;j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j] != ' ')
count++;
}
if (count==COL-1)
return board[i][j-1];//这个返回值非常巧妙
}
//判断列
for (int j=0;j<COL;j++)
{
int count = 0;
int i = 0;
for (i=0;i<ROW-1;i++)
{
if (board[i][j] == board[i + 1][j] && board[i][j] != ' ')
count++;
}
if (count==ROW-1)
return board[i-1][j];
}
//判断正对角线
int x = 0;
int y = 0;
int cnt1 = 0;
while (x<ROW-1 && y<COL-1)
{
if (board[x][y] == board[x + 1][y + 1] && board[x][y] != ' ')
{
cnt1++;
}
x++;
y++;
}
if (cnt1 == ROW - 1)
return board[x][y];
//判断反对角线
int x_ = 0;
int y_ = COL - 1;
int cnt2 = 0;
while (x_<ROW - 1 && y_>0)
{
if (board[x_][y_] == board[x_ + 1][y_ - 1] && board[x_][y_] != ' ')
cnt2++;
x_++;
y_--;
}
if (cnt2 == ROW - 1)
return board[x_][y_];
//判断是否平局
int flag = 0;
for (int i=0;i<ROW;i++)
{
for (int j=0;j<COL;j++)
{
if (board[i][j] == ' ')
flag = 1;
}
}
if (flag == 0)
return 'T';
return 'C';
}
game1/game1 · 可涵/C语言练习 - 码云 - 开源中国 (gitee.com)
源码已经保存到仓库