C++ 实现对战AI五子棋

个人主页:日刷百题

系列专栏〖C/C++小游戏〗*** 〖Linux〗 〖数据结构〗** C语言*

🌎欢迎各位点赞👍+收藏⭐️+留言📝

前言:

为了能够快速上手一门语言,我们往往在学习了基本语法后,采用写一个小项目的方式来加深理解语言的语法及运用,本文采用c++去实现对战AI五子棋,采用面向对象开发的一款游戏,里面应用了类和对象以及vector容器等知识。

一、项目效果展示



二、游戏思路


三、游戏框架

我们这里创建四个类(可以简单的理解为加强版的结构体),玩家类、AI类、棋盘类、棋盘控制类,将玩家类、AI类、棋盘类作为参数传给棋盘控制类,棋盘控制类获取这三个类的信息,从而可以控制游戏的运行,而玩家和AI要进行下棋操作时,需要棋盘信息,所以在玩家和AI类设置棋盘类。

根据上面分析,我们搭建好框架,先实现棋盘类功能,再实现AI和玩家类,最后实现棋盘控制类

四、棋盘类实现

4.1 用棋盘类构造函数初始化

4.1.1 checkerboard.h

cpp 复制代码
#include<graphics.h>//eaysx头文件
#include<vector>
using namespace std;
enum  GameResult { BLACK_WIN,WHITE_WIN,DRAW ,CONTINUE};
class checkerboard
{
public:
	//构造函数初始化成员变量
	checkerboard(int BoardSize, int margin_x, int margin_y, float ChessSize)
	{
		this->BoardSize = BoardSize;//几线棋盘
		this->margin_x=margin_x;
		this->margin_y = margin_y;
		this->ChessSize = ChessSize;//棋子大小

		 //加载黑子和白子图片到黑子和白子变量
		loadimage(&BLACK_IMG, "res/black.png", ChessSize, ChessSize, true);
		loadimage(&WHITE_IMG, "res/white.png", ChessSize, ChessSize, true);
		
	//棋盘初始化
		for (int i = 0; i < ChessSize; i++)
		{
			vector<int> row;
			for (int j = 0; j < ChessSize; j++)
			{
				row.push_back(0);
			}
			BoardMap.push_back(row);
		}

		
		 gameresult= CONTINUE;
		

	}

	

	int BoardSize;//棋盘大小
	float ChessSize;//棋子大小
	vector<vector<int>> BoardMap;//表示棋盘落子情况
private:
	IMAGE BLACK_IMG;//黑棋图片变量
	IMAGE WHITE_IMG;//白棋图片变量
	
	int margin_x;//左侧边界45
	int margin_y;//右侧边界45


};

4.2 棋盘类初始化函数

注:

这个初始化函数和棋盘类构造函数的初始化一样,为什么再初始化一次呢?因为我们后面进行游戏运行时,一局结束,再来一局还需要再调用一次棋盘初始化,而定义棋盘类只能调用一次构造函数,所以再创一个棋盘类初始化函数

4.2.1 checkerboard.h

cpp 复制代码
pubilc:
void Init();//棋盘初始化

4.2.2 checkerboard.cpp

cpp 复制代码
void checkerboard::Init()
{
    initgraph(L, W, 1);//窗口大小
    //加载到窗口棋盘图片
    loadimage(0, "res/棋盘2.jpg", L,W,true);
    //播放声音
  /*  mciSendString("play res/start.WAV", 0, 0, 0);*/
    //加载黑子和白子图片到黑子和白子变量
    //loadimage(&BLACK_IMG, "res/black.png", ChessSize, ChessSize, true);
    //loadimage(&WHITE_IMG, "res/white.png", ChessSize, ChessSize, true);

    //后面没有调用构造函数,调用初始化,所有在这里还需要对容器归0
    for (int i = 0; i < ChessSize; i++)
    {
        
        for (int j = 0; j < ChessSize; j++)
        {
            BoardMap[i][j] = 0;
        }
        
    }

    gameresult = CONTINUE;
  
}

4.3 检查鼠标点击是否有效

注:

虽然代码很长,但是思路很简单,先计算点击位置(x,y) 附近的4个落棋位置的实际坐标位置,然后再计算点击位置到这四个落棋位置之间的距离,如果落棋位置与点击位置距离小于棋子大小的0.4倍,就认为这个落棋位置是玩家想要落棋的位置,存储在pos中。若此时该位置没有其他棋子,则为有效点击,返回真。

