项目演示
![](https://img-blog.csdnimg.cn/direct/db09aee9e68542c9bc45e3d80339bd40.png)
代码
readme.md
This project is my first small project. It mainly implements an AI for Gomoku.
It's a very basic but easy-to-learn AI model.
Theoretically, it can predict the next three moves and doesn't have strict requirements for computer specifications.
After opening the project in Visual Studio (VS), you can run it directly.
It includes two modes: a play mode and a test mode.
In the test mode, you input three numbers each time, representing the position and target of the move (0 for AI, 1 for the player).
Then, the computer will output each step it thinks, which is convenient for debugging.
In the future, I may use the easyx library to develop a more visually appealing interface and improve the game.cpp file.
ai.h
#pragma once
#include"basic.h"
int GetChessBoardScore(char[][COLS], int);
ChessPoint GetMaxPoint(char[][COLS], int);
ChessPoint GetBestPoint(char[][COLS], bool, int);
bool TestWhetherWin(char[][COLS]);
basic.h
#pragma once
#define LENGTH 800
#define WIDTH 640
#define ROWS 15
#define COLS 15
#define W_AI 0
#define W_PL 1
#define C_AI '*'
#define C_PL '+'
#define C_NO '.'
struct ChessPoint
{
int x;
int y;
int score;
};
bool IsIn(ChessPoint);
bool IsWhich(int);
char GetCB(char[][COLS], ChessPoint);
ChessPoint CreatePoint(int, int, int);
ChessPoint AddPoint(ChessPoint, ChessPoint);
int SwapWhich(int);
void InitScore(int[][COLS]);
game.h
#pragma once
void starting();
void endgame();
play.h
#pragma once
void starting();
void endgame();
test.h
#pragma once
#include"basic.h"
void testing(char[][COLS]);
void PrintChessScore(char[][COLS]);
void PrintChessBoard(char[][COLS]);
void InitChessBoard(char[][COLS]);
ai.cpp
#include"basic.h"
#include<iostream>
#include<Windows.h>
int GetScore(int my,int his)
{
if (my >= 5)
{
return 99999;
}
if (my == 4)
{
if (his == 0)
{
return 20000;
}
if (his == 1)
{
return 12000;
}
if (his == 2)
{
return 4000;
}
}
if (my == 3)
{
if (his == 0)
{
return 8000;
}
if (his == 1)
{
return 4000;
}
if (his == 2)
{
return 2000;
}
}
if (my == 2)
{
if (his == 0)
{
return 2000;
}
if (his == 1)
{
return 800;
}
if (his == 2)
{
return 400;
}
}
if (my == 1)
{
if (his == 0)
{
return 2;
}
if (his == 1)
{
return 1;
}
if (his == 2)
{
return 0;
}
}
return 0;
}
int GetMax(int x, int y)
{
if (x >= y)
{
return x;
}
return y;
}
int GetMin(int x, int y)
{
if (x <= y)
{
return x;
}
return y;
}
int GetChessBoardScore(char chessboard[][COLS], int which)
{
if (!IsWhich(which))
{
return 0;
}
int direx[4] = { 0,1,1,1 };
int direy[4] = { 1,1,0,-1 };
char my='\0', his='\0';
int score = 0;
if (which == W_AI)
{
my = C_AI;
his = C_PL;
}
if (which == W_PL)
{
my = C_PL;
his = C_AI;
}
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (i == 0 || j == 0)
{
for (int D = 0; D < 4; D++)
{
int mynum = 0;
int hisnum = 1;
int OneScore = 0;
ChessPoint Point = CreatePoint(i, j, 0);
ChessPoint Direc = CreatePoint(direx[D], direy[D], 0);
while (1)
{
if (!IsIn(Point))
{
break;
}
if (GetCB(chessboard, Point) == my)
{
mynum++;
}
else
{
if (GetCB(chessboard, Point) == his)
{
hisnum++;
}
break;
}
Point = AddPoint(Point, Direc);
}
if (mynum == 0)
{
OneScore = 0;
}
else
{
OneScore = GetScore(mynum, hisnum);
}
score += OneScore;
}
}
else if (chessboard[i][j] != my)
{
for(int D = 0; D < 4; D++)
{
int mynum = 0;
int hisnum = 0;
int OneScore = 0;
if (chessboard[i][j] == his)
{
hisnum++;
}
ChessPoint Point = CreatePoint(i, j, 0);
ChessPoint Direc = CreatePoint(direx[D], direy[D], 0);
while (1)
{
Point = AddPoint(Point, Direc);
if (!IsIn(Point))
{
break;
}
if (GetCB(chessboard,Point) == my)
{
mynum++;
}
else
{
if (GetCB(chessboard,Point) == his)
{
hisnum++;
}
break;
}
}
if (mynum == 0)
{
OneScore = 0;
}
else
{
OneScore = GetScore(mynum, hisnum);
}
score += OneScore;
}
}
}
}
return score;
}
ChessPoint GetMaxPoint(char chessboard[][COLS], int which)
{
if (!IsWhich(which))
{
return CreatePoint(-1, -1, -1);
}
char MY = '\0', HIS = '\0';
if (which == W_AI)
{
MY = C_AI;
HIS = C_PL;
}
if (which == W_PL)
{
MY = C_PL;
HIS = C_AI;
}
int Minx = ROWS - 1, Maxx = 0;
int Miny = COLS - 1, Maxy = 0;
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (chessboard[i][j] != C_NO)
{
if (i < Minx)
{
Minx = i;
}
if (i > Maxx)
{
Maxx = i;
}
if (j < Miny)
{
Miny = j;
}
if (j > Maxy)
{
Maxy = j;
}
}
}
}
Minx = GetMax(0, Minx - 3);
Maxx = GetMin(ROWS - 1, Maxx + 3);
Miny = GetMax(0, Miny - 3);
Maxy = GetMin(COLS - 1, Maxy + 3);
int IFSCORE[ROWS][COLS];
InitScore(IFSCORE);
for (int i = Minx; i <= Maxx ; i++)
{
for (int j = Miny; j <= Maxy; j++)
{
if (chessboard[i][j] != C_NO)
{
continue;
}
chessboard[i][j] = MY;
int AttackScore = GetChessBoardScore(chessboard, which);
chessboard[i][j] = HIS;
int DefenceScore = GetChessBoardScore(chessboard, SwapWhich(which));
chessboard[i][j] = C_NO;
IFSCORE[i][j] = AttackScore + DefenceScore;
}
}
ChessPoint finalpoint = CreatePoint(Minx, Miny, -999999);
for (int i = Minx; i <= Maxx; i++)
{
for (int j = Miny; j <= Maxy; j++)
{
if (IFSCORE[i][j] > finalpoint.score)
{
finalpoint = CreatePoint(i, j,IFSCORE[i][j]);
}
}
}
return finalpoint;
}
ChessPoint GetBestPoint(char chessboard[][COLS],bool Testing,int round)
{
if (round == 1)
{
int midx = ROWS / 2;
int midy = COLS / 2;
return CreatePoint(midx, midy, 0);
}
char MY = C_AI, HIS = C_PL;
int Minx = ROWS - 1, Maxx = 0;
int Miny = COLS - 1, Maxy = 0;
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (chessboard[i][j] != C_NO)
{
if (i < Minx)
{
Minx = i;
}
if (i > Maxx)
{
Maxx = i;
}
if (j < Miny)
{
Miny = j;
}
if (j > Maxy)
{
Maxy = j;
}
}
}
}
Minx = GetMax(0, Minx - 3);
Maxx = GetMin(ROWS - 1, Maxx + 3);
Miny = GetMax(0, Miny - 3);
Maxy = GetMin(COLS - 1, Maxy + 3);
int SCORE[ROWS][COLS];
InitScore(SCORE);
for (int i = Minx; i <= Maxx; i++)
{
for (int j = Miny; j <= Maxy; j++)
{
if (chessboard[i][j] != C_NO)
{
continue;
}
chessboard[i][j] = MY;
if (GetChessBoardScore(chessboard, W_AI) >= 99999)
{
chessboard[i][j] = C_NO;
return CreatePoint(i, j, 99999);
}
ChessPoint point1 = GetMaxPoint(chessboard, W_PL);
chessboard[point1.x][point1.y] = HIS;
ChessPoint point2 = GetMaxPoint(chessboard, W_AI);
chessboard[point2.x][point2.y] = MY;
int AiScore = GetChessBoardScore(chessboard, W_AI);
int PlScore = GetChessBoardScore(chessboard, W_PL);
if (PlScore >= 12000)
{
ChessPoint histesting = GetMaxPoint(chessboard, W_PL);
chessboard[histesting.x][histesting.y] = HIS;
if (histesting.score >= 99999)
{
if (GetChessBoardScore(chessboard, W_PL) >= 99999)
{
chessboard[point1.x][point1.y] = C_NO;
chessboard[point2.x][point2.y] = C_NO;
chessboard[i][j] = C_NO;
chessboard[histesting.x][histesting.y] = C_NO;
return point1;
}
}
chessboard[histesting.x][histesting.y] = C_NO;
}
SCORE[i][j] = AiScore - PlScore;
chessboard[point1.x][point1.y] = C_NO;
chessboard[point2.x][point2.y] = C_NO;
chessboard[i][j] = C_NO;
if (Testing)
{
std::cout << "if set in " << i << " " << j << std::endl;
std::cout << "best position for pl is " << point1.x << " " << point1.y << std::endl;
std::cout << "then ai should set in " << point2.x << " " << point2.y << std::endl;
std::cout << "score is" << point2.score << std::endl << std::endl;
}
}
}
ChessPoint final = CreatePoint(0, 0, -999999);
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
if (SCORE[i][j] > final.score)
{
final = CreatePoint(i, j, SCORE[i][j]);
}
}
}
if (round <= 7)
{
int FinalX[100];
int FinalY[100];
int Counting = 0;
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
int t = SCORE[i][j] - final.score;
if (-399 <= t && t <= 399)
{
FinalX[Counting] = i;
FinalY[Counting] = j;
Counting++;
Counting %= 100;
}
}
}
if (Counting == 0)
{
return final;
}
int start;
start = GetTickCount64() % 999999;
int tx = (int)start % Counting;
int finalx = FinalX[tx];
int finaly = FinalY[tx];
if (Testing)
{
std::cout << "counting is " << Counting << std::endl;
for (int i = 0; i < Counting; i++)
{
std::cout << FinalX[i] << " " << FinalY[i] << std::endl;
}
}
return CreatePoint(finalx, finaly, SCORE[finalx][finaly]);
}
return final;
}
bool TestWhetherWin(char chessboard[][COLS])
{
int score1 = GetChessBoardScore(chessboard, W_AI);
if (score1 >= 99999)
{
std::cout << "computer win" << std::endl;
return true;
}
int score2 = GetChessBoardScore(chessboard, W_PL);
if (score2 >= 99999)
{
std::cout << " you win" << std::endl;
return true;
}
return false;
}
basic.cpp
#include"basic.h"
#include<limits.h>
bool IsIn(ChessPoint point)
{
int a = point.x;
int b = point.y;
if (a >= 0 && b >= 0 && a < ROWS && b < COLS)
{
return true;
}
return false;
}
bool IsWhich(int a)
{
if (a == W_AI || a == W_PL)
{
return true;
}
return false;
}
ChessPoint CreatePoint(int x, int y,int score)
{
ChessPoint point;
point.x = x;
point.y = y;
point.score = score;
return point;
}
char GetCB(char chessboard[][COLS], ChessPoint point)
{
return chessboard[point.x][point.y];
}
ChessPoint AddPoint(ChessPoint point1, ChessPoint point2)
{
ChessPoint point;
point.x = point1.x + point2.x;
point.y = point1.y + point2.y;
point.score = point1.score + point2.score;
return point;
}
int SwapWhich(int which)
{
if (which == W_AI)
{
return W_PL;
}
if (which == W_PL)
{
return W_AI;
}
else
{
return -1;
}
}
void InitScore(int IFSCORE[][COLS])
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
IFSCORE[i][j] = -999999;
}
}
}
game.cpp
#include<graphics.h>
#include"basic.h"
void starting()
{
initgraph(LENGTH, WIDTH);
setbkcolor(RGB(150, 200, 100));
cleardevice();
Sleep(10000);
}
void endgame()
{
closegraph();
}
play.cpp
#include"basic.h"
#include"ai.h"
#include"test.h"
#include<iostream>
void play(char chessboard[][COLS])
{
system("color 0A");
InitChessBoard(chessboard);
int round = 0;
while (true)
{
round++;
std::cout << round << std::endl;
if (round % 2 == 1)
{
std::cout << "it is computer's turn..." << std::endl;
ChessPoint point = GetBestPoint(chessboard, false, round);
chessboard[point.x][point.y] = C_AI;
}
if (round % 2 == 0)
{
std::cout << "it is your turn..." << std::endl;
int x, y;
std::cin >> x >> y;
ChessPoint point = CreatePoint(x, y, 0);
while (!IsIn(point) || chessboard[x][y] != C_NO)
{
std::cout << "you can not set in this position" << std::endl;
std::cin >> x >> y;
}
chessboard[x][y] = C_PL;
}
system("cls");
PrintChessBoard(chessboard);
if (TestWhetherWin(chessboard))
{
break;
}
}
}
test.cpp
#include"basic.h"
#include"ai.h"
#include<iostream>
void InitChessBoard(char chessboard[][COLS])
{
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
chessboard[i][j] = C_NO;
}
}
}
void PrintChessScore(char chessboard[][COLS])
{
std::cout << std::endl << "chessboard score is: " << std::endl;
std::cout << "ai:" << GetChessBoardScore(chessboard, W_AI) << std::endl;
std::cout << "player:" << GetChessBoardScore(chessboard, W_PL) << std::endl;
ChessPoint point = GetMaxPoint(chessboard, W_AI);
std::cout << "max score position is: ";
std::cout << point.x <<" " << point.y << std::endl;
static int i = 0;
ChessPoint point3 = GetBestPoint(chessboard,false,++i);
std::cout << "best position is: ";
std::cout << point3.x << " " << point3.y << std::endl;
}
void PrintChessBoard(char chessboard[][COLS])
{
std::cout << "print chessboard:" << std::endl;
std::cout << " ";
for (int i = 0; i < COLS; i++)
{
std::cout << i%10 << " ";
}
std::cout << std::endl;
for (int i = 0; i < ROWS; i++)
{
std::cout << i%10 << " ";
for (int j = 0; j < COLS; j++)
{
std::cout << chessboard[i][j] << " ";
}
std::cout << std::endl;
}
}
void ScanfChessBoard(char chessboard[][COLS])
{
ChessPoint point;
int which;
while (true)
{
std::cin >> point.x >> point.y>>which;
if (!IsIn(point)||!IsWhich(which))
{
break;
}
if (which == W_AI)
{
chessboard[point.x][point.y] = C_AI;
}
else if(which==W_PL)
{
chessboard[point.x][point.y] = C_PL;
}
PrintChessBoard(chessboard);
PrintChessScore(chessboard);
}
}
void testing(char chessboard[][COLS])
{
InitChessBoard(chessboard);
ScanfChessBoard(chessboard);
}
main.cpp
#include"basic.h"
#include"test.h"
#include"play.h"
#include"game.h"
#include<iostream>
int main()
{
std::cout << "choose your mode\n1.play 2.test\n";
int x;
char chessboard[ROWS][COLS];
std::cin >> x;
while (x != 1 && x != 2)
{
std::cout << "please choose again\n";
std::cin >> x;
}
if (x == 1)
{
play(chessboard);
}
if (x == 2)
{
testing(chessboard);
}
return 0;
}