编程之美:第一章 1.14连连看游戏设计

/*
连连看游戏设计:
主要包含游戏局面的状态描述,游戏规则的描述:状态的合法转移(哪些操作满足规则,经过这些操作,达到哪些状态)。自动机模型适合描述游戏设计。

如何求出相同图形之间的最短路径,最短路径的转弯数目最少,转弯数目最少时,经过格子数目尽可能少。
最短路径中:把最短路径问题的目标函数改为从一个点到另一个店的转弯次数。广度优先搜索

首先把图形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;
}

    原文作者:天地一扁舟
    原文地址: https://blog.csdn.net/qingyuanluofeng/article/details/39273255
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