4.3.1 checkerboard.h

棋盘类外:

cpp 复制代码
//落子位置
struct ChessPos
{
	int row;
	int col;
};
enum  chess_type{CHESS_WHITE=-1,CHESS_BLACK=1};

棋盘类内:

cpp 复制代码
public:
bool ClickBord(int x, int y, ChessPos& pos);//检查有效点击

4.3.2 checkerboard.cpp

cpp 复制代码
bool checkerboard::ClickBord(int x, int y, ChessPos& pos)
{
    //保证在棋盘内
    if (x >= margin_x && x <= (L - margin_x) && y >= margin_y && y <= (W - margin_y))
    {
        int col = (x - margin_x) / ChessSize;
        int row = (y - margin_y) / ChessSize;
        //该位置左上角的交点的坐标
        int LTPos_x = margin_x + ChessSize * col;
        int LTPos_y = margin_y + ChessSize * row;

        int critical = ChessSize * 0.4;//临界值
        //鼠标点击位置与右上角交点之间的距离
        int distance1 = sqrt((x - LTPos_x) * (x - LTPos_x) + (y - LTPos_y) * (y - LTPos_y));//勾股定理


         //该位置右上角的交点的坐标
        int RTPos_x = LTPos_x + ChessSize;
        int RTPos_y = LTPos_y;


        //鼠标点击位置与右上角交点之间的距离
        int distance2 = sqrt((x - RTPos_x) * (x - RTPos_x) + (y - RTPos_y) * (y - RTPos_y));//勾股定理

         //该位置左下角的交点的坐标
        int LDPos_x = LTPos_x;
        int LDPos_y = LTPos_y + ChessSize;


        //鼠标点击位置与左下角交点之间的距离
        int distance3 = sqrt((x - LDPos_x) * (x - LDPos_x) + (y - LDPos_y) * (y - LDPos_y));//勾股定理



         //该位置右下角的交点的坐标
        int RDPos_x = LTPos_x + ChessSize;
        int RDPos_y = LTPos_y + ChessSize;


        //鼠标点击位置与右下角交点之间的距离
        int distance4 = sqrt((x - RDPos_x) * (x - RDPos_x) + (y - RDPos_y) * (y - RDPos_y));//勾股定理
        if (distance1 <= critical)
        {
            pos.col = col;
            pos.row = row;
            if (BoardMap[pos.row][pos.col] == 0)//该坐标没有棋子
            {
                return true;
            }
            return false;

        }
        else if (distance2 <= critical)
        {
            pos.col = col + 1;
            pos.row = row;
            if (BoardMap[pos.row][pos.col] == 0)//该坐标没有棋子
            {
                return true;
            }
            return false;


        }
        else if (distance3 <= critical)
        {
            pos.col = col;
            pos.row = row + 1;
            if (BoardMap[pos.row][pos.col ] == 0)//该坐标没有棋子
            {
                return true;
            }
            return false;


        }
        else if (distance4 <= critical)
        {
            pos.col = col + 1;
            pos.row = row + 1;
            if (BoardMap[pos.row ][pos.col] == 0)//该坐标没有棋子
            {
                return true;
            }
            return false;


        }
        else
        {
            return false;
        }
    }

    else
    {
        return false;
    }
}

4.4 下棋

功能:实现记录最后一次落子的位置以及最后一次下棋是玩家方还是AI方,在棋盘二维数组记录落子数据。

4.4.1 checkerboard.h

棋盘类外:

cpp 复制代码
//落子位置
struct ChessPos
{
	int row;
	int col;
};
enum  chess_type{CHESS_WHITE=-1,CHESS_BLACK=1};

棋盘类内:

cpp 复制代码
public:
	void PlayChess(ChessPos& pos,chess_type type);//下棋

4.4.2 checkerboard.cpp

cpp 复制代码
void checkerboard::PlayChess(ChessPos& pos, chess_type type)
{
    int x = margin_x + ChessSize * pos.col-ChessSize*0.5;
    int y = margin_y + ChessSize * pos.row- ChessSize *0.5;
   
        BoardMap[pos.row][pos.col] = type;
        lastpos.row = pos.row;
        lastpos.col = pos.col;
        lasttype = type;
    
    if (type == CHESS_BLACK)
    {
        putimagePNG(x, y, &BLACK_IMG);
       
    }
    else
    {
        putimagePNG(x, y, &WHITE_IMG);

    }
}

