基于C++的人工智能单机版棋类游戏开发

发布时间:2024年01月24日

目 录

摘要 1
ABSTRACT 2
1绪论 3
1.1 课题研究背景 3
1.2 国内外研究现状 5
1.3 主要研究内容及方法 6
1.4 论文组织结构 6
2 相关研究工作技术概述 7
2.1 人工智能 7
2.2 博弈论 9
2.2.1 基本定义 9
2.2.2 应用与影响 10
2.3 棋类游戏介绍 11
3 算法设计 12
3.1 五子棋相关技术介绍 12
3.2 棋类游戏基础算法概述 13
3.2.1 盲目搜索算法 13
3.2.2 极大极小算法 14
3.2.3 ALPHA-BETA剪枝算法 16
3.3 五子棋算法设计 18
4 系统设计与实现 25
4.1 总体程序框架 25
4.2 程序界面设计 28
4.2.1 计算机图形学概述 28
4.2.2 界面设计与人机交互 31
4.3 读档功能 36
4.4 悔棋功能 37
4.5 测试 38
5 总结和未来展望 39
参考文献 40
在搜索方面,在极大与极小值计算的基础上经过改进而得到的Alpha-Beta剪枝计算,具有非常广阔的应用。不过,由于使用Alpha-Beta剪枝计算的搜索深度进一步提升,此计算法所耗费的时间和硬件资源也呈指数式上升,这样造成了检索节点较多且检索时限较长的弊端。这些缺陷,在普通计算机中会影响搜寻深度的提高,会影响搜寻效果和博弈水平.
在估值方面,五子棋主要采用基于模型的估值方式。这种估值方式优点在于简单直接,拥有较高的准确性,劣势在于对于棋型的划分与其价值的设定通常根据经验获得且需要通过手动操作进行调整,存在着不稳定性。
1.3主要研究内容及方法
本课题主要的研究内容是通过C++开发一个能够实现计算机与玩家对弈的五子棋游戏程序,并在后期通过玩家对其进行测试,最终对五子棋游戏软件对弈算法的性能进行评估。具体如下:

  1. 使用C++对软件进行开发,对五子棋对弈平台进行编程实现。
  2. 利用EAZY-X图包中地图形设计图形界面。
  3. 对搜索算法进行构思与搭建,并通过多次尝试挑选出最合适的搜索方案。
    4.对赋值算法进行搭建与调试,给予不同的棋型以不同的得分。并在初步定下赋值后进行调试,找出最合适的赋值方案。
    5.通过多次测试,思考该五子棋程序图形界面与算法中的不足,思考算法与图形界面设计的改进。
    1.4 论文组织结构
    本文的组织结构主要分为以下五章:
    第一章:介绍课题相关背景;国内外关于计算机博弈与人工智能算法的相关情况,并大致介绍本课题的研究方法。
    第二章:主要具体介绍本课题的相关技术。首先对计算机博弈进行了介绍。随后对五子棋相关算法做概述,并介绍AlphaGo五子棋软件的相应知识。
    第三章:对五子棋的对弈算法做详细介绍,首先具体介绍五子棋的经典算法,随后具体介绍本程序所使用的针对基础规则的五子棋的对弈算法。
    第四章:在第三章的人工智能五子棋算法的介绍的基础上,本章我们将会对计算机图形学与程序的图形界面设计进行详细的介绍。其主要包括程序的主界面,各项功能与游戏界面的设计。
#undef UNICODE
#include "stdafx.h"
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#define W 640
#define H 640
#define WIDTH 25
#define NUM	15

//两边无棋子系列
#define NONE1	0
#define NONE2	10
#define NONE3	3000
#define NONE4	10000//必胜
#define NONE5	100000//必胜

//两边都有棋子系列
#define BOTH1	0
#define BOTH2	3
#define BOTH3	100
#define BOTH4	500
#define BOTH5	100000

#define SIDE1	0
#define SIDE2	5
#define SIDE3	500
#define SIDE4	1000//胜利
#define SIDE5	100000


struct {
	int type;
	int success;
}mSuccess;//成功信息

enum {
	GAME_MENU,
	GAME_RUN
}g_GameDraw;//界面绘制状态

enum {
	GAME_MENU1,
	GAME_RUN1,
	GAME_SUCCESS
}g_GameState;//逻辑处理

struct
{
	int x;
	int y;
	int w;
	int h;
	bool draw;
}rect[3];

