回复 10楼 九转星河
我可没说做的出自动最小步数,而是指记录游戏者的游戏步数,没走冤枉路的话就是最少步数了。这个要做自动最少步数的ai我智商不够,做不了。
回复 11楼 xzlxzlxzl
原来是这样~不过还有一个问题~如果是随机生成获取最小步数是有随机性的吧~有可能两三步就可以还原哦~而且~还要先判断该棋盘到底是否能复原~
256-32求解~不是我挑剔一下~而是看到这么明显特么按耐不住~~
程序代码:#include "stdafx.h" //在vs、vc中可用,gcc编译器可注释掉
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
//#pragma comment(lib, "user32.lib") //为消息提示窗口加入user32库
void setLocate(int x,int y)
{//设置字符显示位置
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
COORD loc={x,y};
SetConsoleCursorPosition(hOut,loc);
}
void drawframe()
{//画外框
int i;
printf("┌─┬─┬─┬─┐ 空格键:产生随机地图 ESC键:退出 方向键:移动空格\n");
for(i=0;i<3;i++)
{
printf("│ │ │ │ │\n");
printf("├─┼─┼─┼─┤\n");
}
printf("│ │ │ │ │\n");
printf("└─┴─┴─┴─┘\n");
}
int testmove(int a[][4],int flg)
{//测试移动是否合法,合法则交换数据
int i,j,x,y,b[4][2]={-1,0,0,-1,0,1,1,0};
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(!a[i][j])
{
x=i;
y=j;
}
}
}
i=x+b[flg][0];
j=y+b[flg][1];
if(i<0||i>3||j<0||j>3)return 0;
a[i][j]^=a[x][y];
a[x][y]^=a[i][j];
a[i][j]^=a[x][y];
return 1;
}
int getkey()
{//获得键值
unsigned char a;
int n=0;
if(!kbhit())return 0;
a=getch();
if(a>127)
{
n=a*256;
a=getch();
}
n=n+a;
return n;
}
void rndmap(int a[][4])
{//随机地图产生
int i,j;
srand(clock());
for(i=0;i<4;i++)
for(j=0;j<4;j++)
a[i][j]=i*4+j+1;
a[3][3]=0;
for(i=0;i<128;i+=testmove(a,rand()%4)); //为减少代码,该语句有死循环的危险
setLocate(2,10);
printf(" ");
}
void listmap(int a[][4],int s)
{
int i,j,x,y;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
setLocate(j*4+2,i*2+1);
if(a[i][j])printf("%2d",a[i][j]);
else
{
x=j*4+2;
y=i*2+1;
printf(" ");
}
}
}
setLocate(21,3);
printf("步数:%d",s);
setLocate(x,y);
}
int testwin(int a[][4])
{//检测是否胜利
int i,*p;
p=&a[0][0];
for(i=0;i<15&&p[i]==i+1;i++);
return i==15;
}
void main()
{
int a[4][4],key,i,s=0;
drawframe();
rndmap(a);
listmap(a,s);
while((key=getkey())!=27)
{
if(key==32||(key>57415&&key<57425))
{
if(key==32)
{
rndmap(a);
s=0;
}
if(!testwin(a)&&key>57415&&key<57425)
{
i=(key-57416)/3+(key>57419);
s+=testmove(a,i);
//if(testwin(a))MessageBox(NULL,"你胜利了,请按空格键继续!","提示",MB_OK); //胜利消息提示,vs代码需要取消unicode字符集
if(testwin(a))
{//为增加代码通用性,还是使用传统提示输出,vs、vc的可用上行代码调用windows窗口消息做提示
setLocate(2,10);
printf("你胜利了,请按空格键继续!");
}
}
listmap(a,s);
}
}
}