/*
连连看游戏设计:
主要包含游戏局面的状态描述,游戏规则的描述:状态的合法转移(哪些操作满足规则,经过这些操作,达到哪些状态)。自动机模型适合描述游戏设计。
如何求出相同图形之间的最短路径,最短路径的转弯数目最少,转弯数目最少时,经过格子数目尽可能少。
最短路径中:把最短路径问题的目标函数改为从一个点到另一个店的转弯次数。广度优先搜索
首先把图形A(x1,y1)压入队列,然后扩展A(x1,y1)可以直线到达的格子,假设这些格子的集合为S0,S0 =Find(x1,y1),如果图形B(x2,y2)在S0zhong ,结束搜索。
A和B可以用直线连接。
否则,低于所有S0集合中的空格子(没有图形),分别找到它们可以直线到达的格子,假设该集合为S1 = {Find(p)|p属于S0},S1包含了S0,令S1’= S1 – S0,
则S1’中的格子和图形A(x1,y1)可以通过转弯数目为1的路径连接。如果图形B在S1’中,可以用转弯数目为1的路径连接。
否则,对S1’中集合的空格子,找出可直线到达的格子集合,记为S2,S2′ = S2 – S0-S1,若B在S2’ZHong,可以用转弯数为 2的路径连接。
扩展的过程中,记下每个格子从哪个格子连过来的(转弯的位置),最后图形A和B之间的路径可以绘制出来。
S1′ = S1 – S0,S2′ = S2 – S0 – S1,可以通过记录从图形A(x1,y1)到该格子(x,y)的转弯数目实现。开始,将所有格子(x,y)和格子A(x1,y1)之间路径的最少转弯数目Min
Crossing(x,y)初始化为无穷大。令MinCrossing(A) = MinCrossing(x1,y1) = 0,格子A到自身当然不需要转弯。第一步扩展后,所有S0集合中的格子的MinCrossing的
值为0.在S0集合继续扩展得到S1的集合中,格子X和格子A之间至少有转弯为1的路径。如果格子X本身在S0中,那么MinCrossing(X) = 0,这时,保留转弯数目少的路径
MinCrossing(X) = MinValue(MinCrossing(X),1) = 0.
每一个格子X(x,y),都有一个状态值MinCrossing(X)。记录下该格子和起始格子A之间的最优路径的转弯数目。广度优先搜索,就是每次优先扩展状态值最少的格子。
如果要保证转弯数目最少的情况下,保持路径长度尽可能短,需要对每一个格子X保存两个状态值MinCrossing(X)和MinDistance(X)。从格子X扩展到格子Y的过程,
用下面代码实现
判断死锁:
判断两个格子是否可以消去,对游戏中尚未消去的格子,两两计算一下是否可以消去。每次都是扩展出起始格子A(x1,y1)能够到达的格子。对于每一个格子,可以调用
一次上面的扩展过程,得到所有可以到达的格子。如果这些格子中有任意一个格子的图形跟起始格子一致,则可以消去,不处于死锁状态
*/
#include <stdio.h>
typedef struct Pos
{
Pos(){}
Pos(int ix,int iy):_ix(ix),_iy(iy){}
int _iX;
int _iY;
}Pos;
typedef struct Pic
{
}Pic;
typedef struct Grid
{
Pos _pos;
Pic _pic;
int _minCrossing;
int _minDistance;
}Grid;
int Dist(int x,int y)
{
return 1;
}
void bfs()
{
Grid x,y;
if((x._minCrossing + 1 < y._minCrossing) || ((x._minCrossing + 1 == y._minCrossing ) && (x._minDistance(x) + Dist(x,y))))
//如果发现从格子X过来的路径改进了转弯数目或者路径的长度,则更新格子Y
{
y._minCrossing = x._minCrossing + 1;
y._minDistance = x._minDistance + Dist(x,y);
}
}
//如何求出相同图形之间的最短路径,最短路径的转弯数目最少,转弯数目最少时,经过格子数目尽可能少。
//最短路径中:把最短路径问题的目标函数改为从一个点到另一个店的转弯次数。广度优先搜索
bool findPath(const Grid& preClick,const Grid& curClick)
{
return true;
}
void run()
{
//生成游戏初始局面
Grid preClick = NULL,curClick = NULL;
bool isComplete = false;
while(!isComplete)
{
//监听用户动作
int x,y;
if()//用户点击格子(x,y),且格子(x,y)为非空格子
{
preClick = curClick;
curClick._pos(x,y);
}
if(preClick != NULL && curClick != NULL && preClick._pic = curClick._pic && findPath(preClick,curClick))
//如果前后两次点击均不为空,两次图片一致,能够找到路径,那么开始尝试消去
{
//显示两个格子之间的消去路径
//消去格子preClick和curClick
preClick = curClick = NULL;
}
}
}
void process()
{
run();
}
int main(int argc,char* argv[])
{
process();
getchar();
return 0;
}