4.5 判断棋盘是否下满

4.5.1 checkerboard.h

cpp 复制代码
bool BoardFull();

4.5.2 checkerboard.cpp

cpp 复制代码
bool checkerboard::BoardFull()
{
    for (int row = 0; row < BoardSize; row++)
    {
        for (int col = 0; col < BoardSize; col++)
        {
            if (BoardMap[row][col] == 0)//棋盘没满
            {
                return false;
            }
        }
   }
    return true;
}

4.6 判断游戏状态

4.6.1 checkerboard.h

棋盘类外:

cpp 复制代码
enum  GameResult { BLACK_WIN,WHITE_WIN,DRAW ,CONTINUE};

棋盘类内:

cpp 复制代码
private:
GameResult gameresult;
GameResult IsWin();

4.6.2 checkerboard.cpp

cpp 复制代码
GameResult checkerboard::IsWin()
{
    bool boardfull = BoardFull();
    
    //每个方向记连续棋子个数
    int Black_Num = 0;
    int  White_Num = 0;
    if (lasttype == CHESS_BLACK)//黑子方
    {
        //计算四个方向是否有5个
        for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向
        {
            for (int j = -1; j <= 1; j++)
            {
                //每个方向记连续棋子个数
                Black_Num = 0;
                White_Num = 0;


                if ((i == 0 && j == 0) || (i == 0 && j == 1))
                {
                    continue;
                }
                for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向
                {
                    int Cur_row = lastpos.row + i * k;
                    int Cur_col = lastpos.col + j * k;
                    if (Cur_row >= 0 && Cur_row < BoardSize &&
                        Cur_col >= 0 && Cur_col < BoardSize &&
                        BoardMap[Cur_row][Cur_col] == CHESS_BLACK)
                    {
                        Black_Num++;
                    }

                    else//超出棋盘或者是白子或者空白
                    {
                        break;
                    }
                }
                for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向
                {
                    int Cur_row = lastpos.row - i * k;
                    int Cur_col = lastpos.col - j * k;
                    if (Cur_row >= 0 && Cur_row < BoardSize &&
                        Cur_col >= 0 && Cur_col < BoardSize &&
                        BoardMap[Cur_row][Cur_col] == CHESS_BLACK)
                    {
                        Black_Num++;
                    }
                    else//超出棋盘或者是白子或者空白
                    {
                        break;
                    }
                }
                //判断游戏状态
                if (Black_Num == 4)//5个黑子,游戏结束
                {
                    
                    return BLACK_WIN;
                }
                else
                {
                    if (boardfull)
                    {
                        return  DRAW;
                    }
                    
                }

            }
        }

    }
    else//白子方
    {
        //计算四个方向是否有5个
        for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向
        {
            for (int j = -1; j <= 1; j++)
            {
                //每个方向记连续棋子个数
                Black_Num = 0;
                White_Num = 0;


                if ((i == 0 && j == 0) || (i == 0 && j == 1))
                {
                    continue;
                }
                for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向
                {
                    int Cur_row = lastpos.row + i * k;
                    int Cur_col = lastpos.col + j * k;
                    if (Cur_row >= 0 && Cur_row < BoardSize &&
                        Cur_col >= 0 && Cur_col < BoardSize &&
                        BoardMap[Cur_row][Cur_col] == CHESS_WHITE)
                    {
                        White_Num++;
                    }

                    else//超出棋盘或者是黑子或者空白
                    {
                        break;
                    }
                }
                for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向
                {
                    int Cur_row = lastpos.row - i * k;
                    int Cur_col = lastpos.col - j * k;
                    if (Cur_row >= 0 && Cur_row < BoardSize &&
                        Cur_col >= 0 && Cur_col < BoardSize &&
                        BoardMap[Cur_row][Cur_col] == CHESS_WHITE)
                    {
                       White_Num++;
                    }
                    else//超出棋盘或者是黑子或者空白
                    {
                        break;
                    }
                }
                //判断游戏状态
                if (White_Num == 4)//5个白子,游戏结束
                {

                    return WHITE_WIN;
                }
                else
                {
                    if (boardfull)
                    {
                        return  DRAW;
                    }

                }

            }
        }

    }
    return CONTINUE;
}

