引言:
完成一个三子棋游戏,这其实也算一个小项目。因此需要分文件书写。
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)
源码已经保存到仓库