* #####在写代码之前我们先来看看一下三子棋的规则:玩家和电脑在棋盘上下棋,玩家走一步,电脑走一步,直到任何一方的三个棋子连起来或者棋盘下满了为止结束。#
先分析我们应该用代码实现什么是写代码之前的重要任务:
1.打印游戏菜单。
2.打印棋盘。
3.实现玩家主观下棋和电脑自动下棋。
4.判断游戏的输赢。
接下来就看看如何实现上述吧!
第一步打印菜单比较简单:
void menu() { printf("###############################################################\n"); printf("####################### 1:Play 2:Exit #############\n"); printf("###############################################################\n"); }
构建棋盘是三子棋的重点,因为我们选择下棋的落点都是一个坐标,一共有九个坐标,所以选择数组来存放坐标
void init(char board[3][3],int line,int row)//使数组中含有的元素全变为空格 { int a = 0; int b = 0; for (a = 0; a < 3; a++) { for (b = 0; b < 3; b++) { board[a][b] = ' '; } } }
这里有一个很容易错的点是在构建数组时如果是 char arr[3][3]={0};这样的数组在打印棋盘是也是下图的效果,但是我们要明确0和空格是完全不一样的,0对应的是空字符。
数组创建完成,打印上图中的棋盘
void Printboard(char board[3][3], int line, int row)//打印棋盘 { int c = 0; for (c = 0; c < 3; c++) { int d = 0; for (d = 0; d < 3; d++) { if (d<2) { printf(" %c |", board[c][d]);//将数组元素放到棋盘中去 } if (d==3) { printf(" %c ", board[c][d]); } } printf("\n"); if (c <2)//使横着的边界只打印两行 { int e = 0; for (e = 0; e < 3; e++) { if (e < 2) printf("---|"); if (e == 2) printf("----"); } printf("\n"); } } printf("\n");//换行,使每次打印的棋盘不会连在一起 }
接下来就可以实现玩家下棋了,在玩家下棋时输入的坐标是1-3的,因为玩家不知道数组坐标从0开始,我们只需减一就可以了
void Playermove(char board[3][3], int line, int row) { int f = 0; int g = 0; printf("Please player select the coordinations\n"); while (1) { scanf("%d%d", &f, &g); if (f > 0 && f < 4 && g>0 && g < 4) { if (board[f - 1][g - 1] == ' ') { board[f - 1][g - 1] = '#';//#是玩家的棋 break; } else { printf("Error: please selects again\\n"); } } else { printf("Error: please select again\n"); } } }
电脑自动下棋,在这里需要用到随机数,使用rand()%3是为了使随机数在0-3;
每次玩家和电脑走一步后都应该打印一次棋盘,并且判断是否分出胜负; while (1) { Playermove(board, 3, 3); Printboard(board, 3, 3); int z = Ifwin(board, 3, 3);//判断输赢 if (z == 0) { printf("Player is win\n"); break; } else if (z == 1) { printf("Computer is win\n"); break; } else if (z == 2) { printf("No body win\n"); break; }
判断输赢的代码我写的很难看,这里就不放了,后面会附上所有的代码,判断方法就是判断数组中是否有行三连,列三连,斜三连,如果棋盘满了还没分出胜负,那就是平局,如果判断输赢有更简单的方式请您在评论区留言,谢谢。
全部代码:
{ printf("###############################################################\n"); printf("####################### 1:Play 2:Exit #############\n"); printf("###############################################################\n"); } void init(char board[3][3],int line,int row)//使数组中含有的元素全变为空格 { int a = 0; int b = 0; for (a = 0; a < 3; a++) { for (b = 0; b < 3; b++) { board[a][b] = ' '; } } } void Printboard(char board[3][3], int line, int row)//打印棋盘 { int c = 0; for (c = 0; c < 3; c++) { int d = 0; for (d = 0; d < 3; d++) { if (d<2) { printf(" %c |", board[c][d]); } if (d==3) { printf(" %c ", board[c][d]); } } printf("\n"); if (c <2) { int e = 0; for (e = 0; e < 3; e++) { if (e < 2) printf("---|"); if (e == 2) printf("----"); } printf("\n"); } } printf("\n"); } void Playermove(char board[3][3], int line, int row)//玩家下棋 { int f = 0; int g = 0; printf("Please player select the coordinations\n"); while (1) { scanf("%d%d", &f, &g); if (f > 0 && f < 4 && g>0 && g < 4) { if (board[f - 1][g - 1] == ' ') { board[f - 1][g - 1] = '#'; break; } else { printf("Error: please selects again\\n"); } } else { printf("Error: please select again\n"); } } } int Isfull(char board[3][3], int line, int row)//判断是否平局 { int l = 0; for (l = 0; l < 3; l++) { int m = 0; for (m = 0; m < 3; m++) { if (board[l][m] == ' ') { return 3; } } } return 2;//0为玩家赢,1为电脑赢,2为平局,其他继续。 } int Ifwin(char board[3][3], int line, int row)//判断输赢 { int z = 0; for (z = 0; z <3; z++) { if (board[z][1] == board[z][2] && board[z][2] == board[z][0] && board[z][0] == '*'&&board[z][1] != ' ') { return 1; break; } else if (board[z][1] == board[z][2] && board[z][2] == board[z][0] && board[z][0] == '#'&&board[z][1] != ' ') { return 0; break; } else if (board[1][z] == board[2][z] && board[2][z] == board[0][z] && board[0][z] == '*'&&board[1][z] != ' ') { return 1; break; } else if (board[1][z] == board[2][z] && board[2][z] == board[0][z] && board[0][z] == '#'&&board[1][z] != ' ') { return 0; break; } else if (board[1][1] == board[2][2] && board[2][2] == board[0][0] && board[0][0] == '*'&&board[1][1] != ' ' || board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] == '*'&&board[2][0] != ' ') { return 1; break; } else if (board[1][1] == board[2][2] && board[2][2] == board[0][0] && board[0][0] == '#'&&board[1][1] != ' ' || board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] == '#'&&board[1][1] != ' ') { return 0; break; } else if (2 ==Isfull(board, 3, 3)) { return 2; break; } } return 3; } void Computermove(char arr[3][3], int line, int row)//电脑下棋 { while (1) { int x = rand() % 3; int y = rand() % 3; if (x >=0 && x < 3 && y >= 0 && y < 3) { if (arr[x][y] == ' ') { arr[x][y] = '*'; break; } } } } void Game()//游戏主体 { char board[3][3] = {0}; init (board,3,3); while (1) { Playermove(board, 3, 3); Printboard(board, 3, 3); int z = Ifwin(board, 3, 3); if (z == 0) { printf("Player is win\n"); break; } else if (z == 1) { printf("Computer is win\n"); break; } else if (z == 2) { printf("No body win\n"); break; } Computermove(board, 3, 3); Printboard(board, 3, 3); z = Ifwin(board, 3, 3); if (z == 0) { printf("Player is win\n"); break; } else if (z == 1) { printf("Computer is win\n"); break; } else if (z == 2) { printf("No body win\n"); break; } } } void test() { int a = 0; do//使用do...while循环是因为do...while必定循环一次,并且可以继续循环。 { menu(); printf("Please select:<"); scanf("%d", &a); if (a == 1) { Game(); } else if (a == 2) { printf("Exit\n"); break; } else { printf("error\n"); } } while (a); } int main() { srand((unsigned int)time(NULL));//随机数必备 test(); return 0; }