4.7 判断游戏是否结束

4.7.1 checkerboard.h

cpp 复制代码
bool CheckOver();//检查游戏是否结束 

4.7.2 checkerboard.cpp

cpp 复制代码
bool checkerboard::CheckOver()
{
    gameresult = IsWin();
    if (gameresult == BLACK_WIN)
    {
        Sleep(2000);
        loadimage(0, "res/胜利.jpg",W,L,true);
        //播放声音
        mciSendString("play res/胜利.mp3", 0, 0, 0);
        _getch();
        return true;
    }
    else if (gameresult == WHITE_WIN)
    {
        Sleep(2000);
        loadimage(0, "res/失败.jpg",W , L, true);
        //播放声音
        mciSendString("play res/失败.mp3", 0, 0, 0);
        _getch();//暂停,按任意键继续
        return true;
    }
    else if (gameresult == DRAW)
    {
        Sleep(2000);
        loadimage(0, "res/平局.png",W , L , true);
        _getch();
        return true;
        
    }
    else//继续游戏
    {
        return false;
    }

}

五、玩家类实现

5.1 用玩家类构造函数初始化

5.1.1 chess_player.h

cpp 复制代码
#include"checkerboard.h"
#include"AI.h"
class chess_player
{
public:
	chess_player(checkerboard& checkerboard)
	{
		this->checkerboard = &checkerboard;
	}
	
	void go();
private:
	checkerboard* checkerboard;
};

5.2 玩家下棋

5.2.1 chess_player.h

cpp 复制代码
void go();

5.2.2 chess_player.cpp

cpp 复制代码
void chess_player::go()
{
	
	ChessPos pos;
	while (1)
	{
		MOUSEMSG mousemsg = GetMouseMsg();//鼠标信息结构体变量
		bool click_board = checkerboard->ClickBord(mousemsg.x, mousemsg.y, pos);
		if (mousemsg.uMsg == WM_LBUTTONDOWN &&click_board )//用到checkboard对象的成员
		{
			printf("%d,%d\n", pos.row, pos.col);
			break;
		}
	}
	
	checkerboard->PlayChess(pos, CHESS_BLACK);//黑子下棋的位置(渲染和记录)
}

六、AI类实现

6.1 用AI类构造函数初始化

6.1.1 AI.h

cpp 复制代码
#include"checkerboard.h"
#include<vector>
class AI
{
public:
	AI(checkerboard& checkerboard)//AI构造函数
	{
		this->checkerboard = &checkerboard;
		for (int i = 0; i <checkerboard.ChessSize; i++)
		{
			vector<int> row;
			for (int j = 0; j <checkerboard.ChessSize; j++)
			{
				row.push_back(0);
			}
			ScoreMap.push_back(row);
		}
	}

	void go();

private:
	checkerboard* checkerboard;
	vector<vector<int>>  ScoreMap;
	void  CalculateScore();
	ChessPos   MaxScore();
	
};

6.2 AI计算权值最高的棋盘空白位置

计算棋盘空白位置的权值,首先对该位置的横、竖、上斜、下斜四个方位做判断,以该位置为起点,每个方位只需要在单方向上判断4个棋子位,反方向判断四个棋子位,统计连续的白子或者黑子个数,根据下面的表格给出相应权重值,选择出累计权值最高的位置为AI落子点。

6.2.1 AI.h

cpp 复制代码
private:
	
	vector<vector<int>>  ScoreMap;
	void  CalculateScore();

6.2.2 AI.cpp

