五子棋人机对弈(c/c++)
AI下棋算法部分
一个简单的算法:计算机进行计算寻找下棋位置
-
预设(可改):
·第一步黑棋(AI)先行; -
需提供数据:
· 15*15的棋盘落子数据:int board[15][15](0表示无子;1表示play1棋子;2表示play2棋子);
· 下棋步数(非必须):int step。
#pragma once
class AI
{
private:
int record[15][15]; //计分数组
public:
void quantification(); //状态判断
int Scoring(int state); //棋盘打分
void Do(); //遍历下棋
};
void AI::quantification()
{
int play1, play2; //play1,2计数;
api_sleep(650); //延时
//上至下扫描
for (int a = 0; a < 15; a++) //判断行成立;a行;b列
{
for (int b = 0; b < 15; b++)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; play1 + b + 1 < 15 && play2 + b + 1 < 15;)
if (board[a][play1 + b + 1] == 1 && play2 == 0)
play1++;
else if (board[a][play2 + b + 1] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[a][max + b + 1] == 0)
if ((max == 2 || max == 3) && board[a][max + b + 2] == board[a][b + 1])
record[a][max + b + 1] += 50000;
else if (max == 3 && board[a][b + 1] == board[a][b - 1])
record[a][b] += 100000;
else
record[a][1 + b + max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
for (int a = 0; a < 15; a++) //判断列成立;a列;b行
{
for (int b = 0; b < 15; b++)
if (board[b][a] == 0)
{
for (play1 = 0, play2 = 0; play1 + b + 1 < 15 && play2 + b + 1 < 15;)//***改
if (board[play1 + b + 1][a] == 1 && play2 == 0)
play1++;
else if (board[play2 + b + 1][a] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[max + b + 1][a] == 0)
if ((max == 2 || max == 3) && board[max + b + 2][a] == board[b + 1][a])
record[max + b + 1][a] += 50000;
else if (max == 3 && board[b + 1][a] == board[b - 1][a])
record[b][a] += 100000;
else
record[1 + b + max][a] += Scoring(max);
record[b][a] += Scoring(max);
}
}
for (int a = 0; a < 15; a++) //判断主对角线成立;a行;b列
{
for (int b = 0; b < 15; b++)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; play1 + b + 1 < 15 && play2 + b + 1 < 15 && play1 + a + 1 < 15 && play2 + a + 1 < 15;)
if (board[play1 + a + 1][play1 + b + 1] == 1 && play2 == 0)
play1++;
else if (board[play2 + a + 1][play2 + b + 1] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[max + a + 1][max + b + 1] == 0)
if ((max == 2 || max == 3) && board[max + a + 2][max + b + 2] == board[a + 1][b + 1])
record[max + a + 1][max + b + 1] += 50000;
else if (max == 3 && board[a + 1][b + 1] == board[a - 1][b - 1])
record[a][b] += 100000;
else
record[1 + a + max][1 + b + max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
for (int a = 0; a < 15; a++) //判断副对角线成立;a行;b列
{
for (int b = 14; b >= 0; b--)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; b - play1 - 1 > 0 && b - play2 - 1 > 0 && play1 + a + 1 < 15 && play2 + a + 1 < 15;)
if (board[a + 1 + play1][b - 1 - play1] == 1 && play2 == 0)
play1++;
else if (board[a + 1 + play2][b - 1 - play2] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[1 + a + max][b - 1 - max] == 0)
if ((max == 2 || max == 3) && board[2 + a + max][b - 2 - max] == board[a + 1][b - 1])
record[1 + a + max][b - 1 - max] += 50000;
else if (max == 3 && board[a + 1][b - 1] == board[a - 1][b + 1])
record[a][b] += 100000;
else
record[1 + a + max][b - 1 - max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
//下至上扫描
for (int a = 14; a >= 0; a--) //判断行成立;a行;b列
{
for (int b = 14; b >= 0; b--)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; b - play1 - 1 >= 0 && b - play2 - 1 >= 0;)
if (board[a][b - play1 - 1] == 1 && play2 == 0)
play1++;
else if (board[a][b - play2 - 1] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[a][b - max - 1] == 0)
if ((max == 2 || max == 3) && board[a][b - 2 - max] == board[a][b - 1])
record[a][b - 1 - max] += 50000;
else if (max == 3 && board[a][b - 1] == board[a][b + 1])
record[a][b] += 100000;
else
record[a][b - 1 - max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
for (int a = 14; a >= 0; a--) //判断列成立;a列;b行
{
for (int b = 14; b >= 0; b--)
if (board[b][a] == 0)
{
for (play1 = 0, play2 = 0; b - play1 - 1 >= 0 && b - play2 - 1 >= 0;)
if (board[b - play1 - 1][a] == 1 && play2 == 0)
play1++;
else if (board[b - play2 - 1][a] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[b - max - 1][a] == 0)
if ((max == 2 || max == 3) && board[b - max - 2][a] == board[b - 1][a])
record[b - max - 1][a] += 50000;
else if (max == 3 && board[b - 1][a] == board[b + 1][a])
record[a][b] += 100000;
else
record[b - 1 - max][a] += Scoring(max);
record[b][a] += Scoring(max);
}
}
for (int a = 14; a > 0; a--) //判断主对角线成立;a行;b列
{
for (int b = 14; b > 0; b--)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; b - play1 - 1 > 0 && b - play2 - 1 > 0 && a - play1 - 1 > 0 && a - play2 - 1 > 0;)
if (board[a - play1 - 1][b - play1 - 1] == 1 && play2 == 0)
play1++;
else if (board[a - play2 - 1][b - play2 - 1] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (board[a - max - 1][b - max - 1] == 0)
if ((max == 2 || max == 3) && board[a - max - 2][b - max - 2] == board[a - 1][b - 1])
record[a - max - 1][b - max - 1] += 50000;
else if (max == 3 && board[a - 1][b - 1] == board[a + 1][b + 1])
record[a][b] += 100000;
else
record[a - 1 - max][b - 1 - max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
for (int a = 14; a >= 0; a--) //判断副对角线成立;a行;b列
{
for (int b = 14; b >= 0; b--)
if (board[a][b] == 0)
{
for (play1 = 0, play2 = 0; b + play1 + 1 < 15 && b + play2 + 1 < 15 && a - play1 - 1 > 1 && a - play2 - 1 > 1;)
if (board[a - play1 - 1][b + 1 + play1] == 1 && play2 == 0)
play1++;
else if (board[a - play2 - 1][b + 1 + play2] == 2 && play1 == 0)
play2++;
else break;
int max = play1 > play2 ? play1 : play2;
if (b + 1 + max <= 14 && board[a - max - 1][b + 1 + max] == 0)
if ((max == 2 || max == 3) && board[a - max - 2][b + max + 2] == board[a - 1][b + 1])
record[a - max - 1][b + 1 + max] += 50000;
else if (max == 3 && board[a - 1][b + 1] == board[a + 1][b - 1])
record[a][b] += 100000;
else
record[a - 1 - max][b + 1 + max] += Scoring(max);
record[a][b] += Scoring(max);
}
}
}
int AI::Scoring(int state) //可修改
{
switch (state)
{
case 1:return 10;
break;
case 2:return 250;
break;
case 3:return 25001;
break;
case 4:return 1000000;
break;
case 5:return 1000000;
break;
default:return 0;
break;
}
}
void AI::Do()
{
for (int a = 0; a < 15; a++)
for (int b = 0; b < 15; b++)
record[a][b] = 0; //分数清零
if (step < 2)
{
board[7][7] = 1;
} //第一步下至棋盘中央
else
{
quantification();
int place[3] = { 0,0,0 };
for (int a = 0; a < 15; a++)
for (int b = 0; b < 15; b++)
if (place[2] < record[a][b])
place[2] = record[a][b], place[0] = a, place[1] = b;
while (board[place[0]][place[1]] != 0) //为预防重复落棋预设(视情况可去掉)
if (place[0] < 15)
place[0]++;
else if (place[1] < 15)
place[1]++;
else place[0]--;
board[place[0]][place[1]] = 1;
}
}