-
画图分析
通过图像可以知道,我们需要菜单,棋盘,下棋过程,判断输赢这四个步骤。
那么就好办了,我们一步一步来,就可以完成了。
目录
一.main函数
菜单代码
void menu() { printf("**************\n"); printf("**** 1.play **\n"); printf("**** 0.exct **\n"); printf("**************\n"); }
主函数
因为是写小游戏,程序至少运行一次,do while循环是一个好选择。
又switch分支语句来选择菜单内容
int main() { srand((unsigned int)time(NULL)); int input; do { menu(); printf("请选:> "); scanf("%d", &input); switch (input) { case 1 : game(); break; case 2 : printf("退出游戏\n"); break; default: printf("选择错误,重新选择\n"); break; } } while (input); return 0; }
2.三子棋游戏实现
当我们通过主函数 输入 1 后 进入game函数
我们知道是一个三行三列的二维数组
char board[ROW][COL];
这里并没有写死数组的大小,而是用定义
#define ROW 3 #define COL 3
有了数组之后,我们就要初始化数组,先让它每个内容为空。代码如下
初始化棋盘
//函数 initboard(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] = ' '; } } }
我们就拥有了初始化为空的二维数组,但这还不够。我们需要的是棋盘
打印棋盘
接下来我们就打印棋盘。其中有 | 和 --- 来实现分隔.
简单分析,打印了 ' '%c' '之后需要一个 | 并且有2个 | 而不是3个
换行(不要忘记哦)之后 需要 打印 ---|---|--- 而且 --- 有2行不是3行
代码实现
//函数 playboard(board, ROW, COL); //实现 void playboard(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"); } }
这样我们就拥有了棋盘,就可以开始下棋了
下棋步骤
下棋就很简单了,玩家下棋和电脑下棋,玩家落子需要在棋盘范围内。
玩家输入 坐标 判断是否为空 为空就 下一个 # 在该坐标上,不为空就输出 重新输入
//函数 playermove(board, ROW, COL); //实现 void playermove(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; printf("玩家下棋,请输入坐标\n"); while (1) { scanf("%d %d", &i, &j);//玩家一般输入从1开始,但数组下标是0开始 if (i > 0 && i <= row && j > 0 && j <= col) { if (board[i - 1][j - 1] == ' ')//所以这里 - 1 { board[i - 1][j - 1] = '#'; break; } else { printf("该坐标已被占用,请重新输入\n"); } } else { printf("坐标非法,重新输入\n"); } } }
电脑下棋
电脑下棋随机下,用rand函数,将时间作为随机数种子,确保得到的行列坐标是真随机。
rand函数使用需要srand((unsigned int)time(NULL));这里写在main函数中了
//函数 computermove(board, ROW, COL); //实现 void computermove(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; } } }
当我们下完一次棋之后需要打印一次棋盘,并且判断一次输赢,这是一个循环
while (1) { playermove(board, ROW, COL); playboard(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'C') { break; } computermove(board, ROW, COL); playboard(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'C') { break; } } if (ret == '#') { printf("玩家赢\n"); } else if (ret == '*') { printf("电脑赢\n"); }
判断输赢
1.在 iswin 函数中 返回值作为输赢结果
1.1 # 作为玩家赢
1.2 * 作为电脑赢
1.3 ' '表示胜负未分
1.4 Q 表示和棋
2. 判定是否和棋
2.1调用isFull函数。
2.2如果数组中有元素为’ ‘,那么没满,返回0。如果全不为’ ',满了,返回1。
2.3如果棋盘满了未分出胜负,和棋。3.判断
整行 或 整列 还有 对角线
代码实现
int IsFull(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; } char iswin(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[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ') return board[1][1]; if (1 == IsFull(board, ROW, COL)) { return 'Q'; } return 'C'; }
完整代码见Gitee链接 Project5/Project5 · NTC_jason/cc语言 - 码云 - 开源中国 (gitee.com)