#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#include<windows.h>
int i, j, r, k; //i、j、r用于循环, k存放随机数值
int m, n; // m、n是当前空位的下标
int a[4][4]; //存储4×4共16个数字的数组
void show(void); //输出界面
void csh(void); //初始化界面
int yes(void); //判断排序是否成功(1是0否)
void up(void); //数字向上移动到空位(空位则下移)
void down(void); //数字向下移
void left(void); //数字向左移
void rght(void); //数字向右移
void inkey(void); //按键操作
void gtxy(int x, int y) ; //控制光标位置的函数
int main(void)
{ while(1)
{ csh( );
while(1)
{ inkey();
show();
if ( yes( ) )
{ gtxy(6,12); printf("你成功了! 再来一局y/n?"); break; }
}
if(getch( )=='n')break;
}
return 0;
}
void csh(void) //初始化
{ r=0;
CONSOLE_CURSOR_INFO cursor_info={1,0}; //以下两行是隐藏光标的设置
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
for(i=0;i<4;i++) //给数组a依序赋值
for(j=0;j<4;j++)
{ if (i==3 && j==3) a[i][j]=0;
else a[i][j]=1+r++;
}
m=3; n=3; //记下空格(值为0)的下标
down( ); rght( ); rght( ); down( ); //预演4步
srand((unsigned)time(0)); //初始化随机数发生器
for(r=0;r<500;r++) //将数组各值打乱
{ k=rand( )%(4);
switch(k)
{ case 0: { up( ); break; }
case 1: {down( ); break; }
case 2: { left( ); break; }
case 3: { rght( ); break; }
}
}
system(“cls”);
printf("\n\n\t\t 数字拼图");
printf("\n\t┌──────┬──────┬──────┬──────┐");
printf("\n\t│ │ │ │ │");
printf("\n\t├──────┼──────┼──────┼──────┤");
printf("\n\t│ │ │ │ │");
printf("\n\t├──────┼──────┼──────┼──────┤");
printf("\n\t│ │ │ │ │");
printf("\n\t├──────┼──────┼──────┼──────┤");
printf("\n\t│ │ │ │ │");
printf("\n\t└──────┴──────┴──────┴──────┘");
show( );
}
void show(void) //输出界面
{ for(i=0;i<4;i++)
for(j=0;j<4;j++) //gtxy(7*j+9, 2*i+4)是光标到指定位置输出数字
{ gtxy(7*j+9,2*i+4); if(a[i][j]==0)printf(" │");
else if(a[i][j]>9)printf(" %d │",a[i][j]);
else printf(" %d │",a[i][j]);
}
}
void inkey(void) //按键操作
{ int key;
key=getch( );
switch(key)
{ case 72: { up( ); break; }
case 80: {down( ); break; }
case 75: {left( ); break; }
case 77: { rght( ); break; }
}
}
void up(void) //向上移动
{ if (m!=3) //空位不得在下边界
{ a[m][n]=a[m+1][n]; m++; a[m][n]=0; }
}
void down(void) //向下移动
{ if (m!=0) //空位不得在上边界
{ a[m][n]=a[m-1][n]; m--; a[m][n]=0; }
}
void left(void) //向左移动
{ if (n!=3) //空位不得在右边界
{ a[m][n]=a[m][n+1]; n++; a[m][n]=0; }
}
void rght(void) //向右移动
{ if (n!=0) //空位不得在左边界
{ a[m][n]=a[m][n-1]; n--; a[m][n]=0; }
}
int yes(void) //判断是否成功
{ r=0;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{ if (a[i][j]!=1+r++) return (r==16)?1:0; }
}
void gtxy(int x, int y) //控制光标位置的函数
{ COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}