cpp 复制代码
void AI::CalculateScore()
{
	int Black_Num = 0;
	int White_Num = 0;
	int Empty_Num = 0;
	for(int row=0;row<checkerboard->BoardSize;row++)
		for (int col = 0; col< checkerboard->BoardSize; col++)
		{
			if (checkerboard->BoardMap[row][col] != 0)//有棋子,则跳过判断
			{
				continue;
			}
			//先假设下黑子,计分情况
			for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向
			{
				for (int j = -1; j <= 1; j++)
				{
					//每个方向记连续棋子个数
					Black_Num = 0;
					 White_Num = 0;
					 Empty_Num = 0;

					if ((i == 0 && j == 0) || (i ==0 && j == 1))
					{
						continue;
					}
					for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向
					{
						int Cur_row = row + i * k;
						int Cur_col = col + j * k;
						if (Cur_row>=0&&Cur_row<checkerboard->BoardSize&&
							Cur_col>=0&&Cur_col<checkerboard->BoardSize&&
							checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_BLACK)
						{
							Black_Num++;
						}
						else if(Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] ==0)
						{
							Empty_Num++;
							break;
						}
						else//超出棋盘或者是白子
						{
							break;
						}
					}
					for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向
					{
						int Cur_row = row - i * k;
						int Cur_col = col - j * k;
						if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_BLACK)
						{
							Black_Num++;
						}
						else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == 0)
						{
							Empty_Num++;
							break;
						}
						else//超出棋盘或者是白子
						{
							break;
						}
					}
					//该位置的得分情况
					if (Black_Num == 1)//2个黑子
					{
						ScoreMap[row][col] += 10;
					}
					else if (Black_Num == 2)//连续三个黑子
					{
						if (Empty_Num == 1)
						{
							ScoreMap[row][col] += 30;
						}
						else if(Empty_Num==2)
						{
							ScoreMap[row][col] += 40;
						}
					}
					else if (Black_Num == 3)//连续4个黑子
					{
						if (Empty_Num == 1)
						{
							ScoreMap[row][col] += 60;
						}
						else if (Empty_Num == 2)
						{
							ScoreMap[row][col] += 200;
						}
					}
					else if (Black_Num == 4)//连续5个黑子
					{
						ScoreMap[row][col] += 20000;
					}
				}
			}
			//假设该位置下白子,计分情况
			for (int i = 0; i <= 1; i++)//分横,竖,上斜,下斜4个方向
			{
				for (int j = -1; j <= 1; j++)
				{
					//每个方向记连续棋子个数
					Black_Num = 0;
					White_Num = 0;
					Empty_Num = 0;

					if ((i == 0 && j == 0) || (i == 0 && j == 1))
					{
						continue;
					}
					for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中的单向
					{
						int Cur_row = row + i * k;
						int Cur_col = col + j * k;
						if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_WHITE)
						{
							White_Num++;
						}
						else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == 0)
						{
							Empty_Num++;
							break;
						}
						else//超出棋盘或者是黑子
						{
							break;
						}
					}
					for (int k = 1; k <= 4; k++)//最多判断五个子,四个方向中单向的另一个方向
					{
						int Cur_row = row - i * k;
						int Cur_col = col - j * k;
						if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == CHESS_WHITE)
						{
							White_Num++;
						}
						else if (Cur_row >= 0 && Cur_row < checkerboard->BoardSize &&
							Cur_col >= 0 && Cur_col < checkerboard->BoardSize &&
							checkerboard->BoardMap[Cur_row][Cur_col] == 0)
						{
							Empty_Num++;
							break;
						}
						else//超出棋盘或者是黑子
						{
							break;
						}
					}
					//该位置的得分情况
					if (White_Num == 0)//1个白子
					{
						ScoreMap[row][col] += 5;
					}
					else if (White_Num == 1)//连续2个白子
					{
						
						ScoreMap[row][col] += 10;
						
					}
					else if (White_Num == 2)//连续3个白子
					{
						if (Empty_Num == 1)
						{
							ScoreMap[row][col] += 25;
						}
						else if (Empty_Num == 2)
						{
							ScoreMap[row][col] += 50;
						}
					}
					else if (White_Num == 3)//连续4个白子
					{
						if (Empty_Num == 1)
						{
							ScoreMap[row][col] += 55;
						}
						else if (Empty_Num == 2)
						{
							ScoreMap[row][col] += 300;
						}
					}
					else if (White_Num == 4)//连续5个白子
					{
						ScoreMap[row][col] += 30000;

					}
				}
			}
		}
}

6.3 选择权值最高的棋盘位置

6.3.1 AI.h

cpp 复制代码
private:
ChessPos   MaxScore();

6.3.2 AI.cpp

