最近看哈佛公開課cs50,裏面有fifteen的例子,然後就搜了下相關的,簡單的就是8數碼。
這是一位不知道名字大俠寫的程序,太厲害了,看半天,我添加了些註釋,方便看懂。
下圖所示,最初狀態是隨機生成的,通過上下左右鍵移動,輸入q或Q退出。
這程序不涉及算法的問題,只是手動自己排序。
程序:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<conio.h>
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
void DrawArray(int array[])//畫圖形
{
int i,j;
for(i=0;i<3;i++)
{
printf("\n\n\t\t\t");//普通格式
for(j=0;j<3;j++)
if(array[i*3+j]==0) printf(" \t\t",array[i*3+j]);//空的那一位原先是0,現在用\t\t替代
else printf("%d\t\t",array[i*3+j]);//輸出3行3列數
}
}
void Move(char c,int array[])//移動
{
int i,j;
for(i=0;i<9;i++)if(array[i]==0)break;//判斷0所在的位置
switch(c)//圍繞0來做上下左右移動,自己畫出來仔細看看就能明白。
{
case UP:j=((i+3>8)?-1:i+3);break;
case DOWN:j=((i-3<0)?-1:i-3);break;
case LEFT:j=((i==2||i==5||i==8)?-1:i+1);break;
case RIGHT:j=((i==0||i==3||i==6)?-1:i-1);break;
default:j=-1;
}
if(j!=-1){array[i]=array[j];array[j]=0;}//交換0與移動的數字
}
void Init(int array[])//最開始的隨機圖形
{
int i,j,sum=0;
srand(time(0));
do
{
sum=0;
for(i=0;i<8;i++)
{
array[i]=rand()%8+1;//產生1-8的隨機數
}
for(i=0;i<8;i++)
{
for(j=0;j<i;j++)
if(array[j]==array[i])
{
array[i]=array[i]+1;
if(array[i]==9)array[i]=1;
j=-1;//如果出現重複就重新再比較一次,如果沒有這個,還是可能重複
}//隨機數可能重複,以上程序讓隨機數爲不重複的12.....8個數字
}
for(i=0;i<8;i++)
for(j=i+1;j<8;j++)
if(array[i]>array[j])sum++;
}while(sum%2!=0);//防止無解,偶排列只能變換成偶排列,奇排列也同理。在本題中最終變換的是7+6+...+1=28是偶排列,所以初始值也要是偶排列。具體就自己google吧,技術文檔百度就算了!
for(i=8;i>=5;i--)array[i]=array[i-1];
array[4]=0;//將0插到中間
}
int Win(int array[])
{
int i;
for(i=0;i<4;i++)if(array[i]!=i+1)return 0;//0不成功
for(i=5;i<9;i++)if(array[i]!=i)return 0;
return 1;//1成功
}
main()
{
char c;
int array[9],init[9];
Init(array);
for(c=0;c<9;c++) init[c]=array[c];
do
{
system("cls");//如果是TC請替換成clrscr();如果是linux shell,還可以用printf("\033[2J");printf("\033[%d;%dH", 0, 0);清屏
printf("請用上下左右四個鍵將下面的數字排成這個樣子:\n");
printf("1 2 3 \n4 5\n6 7 8");
printf("\n最初狀態是:\n");
printf("%d %d %d\n%d %d\n%d %d %d",init[0],init[1],init[2],init[3],init[5],init[6],init[7],init[8]);
printf("\n祝你好運!\n");
DrawArray(array);
if(Win(array))
{
printf("\n\n\t\t你贏了!好棒!!\t");
c='q';
break;
}
c=getch();
if(c<0)continue;
Move(c,array);
}while(c!='q'&&c!='Q');//輸入q鍵退出
getch();
}