系列目录
目录
一、算法描述
二、代码实现
一、算法描述 本文只介绍作为在在五子棋的条件情况下(机器白子后手,防守策略大于进攻,无禁手,不具有随机性)ai的落子思路
1.评估函数
评估函数即对棋盘上每一个子进行活1,活2,活3,活4、死2,死3,死4的加权评估,最后排序落子位置即为分数最大值对应位置
2.对井字棋的特殊处理
文章图片
文章图片
如图如测试代码所示,每轮会进行棋局判定,分数高的位置即为落子位置。
井字棋的机器落子规则相比一般规则有所变化,因其后手故第一个落子尤为关键
运行结果:
文章图片
在井字棋中边角子>中间子>其他子。故我们对其简单处理即可确保后手的机器不输棋局。
代码如下:
int ai3() { if (map[0][0] == 0) { map[0][0] = 2; return 1; } if (map[1][1] == 0) { map[1][1] = 2; return 1; } return 0; }
文章图片
二、代码实现
int aibeside(int x, int y)
{
if (map[x + 1][y] == 1 || map[x - 1][y] == 1 || map[x][y + 1] == 1 || map[x][y - 1] == 1)return 2;
if (map[x + 1][y + 1] == 1 || map[x - 1][y + 1] == 1 || map[x - 1][y - 1] == 1 || map[x + 1][y - 1] == 1)return 1;
return 0;
}int aibeside2(int x, int y)
{
if (map[x + 1][y] == 1 && map[x + 2][y] == 1)return 10;
if (map[x - 1][y] == 1 && map[x - 2][y] == 1)return 10;
if (map[x][y + 1] == 1 && map[x][y + 2] == 1)return 10;
if (map[x][y - 1] == 1 && map[x][y - 2] == 1)return 10;
if (map[x + 1][y + 1] == 1 && map[x + 2][y + 2] == 1)return 10;
if (map[x - 1][y + 1] == 1 && map[x - 2][y + 2] == 1)return 10;
if (map[x + 1][y - 1] == 1 && map[x + 2][y - 2] == 1)return 10;
if (map[x - 1][y - 1] == 1 && map[x - 2][y - 2] == 1)return 10;
return 0;
}int aibeside3(int x, int y)
{
if (map[x + 1][y] == 1 && map[x + 2][y] == 1 && map[x + 3][y] == 1)return 100;
if (map[x - 1][y] == 1 && map[x - 2][y] == 1 && map[x - 3][y] == 1)return 100;
if (map[x][y + 1] == 1 && map[x][y + 2] == 1 && map[x][y + 3] == 1)return 100;
if (map[x][y - 1] == 1 && map[x][y - 2] == 1 && map[x][y - 3] == 1)return 100;
if (map[x - 1][y - 1] == 1 && map[x - 2][y - 2] == 1 && map[x - 3][y - 3] == 1)return 100;
if (map[x - 1][y + 1] == 1 && map[x - 2][y + 2] == 1 && map[x - 3][y + 3] == 1)return 100;
if (map[x + 1][y - 1] == 1 && map[x + 2][y - 2] == 1 && map[x + 3][y - 3] == 1)return 100;
if (map[x + 1][y + 1] == 1 && map[x + 2][y + 2] == 1 && map[x + 3][y + 3] == 1)return 100;
return 0;
}int aibeside4(int x, int y)
{
if (map[x + 1][y] == 1 && map[x + 2][y] == 1 && map[x + 3][y] == 1 && map[x + 4][y] == 1)return 1000;
if (map[x - 1][y] == 1 && map[x - 2][y] == 1 && map[x - 3][y] == 1 && map[x - 4][y] == 1)return 1000;
if (map[x][y + 1] == 1 && map[x][y + 2] == 1 && map[x][y + 3] == 1 && map[x][y + 4] == 1)return 1000;
if (map[x][y - 1] == 1 && map[x][y - 2] == 1 && map[x][y - 3] == 1 && map[x][y - 4] == 1)return 1000;
if (map[x - 1][y - 1] == 1 && map[x - 2][y - 2] == 1 && map[x - 3][y - 3] == 1 && map[x - 4][y - 4] == 1)return 100;
if (map[x - 1][y + 1] == 1 && map[x - 2][y + 2] == 1 && map[x - 3][y + 3] == 1 && map[x - 4][y + 4] == 1)return 100;
if (map[x + 1][y - 1] == 1 && map[x + 2][y - 2] == 1 && map[x + 3][y - 3] == 1 && map[x + 4][y - 4] == 1)return 100;
if (map[x + 1][y + 1] == 1 && map[x + 2][y + 2] == 1 && map[x + 3][y + 3] == 1 && map[x + 4][y + 4] == 1)return 100;
return 0;
}int corner(int x, int y)
{
if (x == 0 || y == 0 || x == length - 1 || y == length - 1)return -1;
return 0;
}int attack(int x, int y)
{
if (map[x + 1][y] == 2 && map[x + 2][y] == 2 && map[x + 3][y] == 2)return 1000;
if (map[x - 1][y] == 2 && map[x - 2][y] == 2 && map[x - 3][y] == 2)return 1000;
if (map[x][y + 1] == 2 && map[x][y + 2] == 2 && map[x][y + 3] == 2)return 1000;
if (map[x][y - 1] == 2 && map[x][y - 2] == 2 && map[x][y - 3] == 2)return 1000;
if (map[x - 1][y - 1] == 2 && map[x - 2][y - 2] == 2 && map[x - 3][y - 3] == 2)return 1000;
if (map[x - 1][y + 1] == 2 && map[x - 2][y + 2] == 2 && map[x - 3][y + 3] == 2)return 1000;
if (map[x + 1][y - 1] == 2 && map[x + 2][y - 2] == 2 && map[x + 3][y - 3] == 2)return 1000;
if (map[x + 1][y + 1] == 2 && map[x + 2][y + 2] == 2&& map[x + 3][y + 3] == 2)return 1000;
return 0;
}int score[15][15];
int ai()
{
if (ai3() == 1)return 0;
//计分归零
for (int i = 0;
i < length;
i++)
{
for (int j = 0;
j < length;
j++)
{
score[i][j] = 0;
}
}
//每个子计分
for (int i = 0;
i < length;
i++)
{
for (int j = 0;
j < length;
j++)
{
if (map[j][i] == 2)
{
score[j][i] = -1;
continue;
}if (map[j][i] == 1)
{
score[j][i] = -1;
continue;
}score[j][i] += aibeside(j, i);
score[j][i] += aibeside2(j, i);
score[j][i] += aibeside3(j, i);
score[j][i] += aibeside4(j, i);
score[j][i] += corner(j, i);
score[j][i] += attack(j, i);
}
}back:
int maxx = 0, maxy = 0, maxscore = 0;
for (int j = 0;
j < length;
j++)
{
for (int i = 0;
i < length;
i++)
{
if (score[j][i] > maxscore)
{
maxscore = score[j][i];
maxx = j;
maxy = i;
}
}
}
if (map[maxx][maxy] != 0)
{
score[maxx][maxy] = 0;
goto back;
}
map[maxx][maxy] = 2;
positionx = maxx;
positiony = maxy;
IsBlack = 1;
return 0;
}int ai3()
{
if (map[0][0] == 0)
{
map[0][0] = 2;
return 1;
}
if (map[1][1] == 0)
{
map[1][1] = 2;
return 1;
}
return 0;
}
【小项目|【c语言五子棋】简单ai算法初步(实际)】
推荐阅读
- 小项目|【c语言五子棋】简单ai算法(理论)
- 贪吃蛇 C语言
- 数据结构实验报告|数据结构前言练习
- C++|C++实现---学生选课系统
- 操作系统|操作系统动态分区分配方式C/C++语言(首次适应算法(FF)循环首次适应算法(NF)最best适应算法(BF)最坏适应算法(WF))
- 简介|B_QuRT_User_Guide(26)
- C语言|windows系统c语言编译器安装
- 嵌入式|嵌入式开发(管理 RTOS 内存性能和使用的7个技巧)
- C语言|基于单链表的图书管理系统(C语言)