二维数组
循环和选择语句
系统生成随机数
自定义函数
为什么要分文件来写函数?
一个程序应该有最基本的逻辑和各种不同的功能。
初学时的代码复杂度低,但随着学习的深入,代码会越来越复杂。到了工作的时候,一个程序更要进行分工编写。
所以就把基本逻辑模块和功能模块分开,用函数进行封装。
我们本次用到了三个文件。
test.c包含程序最基本的运行逻辑,调用其他的功能构成程序。
game.h包含用到的函数、关键常量、以及头文件的声明。
#define ROW 3//game.h
#define COL 3
#define NZIQI 3
#include
#include
#include
#include
void menu();
void menu1();
void printqipan(char board[ROW][COL], int row, int col);
void chushihua(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col, char player);
void computermove(char board[ROW][COL], int row, int col);
char panduan(char board[ROW][COL], int row, int col, int nziqi);
行数,列数,连棋个数用define声明的常量来表示(目前是三子棋,棋盘为3*3)
game.c实现程序的各种功能。
如何将这三个文件链接起来?
使用包含头文件的方式进行连接。
#include"game1.h"
在另外两个文件前面加上这行代码即可
n子旗完全采用系统随机数的方式下棋。
棋盘小还好,棋盘一大就成了人工智障,走棋完全没有章法。
于是我做了两个功能:人机对战和玩家对战
同时,n子棋需要有很强的拓展性,只需要修改一个数字,便能改变棋盘规模,游戏规则。
游戏开始运行时,我们要打印一个菜单展示交互页面,让玩家输入选项的值和系统交互。创建一个menu函数进行是否开始游戏的选择。
void menu()
{
printf("**************************************\n");
printf("************ 1.play ************\n");
printf("************ 0.exit ************\n");
printf("**************************************\n");
printf("请输入:");
}
同样,开始游戏后的PVE,pvp两个模式的选择,也需要一个菜单,创建函数menu1
void menu1()
{
printf("**************************************\n");
printf("************ 1.pvp ************\n");
printf("************ 0.pve ************\n");
printf("**************************************\n");
printf("请输入:");
}
这两个函数不需要返回值,用void类型。
要注意的是,在这个程序中,有些循环的终止条件不能用变量来控制。
我们可以用while(1)达到无限循环,然后用if语句判断是否break达到结束循环的方式。
while(1)
{
if(结束条件)
{
break;
}
}
我们将基本逻辑写在函数test中。
打印菜单1后,我们要使用变量input接受用户输入的值,然后根据值执行逻辑。
(1)开始游戏
此时用户要进行第二次输入来进行模式选择。
(2)退出游戏
让程序结束。
(3)输入错误
需要让用户重新输入。
此时的情景正适合switch函数。
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
printf("请选择模式\n");
menu1();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
如何在打完一局之后继续进行是否游戏的选择?
使用do while函数,先执行后判断,判断input的值是否为0,值为0,循环结束,刚好对应退出游戏。
int input = 0;
menu();
do
{
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
printf("请选择模式\n");
//此处进行pve和pvp的选择
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
判断pvp和pve的函数也是一样的逻辑
将两次判断逻辑嵌套,就构成了最基本的运行逻辑。
void test()
{
int input = 0;
menu();
do
{
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
printf("请选择模式\n");
int input1 = 0;
menu1();
do
{
char a = '\0';
scanf("%d", &input1);
switch (input1)
{
case 1:
printf("pvp\n");
a=gamepvp();
shengfu1(a);
menu();
break;
case 0:
printf("pve\n");
a=gamepve();
menu();
shengfu2(a);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input1 != 0 && input1 != 1);
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
这其中有很多函数会在下面的模块讲到。
在开始游戏后分为两种模式。
分为pvp和pve,要用两个函数去实现。函数名为gamepvp和gamepve。
我们定一个标注,在玩家对战时,玩家一的棋子为*,玩家二棋子为#。人机对战时,玩家棋子为*,电脑棋子为#。
char player1 = '*';//玩家对战
char player2 = '#';
char player1 = '*';//人机对战
在下棋之前,我们要创建好对应规格的棋盘,对其初始化。
如何创建好对应规格的棋盘?
用二维数组正合适。我们用空格表示棋盘中的空位,将数组定义为char类型。
char board[ROW][COL];
void chushihua(char board[ROW][COL], int row, int col);
之后便进行双方轮流下棋,在每一方下完之后判断胜负,并打印棋盘。
void playermove(char board[ROW][COL], int row, int col, char player);
//玩家下棋
void computermove(char board[ROW][COL], int row, int col);
//电脑下棋
判断胜负用函数panduan去实现
char panduan(char board[ROW][COL], int row, int col, int nziqi);
用while(1)将上述下棋的过程写入循环。
判断胜负之后,用变量ret接受判断函数的返回值(判断函数返回值类型为char),如果不为‘A’,说明游戏还未结束
否则打印棋盘并break跳出循环(结束了总要让你知道结果啊)。
char game()
{
while (1)
{
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
}
}
跳出循环后,将ret的值作为返回值,传递给变量a(a在函数test中),a作为参数函数shengfu的参数,根据a的值来打印游戏结果。
char game()
{
while (1)
{
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
}
return ret;
}
pvp和pve的函数略有不同,但大体思路一致。
这其中的大部分功能,我们都会以函数的形式来实现。
char gamepve()//函数gamepvp
{
char player1 = '*';
char ret = '\0';
char board[ROW][COL];
chushihua(board, ROW, COL);
while (1)
{
printqipan(board, ROW, COL);
printf("玩家下棋\n");
playermove(board, ROW, COL, player1);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
computermove(board, ROW, COL);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
}
return ret;
}
char gamepvp()//函数gamepve
{
char player1 = '*';
char player2 = '#';
char ret = '\0';
char board[ROW][COL];
chushihua(board, ROW, COL);
while (1)
{
printqipan(board, ROW, COL);
printf("玩家一下棋\n");
playermove(board, ROW, COL, player1);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
printqipan(board, ROW, COL);
printf("玩家二下棋\n");
playermove(board, ROW, COL, player2);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
return ret;
}
return ret;
}
下面就是一一实现这些函数的功能。
每次下完棋重新开始游戏,我们都需要一个崭新的棋盘。
这就需要初始化棋盘,将棋盘清空,也就是将二维数组中的每个元素设置为空格字符。
创建一个函数,名字叫chushihua
传递数组,棋盘数据,进行初始化。
void chushihua(char board[ROW][COL],int row,int col)
{
for (int a = 0; a < row; a++)
{
for (int b = 0; b < col; b++)
{
board[a][b] = ' ';
}
}
}
开始游戏前和游戏过程中,我们需要打印棋盘让玩家知道当前棋盘上的状况。
如何打印一个这样的棋盘呢?
为了让棋盘看起来方正,打印数组时在字符的两侧分别加一个空格。
printf("% c ", board[a][b]);
每次打印完一个字符,放置一个字符|,每行的最后不放置字符,打印完一行后换行。
for (int b = 0; b < col; b++)
{
printf("% c ", board[a][b]);
if (b != col - 1)
{
printf("|");
}
}
printf("\n");
每行打印完,打印分割行。最后一行打印之后不打印分割行。
if (a != row - 1)
{
for (int c = 0; c < col - 1; c++)
{
printf("---");
if (c == col - 2)
{
printf("--\n");
}
}
}
然后根据行数重复上述两个操作,直到打印完成
我们来看看效果
3乘3
10乘10
因为每次下棋都要打印棋盘,我们可以在每次打印之前,清空屏幕。
使用系统命令system(“cls”);来清屏。
需要头文件windows.h
创建一个函数,名字叫printqipan
代码如下。
void printqipan(char board[ROW][COL], int row, int col)
{
system("cls");
for (int a = 0; a < row; a++)
{
for (int b = 0; b < col; b++)
{
printf("% c ", board[a][b]);
if (b != col - 1)
{
printf("|");
}
}
printf("\n");
if (a != row - 1)
{
for (int c = 0; c < col - 1; c++)
{
printf("---");
if (c == col - 2)
{
printf("--\n");
}
}
}
}
}
void playermove(char board[ROW][COL], int row, int col, char player)
流程:接受玩家输入的坐标,判断坐标是否合法且未被占用。
要注意的是,在玩家看来,棋盘是从1开始的
但在电脑看来,棋盘是从0开始的(数组元素首下标为0)
所以接收玩家输入的值后应该减一得到数组的位置。
先判断坐标是否合法,如果合法就进入下一步的判断
int a = 0, b = 0;
scanf("%d%d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col)
{
}
else
{
printf("坐标非法");
}
如果坐标被占用,就让玩家重新输入。
未被占用,则在二维数组放置对应的字符,跳出循环。
player为当前执棋玩家所代表的字符。(在运行逻辑中定义)
if (board[a - 1][b - 1] == ' ')
{
board[a - 1][b - 1] = player;
break;
}
else
printf("输入坐标已被占用\n");
切换执子的玩家,只需要改变玩家字符的参数即可。
下面是合并的代码
void playermove(char board[ROW][COL], int row, int col, char player)
{
int a = 0, b = 0;
while (1)
{
scanf("%d%d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col)
{
if (board[a - 1][b - 1] == ' ')
{
board[a - 1][b - 1] = player;
break;
}
else
printf("输入坐标已被占用\n");
}
else
{
printf("坐标非法");
}
}
}
之前我们说过,电脑下棋坐标由随机数生成。
下面讲随机数的生成
电脑每次开机都会有一个随机的种子
使用rand函数,程序就会根据种子提供一组数
a = rand();
但是每次种子相同的情况下程序重新运行提供的数列都是一样的。
想改变生成数列,就需要改变种子
除了重启电脑,还可以将一个变化的量设置为种子,这用到srand函数,最好方法是根据系统时间,这用到了函数time。
使用time(NULL)生成系统的时间戳,表示当前时间距离UTC时间 1970-01-01 00:00:00的秒数。
使用time函数需要包含头文件time.h,使用rand,srand函数需要包含头文件stdlib.h
因为srand函数的参数是无符号整形
所以使用强制转换将时间戳的数据类型设置为无符号整形。
这样就在程序每次运行的时候设置了一个随机的种子。
合并起来,设置种子的函数就是
srand((unsigned int)time(NULL));
设置完了种子,就可以使用rand函数了。
每次程序运行只会设置一个种子,所以将设置种子的函数放在最前面。
int main()
{
srand((unsigned int)time(NULL));
test();
return 0;
}
没错,main函数就这么点内容
如何限制随机数的范围?使用取模运算符。
int a = rand() % col;
int b = rand() % row;
同样,随机数也应该有效。使用和玩家执棋一样的判断方式。
我们也可以加一点有趣的小功能。
使用sleep函数让程序停顿,看起来就像是电脑在思考,后面的参数表示停顿的毫秒数,我们设置为1000。sleep函数同样包含在头文件windows.h头文件中。
代码如下
void computermove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋");
Sleep(1000);
while (1)
{
int a = rand() % col;
int b = rand() % row;
if (board[a][b] == ' ')
{
board[a][b] = '#';
break;
}
}
}
这应该是n子棋中关键的部分,我们需要找到一种高效,通用,适应各种棋盘和玩法的判断方式。
判断分为四个模块,行,列和两种方向的对角线。
我们使用一个叫panduan的函数完成这个功能,用这个函数的返回值来决定程序否继续运行。函数将数组,行数,列数和胜负条件作为参数。
char panduan(char board[ROW][COL], int row, int col,int nziqi)
{
}
我们先创建四个变量,将他们的初值设为1,作为计数器。
int flag1 = 1, flag2 = 1, flag3 = 1, flag4 = 1;
在一条线上判断相邻的两个位置内容是否相同且不为空格,如果相同且不为空格,则计数器加一,不符合,则计数器重置。
for (int a = 0; a < col - 1; a++)
{
if ((board[b][a] == board[b][a+1]) && (board[b][a] != ' '))
{
flag2++;
}
else
{
flag2 = 1;
}
如果n-1次判断都成立,则说明这条线上有n个相同的棋子连在一起,游戏结束,其中一方获胜。如果有一种棋子胜利,那么函数就返回这个棋子代表的字符。
if (flag2 == nziqi)
{
return board[b][a];
}
一条线判断完之后,转到下一条线,计数器重置为1,重复上述的判断。
下面是完整的代码(行和列之间差距很小)
for (int b = 0; b < row; b++)//判断行
{
flag2 = 1;
for (int a = 0; a < col - 1; a++)
{
if ((board[b][a] == board[b][a+1]) && (board[b][a] != ' '))
{
flag2++;
}
else
{
flag2 = 1;
}
if (flag2 == nziqi)
{
return board[b][a];
}
}
}
for (int a = 0; a < col; a++)//判断列
{
flag1 = 1;
for (int b = 0; b < row-1; b++)
{
if ((board[b][a] == board[b + 1][a]) && (board[b][a] != ' '))
{
flag1++;
}
else
{
flag1 = 1;
}
if (flag1 == nziqi)
{
return board[b][a];
}
}
}
然后就是对角线的判断了,和行和列有所不同。
下面用几张图展示行列和对角线的判断的区别
假设这是棋盘
我们将圆圈设为起始点。
此时的只需要判断三条线即可判断完整个棋盘,且起始点都在一条直线上
但是在对角线情况下,情况就不一样
可以看到起始点不是在一条直线上了。
这个时候就需要多一层循环来确定起始点。
和前面的判断一样,再复述一遍对角线的判断过程
下方函数可以确定判断的起始点(其实起始点多了几个,会增加判断时间,但是不影响判断的结果,代码的优化我会再下一篇写出来)
for (int b = 0; b < row-1; b++)
{
flag3 = 1;
for (int a = 0; a < row - 1; a++)
{
}
}
然后进行一条线上的判断
for (; (a < col - 1) && (b < row - 1); a++, b++)
{
if ((board[b][a] == board[b + 1][a + 1]) && (board[b][a] != ' '))
{
flag3++;
}
else
{
flag3 = 1;
}
if (flag3 == nziqi)
{
return board[b][a];
}
}
组合起来就是这样
for (int b = 0; b < row-1; b++)//判断斜上方
{
flag3 = 1;
for (int a = 0; a < row - 1; a++)
{
for (; (a < col - 1) && (b < row - 1); a++, b++)
{
if ((board[b][a] == board[b + 1][a + 1]) && (board[b][a] != ' '))
{
flag3++;
}
else
{
flag3 = 1;
}
if (flag3 == nziqi)
{
return board[b][a];
}
}
}
}
斜上方的判断也是如此,只是修改了起始点和判断走向
for (int b = 0; b < row - 1; b++)//判断斜下方
{
flag4 = 1;
for (int a = col - 1; a > 0; a--)
{
for (; (a > 0) && (b < row - 1); a--, b++)
{
if ((board[b][a] == board[b + 1][a - 1]) && (board[b][a] != ' '))
{
flag4++;
}
else
{
flag4 = 1;
}
if (flag4 == nziqi)
{
return board[b][a];
}
}
}
}
如果按这种方式没有找到n个相同的连在一起的棋子,就判断棋盘是否被铺满。
在外部定义函数is_full来判断。
static int is_full(char board[ROW][COL], int row, int col);
对棋盘中每个棋子进行判断,如果存在空位,就返回1
找完棋盘没有空位,就会返回0
static int is_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;
}
}
return 1;
}
在判断模块,我们调用函数is_full
如果函数的返回值为1,棋盘满,就返回字符‘Q’
在执行完上述所有判断后,如果都没有成立,说明游戏没有结束
返回字符‘A’
if (is_full(board, row, col) == 1)
{
return 'Q';
}
return 'A';
之前我们说过
在判断胜负结束之后,将ret的值作为返回值,传递给变量a。
a作为参数函数shengfu的参数,根据a的值来打印游戏结果。
分为pve和pvp两种情况。
使用switch case语句,将ret作为参数。
void shengfu1(char a)
{
switch (a)
{
case '*':printf("玩家一获胜\n"); break;
case '#':printf("玩家二获胜\n"); break;
case 'Q':printf("平局\n"); break;
case 'A':printf("错误\n"); break;
}
}
void shengfu2(char a)
{
switch (a)
{
case '*':printf("玩家获胜\n"); break;
case '#':printf("电脑获胜\n"); break;
case 'Q':printf("平局\n"); break;
case 'A':printf("错误\n"); break;
}
}
将上述部分全部结合在一起!
得到下面的游戏代码
game.h:
#pragma once//game.h
#define ROW 10
#define COL 10
#define NZIQI 3
#include
#include
#include
#include
void menu();
void menu1();
void printqipan(char board[ROW][COL], int row, int col);
void chushihua(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col, char player);
void computermove(char board[ROW][COL], int row, int col);
char panduan(char board[ROW][COL], int row, int col, int nziqi);
test.c:
#include"game1.h"//test.c
void shengfu1(char a)
{
switch (a)
{
case '*':printf("玩家一获胜\n"); break;
case '#':printf("玩家二获胜\n"); break;
case 'Q':printf("平局\n"); break;
case 'A':printf("错误\n"); break;
}
}
void shengfu2(char a)
{
switch (a)
{
case '*':printf("玩家获胜\n"); break;
case '#':printf("电脑获胜\n"); break;
case 'Q':printf("平局\n"); break;
case 'A':printf("错误\n"); break;
}
}
char gamepve()
{
char player1 = '*';
char ret = '\0';
char board[ROW][COL];
chushihua(board, ROW, COL);
while (1)
{
printqipan(board, ROW, COL);
printf("玩家下棋\n");
playermove(board, ROW, COL, player1);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
computermove(board, ROW, COL);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
}
return ret;
}
char gamepvp()
{
char player1 = '*';
char player2 = '#';
char ret = '\0';
char board[ROW][COL];
chushihua(board, ROW, COL);
while (1)
{
printqipan(board, ROW, COL);
printf("玩家一下棋\n");
playermove(board, ROW, COL, player1);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
printqipan(board, ROW, COL);
printf("玩家二下棋\n");
playermove(board, ROW, COL, player2);
ret = panduan(board, ROW, COL, NZIQI);
if (ret != 'A')
{
printqipan(board, ROW, COL);
break;
}
return ret;
}
return ret;
}
void test()
{
int input = 0;
menu();
do
{
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
printf("请选择模式\n");
int input1 = 0;
menu1();
do
{
char a = '\0';
scanf("%d", &input1);
switch (input1)
{
case 1:
printf("pvp\n");
a=gamepvp();
shengfu1(a);
menu();
break;
case 0:
printf("pve\n");
a=gamepve();
menu();
shengfu2(a);
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input1 != 0 && input1 != 1);
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
srand((unsigned int)time(NULL));
test();
return 0;
}
game.c:
#include "game1.h"
void menu()
{
printf("**************************************\n");
printf("************ 1.play ************\n");
printf("************ 0.exit ************\n");
printf("**************************************\n");
printf("请输入:");
}
void menu1()
{
printf("**************************************\n");
printf("************ 1.pvp ************\n");
printf("************ 0.pve ************\n");
printf("**************************************\n");
printf("请输入:");
}
void chushihua(char board[ROW][COL],int row,int col)
{
for (int a = 0; a < row; a++)
{
for (int b = 0; b < col; b++)
{
board[a][b] = ' ';
}
}
}
void printqipan(char board[ROW][COL], int row, int col)
{
system("cls");
for (int a = 0; a < row; a++)
{
for (int b = 0; b < col; b++)
{
printf("% c ", board[a][b]);
if (b != col - 1)
{
printf("|");
}
}
printf("\n");
if (a != row - 1)
{
for (int c = 0; c < col - 1; c++)
{
printf("---");
if (c == col - 2)
{
printf("--\n");
}
}
}
}
}
void playermove(char board[ROW][COL], int row, int col, char player)
{
int a = 0, b = 0;
while (1)
{
scanf("%d%d", &a, &b);
if (a >= 1 && a <= row && b >= 1 && b <= col)
{
if (board[a - 1][b - 1] == ' ')
{
board[a - 1][b - 1] = player;
break;
}
else
printf("输入坐标已被占用\n");
}
else
{
printf("坐标非法");
}
}
}
void computermove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋");
Sleep(1000);
while (1)
{
int a = rand() % col;
int b = rand() % row;
if (board[a][b] == ' ')
{
board[a][b] = '#';
break;
}
}
}
static int is_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;
}
}
return 1;
}
char panduan(char board[ROW][COL], int row, int col,int nziqi)
{
int flag1 = 1, flag2 = 1, flag3 = 1, flag4 = 1;
//判断列
for (int a = 0; a < col; a++)
{
flag1 = 1;
for (int b = 0; b < row-1; b++)
{
if ((board[b][a] == board[b + 1][a]) && (board[b][a] != ' '))
{
flag1++;
}
else
{
flag1 = 1;
}
if (flag1 == nziqi)
{
return board[b][a];
}
}
}
//行
for (int b = 0; b < row; b++)
{
flag2 = 1;
for (int a = 0; a < col - 1; a++)
{
if ((board[b][a] == board[b][a+1]) && (board[b][a] != ' '))
{
flag2++;
}
else
{
flag2 = 1;
}
if (flag2 == nziqi)
{
return board[b][a];
}
}
}
//对角线
for (int b = 0; b < row-1; b++)
{
flag3 = 1;
for (int a = 0; a < row - 1; a++)
{
for (; (a < col - 1) && (b < row - 1); a++, b++)
{
if ((board[b][a] == board[b + 1][a + 1]) && (board[b][a] != ' '))
{
flag3++;
}
else
{
flag3 = 1;
}
if (flag3 == nziqi)
{
return board[b][a];
}
}
}
}
for (int b = 0; b < row - 1; b++)
{
flag4 = 1;
for (int a = col - 1; a > 0; a--)
{
for (; (a > 0) && (b < row - 1); a--, b++)
{
if ((board[b][a] == board[b + 1][a - 1]) && (board[b][a] != ' '))
{
flag4++;
}
else
{
flag4 = 1;
}
if (flag4 == nziqi)
{
return board[b][a];
}
}
}
}
if (is_full(board, row, col) == 1)
{
return 'Q';
}
return 'A';
}
代码庞大,我只能尽我所能将程序讲得更清晰,但难免有纰漏,难以理解之处。
如果程序有错误,或者文章有改进的地方,请指出,我一定会改正!
下一篇,函数的递归和优化。
大家的关注和点赞是我永远的动力!