MFC随机博弈黑白棋
随机博弈黑白棋
随机博弈黑白棋
TxyITxs | 随机博弈黑白棋 | 2019.04.21
摘要
通过随机落子,实现黑白棋的博弈。无任何落子规则,棋子死活与围棋中棋子的死活一致,即存在至少一口气。动态模拟双方博弈,但棋盘无落子位置时停止。
设计思路
主要基于时钟来实现动态博弈,考虑博弈的持续性数据修改,黑白双方需要互斥访问数据以及正确界面绘制,通过设置两个时钟,一个时钟主要负责界面背景,棋盘网格,黑白棋子绘制,绘制完后,释放数据使用权;另一个时钟主要负责博弈落子(即修改数据),通过在可落子位置随机选择一个,然后释放数据使用权。
棋盘数据使用N*N大小的一维数组Tdata存储,棋子坐标(x,y)对应的数组通过x*N+y计算。棋盘所用可落子位置通过向量vector<CPoint>Tpos来存储,通过随机产生一个索引来得到一个落子位置,然后将该索引对应Tpos的位置删除,修改Tdata中对应位置的值。
1. UI设计
1.1 利用基于对环框的MFC程序框架来搭建UI界面,主要涉及到界面背景色绘制,棋盘网格绘制,以及通过访问数据绘制棋子。
1.2 棋盘背景绘制
void TChessBgUI(CClientDC *dc)
{
CPen pen(PS_SOLID, 1, RGB(0, 0, 0));
CBrush *pbrush = CBrush::FromHandle((HBRUSH)GetStockObject(GRAY_BRUSH));
dc->SelectObject(&pen);
dc->SelectObject(pbrush);
CRect bg;
GetClientRect(bg);
dc->FillRect(bg, pbrush);
}
1.3 棋盘网格绘制,绘制的起始位置CPoint Tst,绘制的结束位置CpointTed,网格间距Tchline,网格的大小N*N。
void TChessUI(CClientDC *dc)
{
CPen pen(PS_SOLID, 1, RGB(0, 0, 0));
dc->SelectObject(&pen);
for (int i = Tst.x; i <= Ted.x; i += Tchline)
{
dc->MoveTo(i, Tst.y);
dc->LineTo(i, Ted.y);
}
for (int j = Tst.y; j <= Ted.y; j += Tchline)
{
dc->MoveTo(Tst.x, j);
dc->LineTo(Ted.x, j);
}
}
1.4 绘制棋子
void TshowLayout(CClientDC *dc)
{
CPen pen(PS_SOLID, 1, RGB(0, 0, 0));
CBrush *pbrush = NULL;
dc->SelectObject(&pen);
int PieceSize = 10;
for (int i = 0; i < Tcount; i++)
{
for (int j = 0; j < Tcount; j++)
{
if (Tdata[i*Tcount + j] ==1)
{
pbrush = CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH));
dc->SelectObject(pbrush);
dc->Ellipse(Tst.x+Tchline*i-PieceSize, Tst.y+Tchline *j- PieceSize, Tst.x + Tchline*i + PieceSize, Tst.y + Tchline *j + PieceSize);
}
if (Tdata[i*Tcount + j] == -1)
{
pbrush = CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH));
dc->SelectObject(pbrush);
dc->Ellipse(Tst.x + Tchline*i - PieceSize, Tst.y + Tchline *j - PieceSize, Tst.x + Tchline*i + PieceSize, Tst.y + Tchline *j + PieceSize);
}
}
}
}
2.数据存储
2.1 全局变量,需要初始化。
vector<int> Tdata;数值0、1、-1,0代表该位置为空,1代表白棋,-1代表黑棋
vector<CPoint> Tpos;棋盘可落子位置
int Tcount =19;棋盘大小
int Tchline = 30;网格间距
CPoint Tst;棋盘起始位置
CPoint Ted;1棋盘结束位置
int Twhite = -1;先手指示器
bool Ttime = false;时钟调度指示器
3.博弈算法
3.1 随机落子模拟
void SimulationData()
{
default_random_engine dre;//随机数引擎
dre.seed((unsigned)time(NULL));
int pos = -1;
if(!Tpos.empty())
{
pos = dre() % Tpos.size();
if (Twhite==1)
{
Tdata[Tpos[pos].x*Tcount + Tpos[pos].y] = 1;
Twhite = -Twhite;//此时指示需提子的棋子颜色,以及下次落子的颜色
}
else if(Twhite == -1)
{
Tdata[Tpos[pos].x*Tcount + Tpos[pos].y] = -1;
Twhite = -Twhite;
}
Tpos.erase(Tpos.begin() + pos);
}
}
随机索引位置的产生,利用C++ 11新特性,使用随机数random类来产生,头文件#include<random>。
3.2 提子过程,将棋盘上Twhite指示的棋子的死子提出,增加棋盘落子可用位置;
void grape()
{
if (Twhite == 0)return;
else
{
vector<CPoint> grap;
vector<bool> visi;
visi.resize(Tcount*Tcount, false);
grap.clear();
for (int i = 0; i < Tcount; i++)
{
for (int j = 0; j < Tcount; j++)
{
if (Tdata[i*Tcount + j] == Twhite)
{
visi.resize(Tcount*Tcount, false);
if (TisLive(i, j,visi) == false)
grap.push_back(CPoint(i, j));
}
}
}
while (!grap.empty())
{
CPoint p=grap.front();
Tdata[p.x*Tcount+p.y] = 0;
Tpos.push_back(p);
grap.erase(grap.begin());
}
}
}
3.3 提子过程需要判断棋子的死活,利用深度搜索算法,判断棋子s(x,y)的死活,则需判断其四邻接棋子的死活,若s,为活棋,无需提子,返回ture,若s为死棋,则返回false;通过递归来实现。
bool TisLive(unsigned int i, unsigned int j, vector<bool>& visi)
{
if (i<0 || i>Tcount || j<0 || j>Tcount)
return false;
else if (Tdata[i*Tcount + j] == -Twhite)
{
return false;
}
else if (Tdata[i*Tcount + j] == 0)
{
return true;
}
else if(Tdata[i*Tcount+j]==Twhite&&visi[i*Tcount + j]==false)
{
visi[i*Tcount + j] = true;
if (TisLive(i - 1, j,visi))
return true;
if(TisLive(i, j - 1, visi))
return true;
if(TisLive(i+1, j, visi))
return true;
if(TisLive(i , j+ 1, visi))
return true;
}
else return false;
return false;
}
3.4 onTimer函数
在初始化函数中设置两个时钟;
SetTimer(0, 1000, NULL);
SetTimer(1, 10, NULL);
两个时钟总用一个onTimer,通过nIDEvent来识别执行此函数的时钟。一个时钟负责UI绘制,一个时钟模拟数据变化。
void CWhiteBlackChessDlg::OnTimer(UINT_PTR nIDEvent)
{
CClientDC dc(this);
switch (nIDEvent)
{
case 0:
{
if (Ttime)
{
SimulationData();
grape();
Ttime = false;
}
}
break;
case 1:
{
if (!Ttime)
{
TChessBgUI(&dc);
TChessUI(&dc);
TshowLayout(&dc);
Ttime = true;
if (Tpos.empty())
{
KillTimer(0);
KillTimer(1);
}
}
}break;
default:break;
}
CDialogEx::OnTimer(nIDEvent);
}
3.5 初始化函数
void TInit()
{
Tdata.resize(Tcount*Tcount,0);
Tpos.resize(Tcount*Tcount);
Tst.SetPoint(30, 30);
Ted.SetPoint(Tchline * Tcount, Tchline * Tcount);
for (int i = 0; i < Tcount; i++)
{
for (int j = 0; j < Tcount; j++)
Tpos[i*Tcount + j] = CPoint(i, j);
}
}
总结
- 在实践过程中,动态模拟的持续性,采用面向过程的算法设计思路,常常导致程序阻塞,因为动态模拟需要使用循环,这可能导致数据一直动态修改,由于循环,导致无法执行到界面绘制代码,界面的控制信息无法捕捉和执行,鉴于这种情况,可以采用时钟或者多线程来实现。
- UI界面采用了模块化设计思路,对程序的复用提供了可能;
- 可以利用该框架,重写提子或落子函数,模拟自然界中的动态变化现象,可以通过直观UI看到变化情况。
- 目前程序尚不完善。
MFC随机博弈黑白棋相关推荐
- [BZOJ2281][SDOI2011]黑白棋(K-Nim博弈)
2281: [Sdoi2011]黑白棋 Time Limit: 3 Sec Memory Limit: 512 MB Submit: 626 Solved: 390 [Submit][Status ...
- 基于Python实现的黑白棋强化学习模型
资源下载地址:https://download.csdn.net/download/sheziqiong/85658862 一.基本原理 1. 强化学习 强化学习是指一类从(与环境)交互中不断学习的问 ...
- 人工智能导论实验2——野人渡河黑白棋问题
人工智能导论实验2--野人渡河&黑白棋问题 实验目的及要求: 本项目要求能够理解人工智能的基本原理,理解状态空间的概念.原理和方法,掌握用状态空间表示问题的步骤,掌握搜索方法的基本原理,并能够 ...
- C++程设实验项目三:黑白棋与基于UCT算法的AI
在这篇博客里,我将总结一下在这次实验中学到的UCT算法实现原理. 首先是参考文章: https://blog.csdn.net/u014397729/article/details/27366363 ...
- Visual C++实现黑白棋游戏项目实战二:界面的设计与实现(附源码和资源 超详细)
需要源码和资源请点赞关注收藏后评论区留言私信~~~ 黑白棋游戏的Visual C++工程采用MFC对话框模式进行开发,下面对它进行详细介绍 一.游戏菜单的实现 首先要在工程资源中添加一个菜单资源类,菜 ...
- JAVA黑白棋之算法浅析
引言 本为主要对我在开发JAVA黑白棋人机算法过程中所用的博弈思想.估值函数.搜索算法分3个方面进行了阐述,由于本人水平有限,如果大家希望了解更多有关黑白棋博弈策略以及人机算法的深入的理论研究, ...
- 【Python案例】基于Pygame黑白棋游戏(附源码)
有没有小火伴是特别喜欢玩五子棋的,我记得我初中是特别喜欢的.于是,我今天就用Python给大家写了一个黑白棋游戏.代码放在下面了. 01.绘制棋盘 Python学习交流Q群:906715085### ...
- 吴昊品游戏核心算法 Round 9 —— 正统黑白棋AI(博弈树)
黑白棋程式简史 在1980年代,电脑并不普及,在黑白棋界里,最强的仍然是棋手(人类). 到了1990年代初,电脑的速度以几何级数增长,写出来的黑白棋程式虽然仍然有点笨拙,但由于计算深度(电脑的速度快) ...
- c语言课程设计之黑白棋游戏,c语言课程设计黑白棋游戏.doc
您所在位置:网站首页 > 海量文档  > 学术论文 > 大学论文 c语言课程设计黑白棋游戏.doc26页 本文档一共被 ...
最新文章
- 文本读取写入易错问题
- Codechef Chef Cuts Tree
- h5手机端浏览器机制_H5测试介绍
- VS2008 ,TFS2008破解序列号
- AT3968-[AGC025E] Walking on a Tree【构造】
- MyEclipse配置进行Hibernate逆映射
- shell初学之nginx(域名)
- windows快速全局检索文件工具-Listary
- SEO实战密码(第3版) 60天网站流量提高20倍-3
- C# ManualResetEvent 类分析
- 短视频去水印解析二次运用--全网短视频解析去水印软件
- Flash遮罩之光芒四射、佛光普照
- ad软件one pin错误是啥意思_AD19的错误提示大总结解释
- oracle HTTP Server安装和配置为集群代理(linux)
- 遥感SCI期刊模板下载教程———IEEE TGRS、GRSL、JSTARS
- 有没有英语语音测试软件,推荐我用过的几款真正可以找外国人练口语的软件app...
- 计步器(Pedometer)实现原理简介
- gmap mysql cachet,MySQL的缓存(Query Cache)
- 视觉工程师必须知道选型知识与计算方法
- Day02:基本IO操作
热门文章
- LeetCode 624. 数组列表中的最大距离
- LeetCode 828. 统计子串中的唯一字符(中心扩展)
- LeetCode 390. 消除游戏(类似约瑟夫环,找映射规律)
- 天玑720支持鸿蒙系统吗,天玑720属于骁龙多少 天玑720处理器相当于骁龙几
- php中写salt,请快速检查这个PHP+SALT实现-不工作?
- java 不重启部署_一篇文章带你搞定SpringBoot不重启项目实现修改静态资源
- python-mysql超简单银行转账
- ARM的UART实验
- 这可能是你与 AI 大神们近距离接触的唯一机会……
- 刷新SOTA!Salesforce提出跨模态对比学习新方法,仅需4M图像数据!