1.主函数
这个代码很长,我们可以把它全部写在主函数里面。但是十分不推荐这么做。以后工作以后,很多时候我们负责的只是一个板块,汇总时只需要主函数调用每个人写的函数就能完成复杂项目。在这里我们先写主函数。
1
2
3
4
5
6
7
8
9
10
|
#include<stdio.h> #include<time.h> #define ROW 3 #define COL 3 //这是对于行和列的初始化 int main() { test(); return 0; } |
2.menu菜单
菜单十分容易完成
1
2
3
4
5
|
void menu() { printf ( "输入1开始游戏" ); printf ( "输入0开始游戏" ); } |
3.test函数
主函数中引用了test函数,我们现在写一个test函数,返回类型void,选择用do while循环来完成大部分函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
void text() { int input = 0; srand ((unsigned int ) time (NULL)); do { switch (input) { case 1: game(); break ; case 2: printf ( "退出游戏\n" ); break ; default : printf ( "选择错误,请重新输入\n" ); break ; } } while (input); } |
4.game函数(1)
game函数内部仍然需要引用许多函数,对于一个三乘三的棋盘来说,有以下的步骤:
数据存储到一个字符的二维数组中,玩家下棋是'*',电脑下棋是'#'数组的内容应该是全部空格
初始化棋牌
打印棋盘
下棋
4.1数据存储的二维数组:InitBoard
这个函数的作用是把该二维数组全部初始化成为空格
1
2
3
4
5
6
7
8
9
10
11
12
13
|
void InitBoard( char arr[ROW][COL], int row, int col) //这里的大写的BOW COL是传入的数组的值,小写的bow col是新的行和列 { int i = 0; int j = 0; for (i = 0;i<row;i++) { for (j = 0;j<col;j++) { board[i][j] = ' ' ; } } } |
4.2棋盘的打印:DisplayBoard
这个函数是把棋盘的形状打印出来
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
void DisplayBoard( 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++) { 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" ); } } |
4.3玩家下棋:PlayerMove
先写玩家下棋:思路是如果玩家输入的地址原来为空格,那么就把这个位置重新定义为 *
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
void PlayerMove( char board[ROW][COL], int row, int col) { printf ( "玩家下棋" ); int x = 0; int y = 0; while (1) { scanf ( "%d %d" ,&x,&y); if (x>=1&&x<=row&&y>=1&&y<=col) //防止输入非法棋子位置 { if (board[x-1][y-1] == ' ' ) //注意这里的x-1和y-1,玩家在输入的时候输入的假如是1 2,那么给电脑的值就是0 1,这么做是为了与二维数组的下标对应 { board[x-1][y-1] = '*' ; //注意这里只有一个等号!!!与上面不同,这里是重新定义而上面是相等的时候 break ; } else { printf ( "该坐标被占用,请重新输入\n" ); } } else { printf ( "输入非法,请重新输入" ); } } } |
4.4电脑下棋 :ComputerMove
再写电脑下棋:思路是如果电脑输入的地址原来为空格,那么就把这个位置重新定义为 #,只不过不同的是电脑输入的x和y是用rand()%3设置出来的随机值,所以我们还要在前面的test函数中放下srand的设置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
void ComputerMove( char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf ( "电脑下棋\n" ); while (1) { x = rand ()%ROW //此时ROW为3,即x等于0到2的随机值 y = rand ()%COL //此时COL为3,即Y等于0到2的随机值 if (board[x][y] == '' ) { board[x][y] = '#' ; break ; } } } |
4.5输赢的判断 ;Win
我们要有判断输赢的代码,并且初始化一个值让其接受返回值
玩家赢 - '*'
电脑赢 - '#'
平均 --- 'Q'
继续 ----'C'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
char Win( char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) //看一下横着的/竖着的3个符号是否相等,返回一个值让game()中的ret接收 { 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[0][i]!= ' ' ) { return board[0][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1]!= ' ' ) { return board[1][1]; } if (1 == FULL(board,row,col)) { return 'Q' ; //如果经过FULL函数判定棋盘满了那么返回一个Q让ret接收,否则返回C } return 'C' ; } |
4.6平局的判定 :FULL
因为要返回值,所以这个函数用int类型存放数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
int Full( 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; //返回值为0 } } } return 1; //如果棋盘满了则返回1 } |
5.game函数
现在可以把所有的函数引用了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
void game() { char board[ROW][COL] = {0}; InitBoard(board, ROW, COL); DisplayBoard(board, ROW, COL); char ret = 0; //初始化ret,ret为前面说的那个返回值 //判断输赢的代码 //玩家赢 - '*' //电脑赢 - '#' //平均 --- 'Q' //继续 ----'C' while (1) { PlayerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = Win(board, ROW, COL); if (ret != 'C' ) { break ; } ComputerMove(board, ROW, COL); DisplayBoard(board, ROW, COL); ret = Win(board, ROW, COL); if (ret != 'C' ) { break ; } } if (ret == '*' ) //到这里才分别判定返回ret的所有值 { printf ( "恭喜你你赢了!\n" ); } else if (ret == '#' ) { printf ( "很遗憾你输了!\n" ); } else { printf ( "平局\n" ); } printf ( "\n" ); } |
总结
可以吧game.c和test.c分别当做两个源文件,test.c中引用game.c,这样代码也会更加清晰。不管有多少函数需要引用,只需要写出函数的本体再引用,这样一个庞大的代码就被我们拆分成了一段一段小代码,难度也就没那么大了。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/m0_62319039/article/details/121368050