前言
Wassup guys
今天是我们的C语言小项目「井字棋升级版」
井字棋,又名三子棋,英文名叫Tic-Tac-Toe;
是一种在3x3格子上进行的连珠游戏,和五子棋类似,格线排成井字故得名。
游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。
其游戏过程就像下面这样
游戏运行结果如下
我在函数这一篇总结中,讲过函数的声明和定义,所有这里我用三个文件来实现这个三子棋游戏
友友们可以将以下代码复制到自己的编译器当中运行:
◾ game.h
游戏函数的声明
#pragma once
//游戏函数的声明
#include
#include
#include
//棋盘的行数
#define ROW 3
//棋盘的列数
#define COL 3
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//电脑检查自己是否会赢
int CheckComputer(char board[ROW][COL], int row, int col);
//电脑检查玩家是否会赢
int CheckPlayer(char board[ROW][COL], int row, int col, int k);
//判断输赢函数
char Is_Win(char board[ROW][COL], int row, int col);
/*
1.玩家赢 ---> 返回'*'
2.电脑赢 ---> 返回'#'
3. 平局 ---> 返回'P'
4. 继续 ---> 返回'C'
*/
◾ game.c
游戏函数的实现
#define _CRT_SECURE_NO_WARNINGS 1
//游戏函数的实现
#include "game.h"
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] = ' ';
}
}
}
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//row = 3行
//col = 3列
for (i = 0; i < row; i++)
{
if (i == 0)
{
printf("┌----┬----┬----┐\n");
}
if ((i == 1) || (i == 2))
{
printf("├----┼----┼----┤\n");
}
for (int j = 0; j < col; j++)
{
printf("│ %c ", board[i][j]);
}
printf("│\n");
}
printf("└----┴----┴----┘\n");
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋,请输入坐标:> ");
scanf("%d %d", &x, &y);
printf("你下棋的位置↓\n");
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (board[x-1][y-1] == ' ')
{
board[x-1][y-1] = 'x';
break;
}
else
{
printf("该坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,超出范围\n");
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
//z是判断变量
int z = 0;
z = CheckComputer(board, row, col);
printf("电脑下棋的位置↓\n");
while (0 == z)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'o';
break;
}
}
}
//电脑检查自己能不能赢
int CheckComputer(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//k用于返回值
int k = 0;
while (0 == k)
{
//电脑判断自己在三行上是否会赢
for (i = 0; i < row; i++)
{
//如果第一个格子和第二个格子都是电脑的棋子,并且第三个格子是空的
//那么电脑直接落子
if (board[i][0] == board[i][1] && (board[i][0] == 'o' || board[i][1] == 'o') && board[i][2] == ' ')
{
board[i][2] = 'o';
k = 1;
break;
}
if (board[i][0] == board[i][2] && (board[i][0] == 'o' || board[i][2] == 'o') && board[i][1] == ' ')
{
board[i][1] = 'o';
k = 1;
break;
}
if (board[i][1] == board[i][2] && (board[i][1] == 'o' || board[i][2] == 'o') && board[i][0] == ' ')
{
board[i][0] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//电脑判断自己在三列上是否会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && (board[0][j] == 'o' || board[1][j] == 'o') && board[2][j] == ' ')
{
board[2][j] = 'o';
k = 1;
break;
}
if (board[0][j] == board[2][j] && (board[0][j] == 'o' || board[2][j] == 'o') && board[1][j] == ' ')
{
board[1][j] = 'o';
k = 1;
break;
}
if (board[1][j] == board[2][j] && (board[1][j] == 'o' || board[2][j] == 'o') && board[0][j] == ' ')
{
board[0][j] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//使用while循环判断对角线是否会赢
while (0 == k)
{
//左边对角线
if (board[0][0] == board[1][1] && (board[0][0] == 'o' || board[1][1] == 'o') && board[2][2] == ' ')
{
board[2][2] = 'o';
k = 1;
break;
}
if (board[0][0] == board[2][2] && (board[0][0] == 'o' || board[2][2] == 'o') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][2] && (board[1][1] == 'o' || board[2][2] == 'o') && board[0][0] == ' ')
{
board[0][0] = 'o';
k = 1;
break;
}
//右边对角线
if (board[0][2] == board[1][1] && (board[0][2] == 'o' || board[1][1] == 'o') && board[2][0] == ' ')
{
board[2][0] = 'o';
k = 1;
break;
}
if (board[0][2] == board[2][0] && (board[0][2] == 'o' || board[2][0] == 'o') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][0] && (board[1][1] == 'o' || board[2][0] == 'o') && board[0][2] == ' ')
{
board[0][2] = 'o';
k = 1;
break;
}
break;
}
k = CheckPlayer(board, row, col, k);
return k;
}
}
//检查玩家是否会赢
int CheckPlayer(char board[ROW][COL], int row, int col, int k)
{
int i = 0;
int j = 0;
while (0 == k)
{
//判断玩家在三行上是否会赢
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && (board[i][0] == 'x' || board[i][1] == 'x') && board[i][2] == ' ')
{
board[i][2] = 'o';
k = 1;
break;
}
if (board[i][0] == board[i][2] && (board[i][0] == 'x' || board[i][2] == 'x') && board[i][1] == ' ')
{
board[i][1] = 'o';
k = 1;
break;
}
if (board[i][2] == board[i][1] && (board[i][2] == 'x' || board[i][1] == 'x') && board[i][0] == ' ')
{
board[i][0] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//判断玩家在三列上是否会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && (board[1][j] == 'x' || board[0][j] == 'x') && board[2][j] == ' ')
{
board[2][j] = 'o';
k = 1;
break;
}
if (board[0][j] == board[2][j] && (board[2][j] == 'x' || board[0][j] == 'x') && board[1][j] == ' ')
{
board[1][j] = 'o';
k = 1;
break;
}
if (board[1][j] == board[2][j] && (board[2][j] == 'x' || board[1][j] == 'x') && board[0][j] == ' ')
{
board[0][j] = 'o';
k = 1;
break;
}
}
break;
}
//判断玩家在对角线上是否会赢
while (0 == k)
{
//左边对角线
if (board[0][0] == board[1][1] && (board[1][1] == 'x' || board[0][0] == 'x') && board[2][2] == ' ')
{
board[2][2] = 'o';
k = 1;
break;
}
if (board[0][0] == board[2][2] && (board[2][2] == 'x' || board[0][0] == 'x') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][2] && (board[1][1] == 'x' || board[2][2] == 'x') && board[0][0] == ' ')
{
board[0][0] = 'o';
k = 1;
break;
}
//右边对角线
if (board[0][2] == board[1][1] && (board[0][2] == 'x' || board[1][1] == 'x') && board[2][0] == ' ')
{
board[2][0] = 'o';
k = 1;
break;
}
if (board[0][2] == board[2][0] && (board[2][0] == 'x' || board[0][2] == 'x') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][0] && (board[2][0] == 'x' || board[1][1] == 'x') && board[0][2] == ' ')
{
board[0][2] = 'o';
k = 1;
break;
}
break;
}
return k;
}
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 Is_Win(char board[ROW][COL], int row, int col)
{
//1.判断输赢
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[2][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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
{
return board[1][1];
}
//2.判断平局
if (1 == is_full(board, row, col))
{
return 'P';
}
//3.游戏继续
return 'C';
}
◾ test.c
测试游戏
#define _CRT_SECURE_NO_WARNINGS 1
//测试游戏
#include "game.h"
void menu()
{
printf("\n");
printf("********三子棋小游戏********\n");
printf("****************************\n");
printf("********* 1.Play *********\n");
printf("********* 0.Exit *********\n");
printf("****************************\n");
}
void game()
{
//定义一个棋盘数组
char board[ROW][COL];
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1)
{
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == 'x')
{
printf("恭喜你,赢得了游戏胜利\n");
}
else if (ret == 'o')
{
printf("不是吧,你连电脑都赢不了\n");
}
else
{
printf("居然和电脑打成了平手,你不行啊!\n");
}
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:> ");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
打印一个游戏菜单,有两种选择
1、玩游戏
0、退出游戏
代码实现
void menu()
{
printf("\n");
printf("********三子棋小游戏********\n");
printf("****************************\n");
printf("********* 1.Play *********\n");
printf("********* 0.Exit *********\n");
printf("****************************\n");
}
当运行这个游戏的时候,会首先生成一个菜单,让我们选择;
但是当我玩完一局过后,还想再玩,所以会用到循环
代码实现
int main()
{
int input = 0;
do
{
menu();
printf("请选择:> ");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
在
game()
函数,去实现三子棋的过程
三子棋,顾名思义,我们要定义一个3x3的二维数组棋盘
void game()
{
//定义一个棋盘数组
char board[ROW][COL];
}
首先我们要在 game.h
头文件 里面去声明这个初始化函数
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
然后再去 game.c
游戏函数 里面实现
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] = ' ';
}
}
}
注意:后面的函数也是一样,要先去头文件里面声明,再到游戏函数里面去实现
我们初始化好棋盘以后,要在屏幕上打印一下
代码实现
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (i == 0)
{
printf("┌----┬----┬----┐\n");
}
if ((i == 1) || (i == 2))
{
printf("├----┼----┼----┤\n");
}
for (int j = 0; j < col; j++)
{
printf("│ %c ", board[i][j]);
}
printf("│\n");
}
printf("└----┴----┴----┘\n");
}
接下来就是玩家开始下棋;
由于是个二维数组,并且数组下标是从0开始的,但是玩家可能不是程序员,所以不知道数组的下标;
所以这里把下标定义从1开始;
并且当玩家在棋盘落子以后,我们把棋盘打印出来。
代码实现
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家下棋,请输入坐标:> ");
scanf("%d %d", &x, &y);
printf("你下棋的位置↓\n");
if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
{
if (board[x-1][y-1] == ' ')
{
board[x-1][y-1] = 'x';//玩家落子用'*'表示
break;
}
else
{
printf("该坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法,超出范围\n");
}
}
}
代码实现
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] = 'o';
break;
}
}
}
如果你运行了这个程序以后,会发现电脑的走法貌似不太聪明的样子;
因为我们用随机数生成,会造成玩家赢的很轻松;
那如果电脑有了AI的思想呢?它就知道如何进攻、防守。
那么来思考一下,你是怎么下三子棋的?
1、如果我们在三行、三列、对角线上,下了两个棋子后,我们会继续下第三个;
2、如果对方在三行、三列、对角线上有了相同两个棋子后,我们会堵截,不让它下第三个;
此时我们就有了思路
电脑需要的就是在:出现两个相同的棋子的地方下自己的棋子就好了
代码一
对
ComputerMove
函数进行修改;
电脑下棋需要加一步,获取返回值,如果返回值为0,那么电脑只有乖乖的按照伪随机数来走啦
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
//z返回值
int z = 0;
z = CheckComputer(board, row, col);
printf("电脑下棋的位置↓\n");
while (0 == z)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'o';
break;
}
}
}
代码二
定义一个函数:
CheckComputer
,作用是电脑检查自己是否会赢;
1、电脑在坐标(1,1)和坐标(1,2)的格子进行判断,如果(1,1)或者(1,2)的格子都为自己的棋子,那么直接在(1,3)的格子落子
2、电脑在坐标(1,1)和坐标(1,3)的格子进行判断,如果(1,1)或者(1,3)的格子都为自己的棋子,那么直接在坐标(1,2)的格子落子
3、电脑在坐标(1,2)和坐标(1,3)的格子进行判断,如果(1,2)或者(1,3)的格子都为自己的棋子,那么直接在坐标(1,1)的格子落子
此时我们只需要定义一个循环,三行都进行判断即可,同理,三列和对角线也是一样
int CheckComputer(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
//k用于返回值
int k = 0;
while (0 == k)
{
//电脑判断自己在三行上是否会赢
for (i = 0; i < row; i++)
{
//如果第一个格子和第二个格子都是电脑的棋子,并且第三个格子是空的
//那么电脑直接落子
if (board[i][0] == board[i][1] && (board[i][0] == 'o' || board[i][1] == 'o') && board[i][2] == ' ')
{
board[i][2] = 'o';
k = 1;
break;
}
if (board[i][0] == board[i][2] && (board[i][0] == 'o' || board[i][2] == 'o') && board[i][1] == ' ')
{
board[i][1] = 'o';
k = 1;
break;
}
if (board[i][1] == board[i][2] && (board[i][1] == 'o' || board[i][2] == 'o') && board[i][0] == ' ')
{
board[i][0] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//电脑判断自己在三列上是否会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && (board[0][j] == 'o' || board[1][j] == 'o') && board[2][j] == ' ')
{
board[2][j] = 'o';
k = 1;
break;
}
if (board[0][j] == board[2][j] && (board[0][j] == 'o' || board[2][j] == 'o') && board[1][j] == ' ')
{
board[1][j] = 'o';
k = 1;
break;
}
if (board[1][j] == board[2][j] && (board[1][j] == 'o' || board[2][j] == 'o') && board[0][j] == ' ')
{
board[0][j] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//使用while循环判断对角线是否会赢
while (0 == k)
{
//左边对角线
if (board[0][0] == board[1][1] && (board[0][0] == 'o' || board[1][1] == 'o') && board[2][2] == ' ')
{
board[2][2] = 'o';
k = 1;
break;
}
if (board[0][0] == board[2][2] && (board[0][0] == 'o' || board[2][2] == 'o') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][2] && (board[1][1] == 'o' || board[2][2] == 'o') && board[0][0] == ' ')
{
board[0][0] = 'o';
k = 1;
break;
}
//右边对角线
if (board[0][2] == board[1][1] && (board[0][2] == 'o' || board[1][1] == 'o') && board[2][0] == ' ')
{
board[2][0] = 'o';
k = 1;
break;
}
if (board[0][2] == board[2][0] && (board[0][2] == 'o' || board[2][0] == 'o') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][0] && (board[1][1] == 'o' || board[2][0] == 'o') && board[0][2] == ' ')
{
board[0][2] = 'o';
k = 1;
break;
}
break;
}
k = CheckPlayer(board, row, col, k);
return k;
}
}
代码二
定义一个函数:
CheckPlayer
,作用是电脑检查玩家是否会赢;
如果玩家在三行、三列、对角线上有了相同两个棋子后,电脑会堵截,不让玩家下第三个
1、电脑在坐标(1,1)和坐标(1,2)的格子进行判断,如果(1,1)或者(1,2)的格子都为玩家的棋子,那么直接在(1,3)的格子落子堵截
2、电脑在坐标(1,1)和坐标(1,3)的格子进行判断,如果(1,1)或者(1,3)的格子都为玩家的棋子,那么直接在(1,2)的格子落子堵截
3、电脑在坐标(1,2)和坐标(1,3)的格子进行判断,如果(1,2)或者(1,3)的格子都为玩家的棋子,那么直接在(1,1)的格子落子堵截
此时我们只需要定义一个循环,三行都进行判断即可,同理,三列和对角线也是一样
int CheckPlayer(char board[ROW][COL], int row, int col, int k)
{
int i = 0;
int j = 0;
while (0 == k)
{
//判断玩家在三行上是否会赢
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && (board[i][0] == 'x' || board[i][1] == 'x') && board[i][2] == ' ')
{
board[i][2] = 'o';
k = 1;
break;
}
if (board[i][0] == board[i][2] && (board[i][0] == 'x' || board[i][2] == 'x') && board[i][1] == ' ')
{
board[i][1] = 'o';
k = 1;
break;
}
if (board[i][2] == board[i][1] && (board[i][2] == 'x' || board[i][1] == 'x') && board[i][0] == ' ')
{
board[i][0] = 'o';
k = 1;
break;
}
}
if (k != 0)
break;
//判断玩家在三列上是否会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && (board[1][j] == 'x' || board[0][j] == 'x') && board[2][j] == ' ')
{
board[2][j] = 'o';
k = 1;
break;
}
if (board[0][j] == board[2][j] && (board[2][j] == 'x' || board[0][j] == 'x') && board[1][j] == ' ')
{
board[1][j] = 'o';
k = 1;
break;
}
if (board[1][j] == board[2][j] && (board[2][j] == 'x' || board[1][j] == 'x') && board[0][j] == ' ')
{
board[0][j] = 'o';
k = 1;
break;
}
}
break;
}
//判断玩家在对角线上是否会赢
while (0 == k)
{
//左边对角线
if (board[0][0] == board[1][1] && (board[1][1] == 'x' || board[0][0] == 'x') && board[2][2] == ' ')
{
board[2][2] = 'o';
k = 1;
break;
}
if (board[0][0] == board[2][2] && (board[2][2] == 'x' || board[0][0] == 'x') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][2] && (board[1][1] == 'x' || board[2][2] == 'x') && board[0][0] == ' ')
{
board[0][0] = 'o';
k = 1;
break;
}
//右边对角线
if (board[0][2] == board[1][1] && (board[0][2] == 'x' || board[1][1] == 'x') && board[2][0] == ' ')
{
board[2][0] = 'o';
k = 1;
break;
}
if (board[0][2] == board[2][0] && (board[2][0] == 'x' || board[0][2] == 'x') && board[1][1] == ' ')
{
board[1][1] = 'o';
k = 1;
break;
}
if (board[1][1] == board[2][0] && (board[2][0] == 'x' || board[1][1] == 'x') && board[0][2] == ' ')
{
board[0][2] = 'o';
k = 1;
break;
}
break;
}
return k;
}
当玩家或者电脑每下一步棋的时候,我们就定义一个函数,判断一下谁赢了;
当棋盘已经落满棋子的时候,并且谁也没有赢,我们就认定为平局;
当棋盘还没有落满棋子的时候,并且谁也没有赢,游戏就继续;
1、玩家赢 —> 返回x
2、电脑赢 —> 返回o
3、平局 —> 返回P
;
4、继续 —> 返回C
;
那么怎么来判断输赢呢?
其实很简单,你看这个棋盘
当三行或者三列,以及两条对角线都落满相同的棋子时,那就就赢了;
举个例子
代码示例
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 Is_Win(char board[ROW][COL], int row, int col)
{
//1.判断输赢
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[2][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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ')
{
return board[1][1];
}
//2.判断平局
if (1 == is_full(board, row, col))
{
return 'P';
}
//3.游戏继续
return 'C';
}
玩家和电脑下棋的思路可以这样理解
当玩家每下一步棋时,就进行输赢判断;
当电脑每下一步棋时,也进行输赢判断;
但是玩家走一步,电脑走一步,必须要拿循环来实现;
那么跳出循环的条件是什么呢?
上面已经分析了判断输赢的四种情况;
如果当棋盘已经全部落子了,就表示游戏不能再继续了,所以就可以跳出循环;
跳出来以后,就把上面判断输赢函数返回的结果来进行比较;
如果是x
,表示玩家赢了;
如果是o
,表示电脑赢了;
如果是P
,表示平局了。
void game()
{
char ret = 0;
while (1)
{
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_Win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == 'x')
{
printf("恭喜你,赢得了游戏胜利\n");
}
else if (ret == 'o')
{
printf("不是吧,你连电脑都赢不了\n");
}
else
{
printf("居然和电脑打成了平手,你不行啊!\n");
}
}
其实上面的AI算法虽然说可以让电脑进行攻击和截堵,但还是有点缺陷,所以再给大家介绍一种。
这个算法很精妙,可以让玩家永远赢不了电脑,最多也就只能打成平局
首先第一步始终让电脑先落子,并且电脑落子的地方永远在坐标为(1,1)的格子里面
(注:#
表示电脑,*
表示玩家)
此时玩家落子就有剩余的8个格子可以选择
那么我们就遍历每一个格子,并推演出让电脑赢的方法(这里给大家演示一种)
第一步:首先电脑在坐标(1,1)落子;
第二步:玩家在坐标(1,2)落子;
第三步:电脑在坐标(3,1)落子;
第四步:玩家在坐标(2,1)落子;
第五步:电脑在坐标(3,3)落子;
第六步:此时玩家不管在棋盘剩余空格的任意位置落子,都已经输了
是不是很妙?其实五子棋的AI算法也类似,到时候会出一篇结合EasyX的图形化五子棋
结语
编程这件事情,你如果不练习,你只是学了语法而已,那是绝对不会写代码的
我是Edison,你知道的越多,你不知道越多,我们下期见!