1.界面设计思路:
想达到在开始之前先打印菜单,然后根据输入的值来决定是否游戏,也即是先打印后判断的思路,因此可以使用do while循环,在do while循环里嵌套使用switch语句根据input的值来判断是否游戏,如果输入数字1则就运行game()函数开始游戏.
#include"game.h" int main() { srand((unsigned int)time(NULL)); int input = 0; 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; }
2.实现游戏需要的函数
要实现游戏至少需要以下7种自定义函数(除去game函数):
#include<stdio.h> #include<time.h> #include<stdlib.h> #define ROW 3 #define COL 3 //菜单 void menu(); //初始化棋盘 void InitBoard(int arr[ROW][COL], int row, int col); //打印棋盘内容 void PrintBoard(int arr[ROW][COL], int row, int col); //玩家下棋 void PlayerMove(int arr[ROW][COL], int row, int col); //电脑下棋 void ComputerMove(int arr[ROW][COL], int row, int col); //判断输赢 char Winer(int arr[ROW][COL], int row, int col); //判断棋盘是否已满 int IsFull(int arr[ROW][COL], int row, int col);
2.1初始化棋盘:
由于是三子棋游戏,在最开始的时候,9个格子里为空,因此可以先把9个格子里的内容都置为空格,也即是将数组里的元素都置为' '.
void InitBoard(int arr[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { arr[i][j] = ' '; } } }
2.2打印棋盘内容:
在游戏刚开始或玩家每次下棋和电脑下棋之后都要打印出最新的棋盘内容,同时为了方面观看,要在打印的时候打印竖线横线空格等把每个元素分隔开
void PrintBoard(int arr[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", arr[i][j]); if (j < col - 1) printf("|"); } printf("\n"); if(i<row-1) printf("---|---|---\n"); } }
2.3玩家下棋
首先要先确定好在玩家下棋之后,该位置的符号变成什么符号,在这里我用星号代替,该玩家下棋时,玩家选择坐标下棋,并判断,如果选择的坐标当前为空则可以下,反之不能下需要重新选择坐标或者玩家输入的坐标不合规也要重新输入坐标.
void PlayerMove(int arr[ROW][COL], int row, int col) { int x, y = 0; printf("请输入坐标->:"); while (1) { scanf("%d %d", &x, &y); if (x >= 1 && x <= 3 && y >= 1 && y <= 3) { if (arr[x - 1][y - 1] == ' ') { printf("玩家下棋\n"); arr[x - 1][y - 1] = '*'; break; } else { printf("该位置已被占用,请重新选择坐标\n"); } } else printf("输入数字非法,请重新输入\n"); } }
2.4电脑下棋:
电脑下棋和玩家下棋类似,不同的是,电脑下棋之后该位置变为和玩家不同的符号,这里我用#号代替,而且电脑下棋要保证随机性(简单人机),如果想要人机变得“聪明”可以思考使用更高级的算法,这里就采用最简单的随机算法
void ComputerMove(int arr[ROW][COL], int row, int col) { printf("电脑下棋\n"); while (1) { int x = rand() % row; int y = rand() % col; if (arr[x][y] == ' ') { arr[x][y] = '#'; break; } } }
2.5判断输赢:
三子棋在每次下棋之后总共有6可能性,即是一行3个相同,一列三个相同,两条对角线相同,下满了,没下满每种结果对应返回值,在game()函数里可根据此返回值判断输赢.
char Winer(int arr[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ') return arr[i][0]; } for (int j = 0; j < col; j++) { if (arr[0][j] == arr[1][j] && arr[1][j] == arr[2][j] && arr[0][j] != ' ') return arr[0][j]; } if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ') return arr[0][0]; if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ') return arr[0][2]; if (IsFull(arr, ROW, COL)) return 'd'; return 'c'; }
2.6判断棋盘是否已满:
此函数相对简单,只需遍历一遍,如果没满就返回0,满了就返回1即可.
int IsFull(int arr[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (arr[i][j] == ' ') return 0; } } return 1; }
3.game函数:
void game() { char ret = 0; int arr[ROW][COL]; InitBoard(arr, ROW, COL); PrintBoard(arr, ROW, COL); while (1) { PlayerMove(arr, ROW, COL); PrintBoard(arr, ROW, COL); ret = Winer(arr, ROW, COL); if (ret != 'c') break; ComputerMove(arr, ROW, COL); PrintBoard(arr, ROW, COL); ret = Winer(arr, ROW, COL); if (ret != 'c') break; } if (ret == '*') printf("玩家获胜\n"); else if (ret == '#') printf("电脑获胜\n"); else printf("平局\n"); }
在最开始定义ret变量和一个数组,分别用来判断输赢和开辟棋盘,先使用初始化函数将棋盘初始化,随后打印一遍,此时棋盘都为空,然后进入循环,开始玩家下棋和电脑下棋,在每次下棋之后都需要判断是否已经游戏结束以及打印下棋后的棋盘,通过ret的赋值来判断游戏是否已经结束,如果结束了就跳出循环,再根据ret的值来判断是谁赢了或者平局.
游戏截图:
结尾:今天的分享到此结束,喜欢的朋友如果感觉有帮助可以点赞三连支持,咱们共同进步!