五子棋AI

项目演示

代码

 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;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值