初学者50求拼图游戏算法

loverP 2003-10-09 09:49:03
拼图游戏大家都玩过吧?就是给一个图,被分割成4*4的矩阵,拿掉一块,剩下的随机打乱顺序,然后利用那个空位,通过一次移动一块图形使图形恢复原貌。
现在请教用计算机来完成这个游戏的算法,要求步数最少。
...全文
351 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
loverP 2003-11-01
  • 打赏
  • 举报
回复
多谢了,我好好研究研究 。
huan_jinwu 2003-10-30
  • 打赏
  • 举报
回复
相信大家都玩过"滑块拼图"游戏!
大概说一下 :假如一副图是由几个部分拼凑成的,现在要你把这些散块拼凑成一副完整的图片
也可以是几个数字来拼凑
比如 3*3的格子
1 2 3
4 5 6
7 8 (相当于原始矩阵)
有一个格子是空的现在要你组合成
1 2 7
3 6 4
5 8 (目标矩阵)
问题是编写一种算法 能根据输入的原始图形(矩阵)拼凑成目标图形(目标矩阵) 要求是步数最少(耗时间最少)
#include"iostream.h"
struct node{
int nodesun[4][4];

int x,y;
}path[1000];
int zx[4]={-1,0,1,0};
int zy[4]={0,-1,0,1};
int top;
int desti[4][4];//目标状态
int detect(struct node *p)
{int i,j;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
if(p->nodesun[i][j]!=desti[i][j])
return 0;
return 1;
}

void printlj()
{int tempt;
int i,j;
tempt=1;
while(tempt<=top)
{ for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<path[tempt].nodesun[i][j];
if(j==3)
cout<<" "<<endl;
}
tempt++;
}
}




void main()
{ //初始化
int i,j,m,n,f;
int temp,find=0;
top=1;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
cin>>temp;
path[1].nodesun[i][j]=temp;
}
cout<<"请输入初始状态的空格的位置(行)"<<endl;
cin>>temp;
path[1].x=temp;
cout<<"请输入初始状态的空格的位置(列)"<<endl;
cin>>temp;
path[1].y=temp;
//目标状态
for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
cin>>temp;
desti[i][j]=temp;
}
//深度优先搜索
while(!find)
{ m=path[top].x;
n=path[top].y ;
for(f=0;f<4;f++)
{i=m+zx[f];
j=n+zy[f];
if(i>=1&&i<=3&&j>=1&&j<=3)
{top++;
path[top]=path[top-1];
path[top].nodesun[m][n]=path[top-1].nodesun[i][j];
path[top].nodesun[i][j]=0;

path[top].x=i;
path[top].y=j;

if(detect(&path[top]))
{printlj();
find=1;
break;
}

break;
}//if

}//for

}//while
}



#include"iostream.h"
struct node{
int nodesun[4][4];
int pre;
int x,y;
}path[400];
int zx[4]={-1,0,1,0};
int zy[4]={0,-1,0,1};
int front,rear;
int desti[4][4];//目标状态
int detect(struct node *p)
{int i,j;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
if(p->nodesun[i][j]!=desti[i][j])
return 0;
return 1;
}

void printlj()
{int tempt;
int i,j;
tempt=rear;
while(tempt!=0)
{ for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<path[tempt].nodesun[i][j];
if(j==3)
cout<<" "<<endl;
}
tempt=path[tempt].pre;
}
}




void main()
{ //初始化
int i,j,m,n,f;
int temp,find=0;
front=rear=1;
path[1].pre=0;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
cin>>temp;
path[1].nodesun[i][j]=temp;
}
cout<<"请输入初始状态的空格的位置(行)"<<endl;
cin>>temp;
path[1].x=temp;
cout<<"请输入初始状态的空格的位置(列)"<<endl;
cin>>temp;
path[1].y=temp;
//目标状态
for(i=1;i<4;i++)
for(j=1;j<4;j++)
{cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<<endl;
cin>>temp;
desti[i][j]=temp;
}
//广度优先搜索
while(front<=rear&&!find)
{ m=path[front].x;
n=path[front].y ;
for(f=0;f<4;f++)
{i=m+zx[f];
j=n+zy[f];
if(i>=1&&i<=3&&j>=1&&j<=3)
{rear++;
path[rear]=path[front];
path[rear].nodesun[m][n]=path[front].nodesun[i][j];
path[rear].nodesun[i][j]=0;
path[rear].pre=front;
path[rear].x=i;
path[rear].y=j;
if(detect(&path[rear]))
{printlj();
find=1;
break;
}
}
}
front++;
}
}

上面是用最简单的深度优先,广度优先直接搜索得来得,毫无AI可言,这并不说明我不能写出其更好得算法,这里最简单得的估价函数f(x)=g(x)+h(x)
g(x)用初始化的节点到当前的节点的路径长度来表示h(x)启发函数用当前状态和目标状态的位置不同的个数来表
nxct 2003-10-28
  • 打赏
  • 举报
回复
jxgz
loverP 2003-10-28
  • 打赏
  • 举报
回复
搜索算法似乎用广度优先遍历就好了,可关键是怎么生成一个图,确切地说怎么判断图已经生成好了。
postform999 2003-10-27
  • 打赏
  • 举报
回复
穷举就不要考虑了,不然算法有什么用。
找一本书:算法与数据结构(pascal版的),但是它的思想很不错,好像有这个,还有著名的旅行售货员问题
nxct 2003-10-27
  • 打赏
  • 举报
回复
用穷举可不可以?
loverP 2003-10-27
  • 打赏
  • 举报
回复
那么,怎么能正确地生成所有状态所构成的图呢?
GREFT 2003-10-26
  • 打赏
  • 举报
回复
就是用广(深)度搜索。
我以前学过的
loverP 2003-10-25
  • 打赏
  • 举报
回复
sunshine007(阳光) :能具体点么?或者介绍本书看,我看了好多书了,可都没有满意答案
sunshine007 2003-10-25
  • 打赏
  • 举报
回复
用搜索树解决.
1.广(深)度搜索:列出每一步的n种可能用,后(中)序遍历,递归不断查找.找到为止.
2.最优搜索.列出节点离终点的步数,加权节点已走步数.找最优路径
loverP 2003-10-23
  • 打赏
  • 举报
回复
postform999(真水无香) :我考虑过图的最短通路。不过还没实现。有没有具体点的办法?
oystered 2003-10-22
  • 打赏
  • 举报
回复
呵呵,找找呀,我在网上见过,到google上找吧
postform999 2003-10-22
  • 打赏
  • 举报
回复
看一看数据结构里的限界-剪枝算法,就是一个求最优生成数的算法,有难度的,我们的课有写过关于这个的论文(15魔方问题),可惜我找不到了 :(
ruanyuping 2003-10-22
  • 打赏
  • 举报
回复
up
huan_jinwu 2003-10-14
  • 打赏
  • 举报
回复
up~

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