int round = 1;//初始化回合数
int mx, my;
int IsMousePaint = true;
int Chess[NUM][NUM] = { 0 };
int person = 1;
int Success;
int Back[NUM][NUM] = { 0 };

void AIPlay(int* x, int* y);//电脑下棋
bool Judge(int x, int y);//判断是否胜利
void draw_Chess(int, int, int);//画棋子
void drawAllChess(int x, int y);//绘制所有棋子
void drawBoard(int x, int y);//画棋盘
int GetType(int Num, int type);//获取类型分数
int GetScore(int x, int y, int type);//

void OnPaint();
int WndProc(MOUSEMSG);

//void playChess(int,int,int);//函数声明

char* str[] = { "新游戏", "读档开始", "退出" };//初始界面指示





int main(int argc, char* argv[])
{
	initgraph(640, 480);//初始界面

	MOUSEMSG m;		// 定义鼠标消息
	g_GameDraw = GAME_MENU;
	g_GameState = GAME_MENU1;

	rect[0].draw = false;
	rect[1].draw = false;
	rect[2].draw = false;//键变色

	while (true)
	{
		// 获取一条鼠标消息
		while (MouseHit())
		{
			m = GetMouseMsg();
			WndProc(m);
		}
	}

	// 关闭图形窗口

	closegraph();

	return 0;
}


//消息处理程序
int WndProc(MOUSEMSG m)
{
	HWND hWnd = GetHWnd();
	switch (g_GameState)//逻辑处理
	{
	case GAME_MENU1:
		switch (m.uMsg)
		{
		case WM_MOUSEMOVE:
			//处理鼠标移动
			if (m.x >= rect[0].x && m.x <= rect[0].w && m.y >= rect[0].y && m.y <= rect[0].h)
			{
				//响应
				rect[0].draw = true;
			}
			else
				rect[0].draw = false;
			if (m.x >= rect[1].x && m.x <= rect[1].w && m.y >= rect[1].y && m.y <= rect[1].h)
			{
				//响应
				rect[1].draw = true;
			}
			else
				rect[1].draw = false;
			if (m.x >= rect[2].x && m.x <= rect[2].w && m.y >= rect[2].y && m.y <= rect[2].h)
			{
				//响应
				rect[2].draw = true;
			}
			else
				rect[2].draw = false;
			break;
		case WM_LBUTTONUP:
			//鼠标按下弹起
			if (m.x >= rect[0].x && m.x <= rect[0].w && m.y >= rect[0].y && m.y <= rect[0].h)
			{
				//响应
				g_GameDraw = GAME_RUN;//进入游戏界面的绘制
				g_GameState = GAME_RUN1;//进入游戏界面的逻辑处理
				rect[0].draw = false;
				rect[1].draw = false;
				rect[2].draw = false;//键变色

			}
			else if (m.x >= rect[1].x && m.x <= rect[1].w && m.y >= rect[1].y && m.y <= rect[1].h)
			{
				rect[0].draw = false;
				rect[1].draw = false;
				rect[2].draw = false;//键变色

				FILE* fp;
				fp = fopen("recode.txt", "r");
				if (fp == NULL)
				{
					MessageBox(hWnd, "存档文件不存在", "提示", MB_OK);
				}
				int i, j;
				for (i = 0;i < NUM;i++)
					for (j = 0;j < NUM;j++)
						fscanf(fp, "%d\t", &Chess[i][j]);
				fscanf(fp, " %d", &round);

				fclose(fp);
				g_GameDraw = GAME_RUN;
				g_GameState = GAME_RUN1;

			}
			else if (m.x >= rect[2].x && m.x <= rect[2].w && m.y >= rect[2].y && m.y <= rect[2].h)
			{
				closegraph();
				exit(0);//退出
			}
			break;//只处理鼠标移动信息和鼠标按下弹起信息
		case WM_RBUTTONDOWN:
			break;
		case WM_RBUTTONUP:
			//
			break;
		default:
			break;
		}
		break;

	case GAME_RUN1:
		int xId, yId;
		if (person == 2)
		{
			//电脑
			AIPlay(&xId, &yId);
			Chess[xId][yId] = 2;

			if (Judge(xId, yId))//如果成功
			{
				g_GameState = GAME_SUCCESS;
			}
			person = 1;
			break;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/newlw/article/details/135739861
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。