|
数字16拼图游戏完成版--带通关演示功能
花了点时间做了个完整版,在原代码基础上做了较大的改动,比如不再用二维数组来表示地图数据,取而代之的是一个64位无符号整数。改进了游戏界面,游戏功能得到完善,如增加重玩、通关演示功能,如果游戏者在玩的过程中过不了关,可以看通关演示,电脑将会在推荐的步数里完成游戏。希望本游戏能让各位在枯燥的码代码时带来一丝休闲!
效果图:
[mw_shl_code=c,true]#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
void setLocate(int x,int y)
{//设置字符显示位置
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
COORD loc={x,y};
SetConsoleCursorPosition(hOut,loc);
}
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 setprint(int x,int y,char *p)
{//将字符串输出到指定位置
setLocate(x,y);
printf("%s",p);
}
void drawframe(int x,int y)
{//画外框
int i;
setprint(x,y,"┌─┬─┬─┬─┐");
for(i=0;i<3;i++)
{
setprint(x,y+i*2+1,"│ │ │ │ │");
setprint(x,y+i*2+2,"├─┼─┼─┼─┤");
}
setprint(x,y+i*2+1,"│ │ │ │ │");
setprint(x,y+i*2+2,"└─┴─┴─┴─┘");
}
void drawmap(unsigned _int64 a,int x,int y)
{//画数字地图
int i,j,k;
for(i=16;i;i--,a/=16)
{
j=a%16;
setLocate(((i-1)%4)*4+2+x,((i-1)/4)*2+1+y);
if(j)printf("%2d",j);
else
{
printf(" ");
k=i-1;
}
}
setLocate((k%4)*4+2+x,(k/4)*2+1+y);
}
unsigned _int64 testmove(unsigned _int64 a,int f)
{//测试移动是否合法并返回移动后的地图数据
int i,j,x,y,c[16],b[4][2]={-1,0,0,-1,0,1,1,0};
for(i=16;i;a/=16,i--)
{
c[i-1]=(int)(a%16);
if(!c[i-1])j=i-1;
}
x=j/4+b[f][0];
y=j%4+b[f][1];
if(!(x<0||x>3||y<0||y>3))
{
c[j]=c[x*4+y];
c[x*4+y]=0;
}
for(i=0,a=0;i<16;i++)a=a*16+c;
return a;
}
unsigned _int64 rndmap(unsigned _int64 *p)
{//产生随机地图
unsigned _int64 a=1311768467463790320,b;
int i,j,k;
srand((unsigned)time(NULL));
for(i=0,b=a;i<128;i++)
{
while(b==a)b=testmove(a,rand()%4);
p=a;
a=b;
}
p=a;
p[i+1]=0;
for(i=0;i<200&&p;i++)
{
for(j=i-1;j>=0&&p!=p[j];j--);
if(j>=0)
{//消除重复步数
for(k=j;p;)p[k++]=p[i++];
i=j;
p[k]=0;
}
}
return a;
}
void playmenu(int x,int y)
{//显示游戏菜单
setprint(x,y+10," 游戏状态 ");
setprint(x-18,y+12,"方向键:控制 Esc: 退出 空格:新局 R:重玩 P:过关演示 ");
}
void demoplay(int x,int y,unsigned _int64 *p)
{//过关演示
int step,gostep,key=57421;
setprint(x,y+10," 过关演示状态 ");
setprint(x-18,y+12," 前进:→ 后退:← Esc: 退出 ");
for(step=gostep=0;p[step];step++);
while(key!=27)
{
if(key==57421&&gostep<step)gostep++;
if(key==57419&&gostep>1)gostep--;
if(key)
{
setprint(x,y+16," 已走步数:");
printf("%3d",gostep);
drawmap(p[step-gostep],x,y);
}
key=getkey();
}
}
void main()
{
unsigned _int64 a,b,s[200]; //**gcc编译器可使用unsigned long long取代unsigned _int64**
int fx=30,fy=2,key=32,step,gostep;
drawframe(fx,fy);
while(key!=27)
{
if(key==32)
{
playmenu(fx,fy);
a=rndmap(s);
for(step=0;s[step];step++);
gostep=0;
setprint(fx,fy+14," 推荐步数:");
printf("%3d",step);
}
if(key=='r'||key=='R')
{
a=s[step-1];
gostep=0;
playmenu(fx,fy);
}
if(key=='p'||key=='P')
{
demoplay(fx,fy,s);
playmenu(fx,fy);
}
if(a==s[0]&&key)key=0;
if(key>57415&&key<57425)
{
b=a;
a=testmove(a,(key-57416)/3+(key>57419));
if(a!=b)gostep++;
if(a==s[0])setprint(fx,fy+10,"恭喜过关,空格键继续... ");
}
if(key)
{
setprint(fx,fy+16," 已走步数:");
printf("%3d",gostep);
drawmap(a,fx,fy);
}
key=getkey();
}
}[/mw_shl_code] |
|