cpp 复制代码
ChessPos AI::MaxScore()
{
	int max = 0;
	vector<ChessPos> maxscore_pos;
	ChessPos pos;
	CalculateScore();
	for (int row = 0; row < checkerboard->BoardSize; row++)
	{
		for (int col = 0; col < checkerboard->BoardSize; col++)
		{
			if (ScoreMap[row][col] > max)
			{
				max = ScoreMap[row][col];
				maxscore_pos.clear();
				pos.row = row;
				pos.col = col;
				maxscore_pos.push_back(pos);
			}
			else if (ScoreMap[row][col] == max)
			{
				pos.row = row;
				pos.col = col;
				maxscore_pos.push_back(pos);
			}
		}
	}

	//计分棋盘归0
	for (int i = 0; i < checkerboard->ChessSize; i++)
	{
		for (int j = 0; j < checkerboard->ChessSize; j++)
		{
			ScoreMap[i][j] = 0;
		}
		
	}
	int index = rand() % maxscore_pos.size();
	return maxscore_pos[index];
}

6.4 AI下棋

6.4.1 AI.h

cpp 复制代码
void go();

6.4.2 AI.cpp

cpp 复制代码
void AI::go()
{
	ChessPos pos = MaxScore();
	checkerboard->PlayChess(pos, CHESS_WHITE);//白子下棋的位置(渲染和记录)
}

七、棋盘控制类实现

7.1 用棋盘控制类构造函数初始化

7.1.1 ChessGame.h

cpp 复制代码
#include"chess_player.h"
#include"AI.h"
#include"checkerboard.h"
class ChessGame
{
public:
	ChessGame(chess_player& chess_player, AI& ai, checkerboard& checkerboard)//构造函数初始化
	{
		this->chess_player = &chess_player;
		this->ai = &ai;
		this->checkerboard = &checkerboard;
	}
	void play();//开始游戏


//创建数据成员变量
private:
	chess_player* chess_player;
	AI* ai;
	checkerboard* checkerboard;

};

7.2 控制游戏进行

7.2.1 ChessGame.h

cpp 复制代码
void play();//开始游戏

7.2.2 ChessGame.cpp

cpp 复制代码
//开始游戏

void ChessGame::play()
{
again:
	checkerboard->Init();
	while (1)
	{
		//棋手先走
		chess_player->go();
		if (checkerboard->CheckOver())
		{
			goto  again;
			
		}
		//AI走
		ai->go();
		if (checkerboard->CheckOver())
		{
			
			goto  again;

		}

	}
}

八、主函数

cpp 复制代码
#include<iostream>
#include"ChessGame.h"
int main()
{
	srand((unsigned int)time(NULL));
	checkerboard checkerboard( 13, 45*0.7, 45*0.7,67.25*0.7);//自动调用构造函数
	chess_player chess_player(checkerboard);//自动调用构造函数
	AI ai(checkerboard);//自动调用构造函数;
	ChessGame chessgame(chess_player,ai, checkerboard);//引用传值
	
	chessgame.play();
	return 0;
	

}

完整代码及素材:c和c++代码: 争取每日一更。。。。。。 - Gitee.comhttps://gitee.com/daily-brush-100-questions/c-language-training-camp/tree/master/c++AI%E4%BA%94%E5%AD%90%E6%A3%8B/c++AI%E4%BA%94%E5%AD%90%E6%A3%8B

希望大家阅读完可以有所收获,同时也感谢各位铁汁们的支持。文章有任何问题可以在评论区留言,百题一定会认真阅读!

相关推荐
薛先生_09916 分钟前
js学习语法第一天
开发语言·javascript·学习
guoji778818 分钟前
安全与对齐的深层博弈:Gemini 3.1 Pro 安全护栏与对抗测试深度拆解
人工智能·安全
实在智能RPA26 分钟前
实在 Agent 和通用大模型有什么不一样?深度拆解 AI Agent 的感知、决策与执行逻辑
人工智能·ai
独隅30 分钟前
PyTorch 模型部署的 Docker 配置与性能调优深入指南
人工智能·pytorch·docker
lihuayong37 分钟前
OpenClaw 系统提示词
人工智能·prompt·提示词·openclaw
报错小能手38 分钟前
深入理解 Linux 虚拟内存管理
开发语言·操作系统
邪神与厨二病44 分钟前
Problem L. ZZUPC
c++·数学·算法·前缀和
黑客说1 小时前
AI驱动剧情,解锁无限可能——AI游戏发展解析
人工智能·游戏
踩着两条虫1 小时前
AI驱动的Vue3应用开发平台深入探究(十):物料系统之内置组件库
android·前端·vue.js·人工智能·低代码·系统架构·rxjava