具有线程和 DirectX Draw 的快速版康威生命游戏






4.42/5 (13投票s)
快速版康威生命游戏,带有线程和 DirectX 绘制。

引言
本文介绍了一个使用MFC、线程和DirectX的快速康威生命游戏版本,并附带了排序算法的可视化演示。它也是“冒泡排序”和“快速排序”算法的可视化演示。
康威生命游戏
生命游戏,也简称为生命,是由英国数学家约翰·何顿·康威于1970年设计的元胞自动机。它是元胞自动机中最著名的例子。“游戏”实际上根本不是游戏。康威的系统更像是一种生命模拟,这意味着它的演化是由其初始状态决定的,不需要人类玩家的进一步输入。通常情况下,人们通过创建初始配置并观察其演化来与生命游戏进行交互,但是在这个应用程序中,您可以通过鼠标点击添加或移除相邻单元格来干预演化过程。
康威生命游戏的规则
“生命游戏的宇宙是一个无限的二维正交方格单元格网格,每个单元格都处于两种可能的状态之一,即存活或死亡。每个单元格都与其八个邻居相互作用,这些邻居是直接水平、垂直或对角线相邻的单元格。在时间的每个步骤中,都会发生以下转换
- 任何活细胞如果活邻居少于两个,则死亡,就好像由于人口不足而死亡一样。
- 任何拥有多于三个存活邻居的存活细胞都会因过度拥挤而死亡。
- 任何拥有两个或三个存活邻居的存活细胞将保持存活,不变,进入下一代。
- 任何死细胞如果正好有三个活邻居,则变成活细胞。
初始图案构成系统的“种子”。第一代是通过同时将上述规则应用于种子中的每个单元格来创建的——出生和死亡同时发生,发生这种情况的离散时刻有时被称为滴答。(换句话说,每一代都是前一代的纯函数。)规则会重复应用,以创建进一步的世代。”
http://en.wikipedia.org/wiki/Conway's_Game_of_Life
背景
我创建这个项目是为了使用DirectX绘制测试康威生命游戏的算法,我发现它非常有趣。
使用应用程序

使用工具栏
- 创建文档 - 创建康威生命游戏或排序的新MDI视图
- 打开现有文档 - 打开康威生命游戏(*.lif)或排序(*.sor)的现有文档
- 保存文档 - 保存康威生命游戏(*.lif)或排序(*.sor)的MDI框架
- 打开康威生命游戏的文档
- 打开排序的文档
- 随机初始化康威生命游戏的模式
- 开始当前活动MDI框架的计算
- 停止计算
- 清除活动视图中的所有单元格并停止计算
- 一个切换开关,用于显示或隐藏网格
- 减慢速度 - 减慢康威生命游戏进一步世代的创建速度
- 加快速度 - 加快康威生命游戏进一步世代的创建速度
- 颜色设置 - 设置康威生命游戏或排序条中单元格的颜色
使用鼠标
- 鼠标左键单击以添加或删除单元格。这对于手动创建初始图案或通过添加新的相邻单元格来更改稳定图案使其处于活动状态非常有用。此外,您可以通过鼠标单击添加或移除相邻单元格来干预演化过程。用户创建的初始图案可以保存并加载,“保存文档”/“打开文档”。
- 通过按下左键移动鼠标光标来在一行中添加/删除单元格。您可以轻松创建任何您想要的初始图案。
- 右键单击在排序视图中执行“快速排序”。
代码中
创建一个独立线程来实现康威生命游戏或排序的算法
void CSortAndLifeView::CreatSortThread()
{
unsigned threadID;
if(hThread)
CloseHandle(hThread);
hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc, this, CREATE_SUSPENDED,
&threadID);
ResumeThread(hThread);
}
unsigned int __stdcall CSortAndLifeView::thread_proc(void* pv)
{
CSortAndLifeView *this_ = reinterpret_cast<CSortAndLifeView*>(pv);
if(this_->m_bDocumentType == DOCTYPE_LIFE)
this_->OnLifeGame();
else if(this_->m_bDocumentType == DOCTYPE_BUBBLESORT)
this_->OnBubbleSort();
else if(this_->m_bDocumentType == DOCTYPE_QUICKSORT)
this_->OnQuickSort();
_endthreadex( 0 );
return 0;
}
重写OnPaint
方法CFomView
类以实现DirectX绘制
void CSortAndLifeView::OnPaint()
{
CPaintDC dc(this);
OnDraw(&dc);
}
void CSortAndLifeView::OnDraw(CDC* pDC)
{
// TODO: add draw code for native data here
CSortAndLifeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
GetClientRect(&rectView);
if(m_bDocumentType == 0)
m_directXObj.CellDraw((char *)pDoc->m_cCellArray,pDoc->m_cellColor,rectView);
else
m_directXObj.BarDraw((int *)pDoc->m_nNumberArray,pDoc->m_barColor,rectView);
m_directXObj.Display();
}
康威生命游戏的单元格大小可以通过在StdAfx.h中设置网格编号来更改。
const int CONST_INT_GRIDNUMBER = 50;
关注点
使用线程和分布式网格计算,该应用程序创建了一个快速的康威生命游戏。