10 changed files with 3658 additions and 0 deletions
			
			
		| @ -0,0 +1,319 @@ | |||||
|  | #include<iostream> | ||||
|  | #include<vector> | ||||
|  | #include<list> | ||||
|  | #include<fstream> | ||||
|  | using namespace std; | ||||
|  | ofstream File_Output; | ||||
|  | vector<unsigned int> Data_All; | ||||
|  | unsigned char Data_Num[21],Data_Blocks[12],Data_Direction[6]; | ||||
|  | unsigned char Space_Num[9],Space_Style[9]; | ||||
|  | unsigned int u,Address,Result; | ||||
|  | bool Found; | ||||
|  | void Add(unsigned int Data); | ||||
|  | void Output_Data(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x0){File_Output<<"0";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x1){File_Output<<"1";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x2){File_Output<<"2";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x3){File_Output<<"3";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x4){File_Output<<"4";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x5){File_Output<<"5";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x6){File_Output<<"6";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x7){File_Output<<"7";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x8){File_Output<<"8";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x9){File_Output<<"9";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xA){File_Output<<"A";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xB){File_Output<<"B";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xC){File_Output<<"C";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xD){File_Output<<"D";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xE){File_Output<<"E";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xF){File_Output<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Data_cout(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x0){cout<<"0";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x1){cout<<"1";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x2){cout<<"2";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x3){cout<<"3";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x4){cout<<"4";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x5){cout<<"5";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x6){cout<<"6";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x7){cout<<"7";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x8){cout<<"8";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0x9){cout<<"9";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xA){cout<<"A";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xB){cout<<"B";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xC){cout<<"C";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xD){cout<<"D";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xE){cout<<"E";} | ||||
|  |         if((0xF&Data>>(7-i)*4)==0xF){cout<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | unsigned char Get_Style(unsigned char Num){ | ||||
|  |     if(Num==0){return 0;} | ||||
|  |     if(Num>=1&&Num<=5){ | ||||
|  |         if(Data_Direction[Num]==0){return 1;}else{return 2;} | ||||
|  |     } | ||||
|  |     if(Num>=6&&Num<=9){return 3;} | ||||
|  |     return 4; | ||||
|  | } | ||||
|  | void Search_Space(){ | ||||
|  |     unsigned char Num,i=0; | ||||
|  |     Space_Again:; | ||||
|  |     if(Data_Blocks[i+10]>4){ | ||||
|  |         Num=Data_Num[Data_Blocks[i+10]-4]; | ||||
|  |         Space_Num[i*4+1]=Num; | ||||
|  |         Space_Style[i*4+1]=Get_Style(Num); | ||||
|  |     } | ||||
|  |     else{ | ||||
|  |         Space_Num[i*4+1]=0; | ||||
|  |         Space_Style[i*4+1]=4; | ||||
|  |     } | ||||
|  |     if(Data_Blocks[i+10]<17){ | ||||
|  |         Num=Data_Num[Data_Blocks[i+10]+4]; | ||||
|  |         Space_Num[i*4+2]=Num; | ||||
|  |         Space_Style[i*4+2]=Get_Style(Num); | ||||
|  |     } | ||||
|  |     else{ | ||||
|  |         Space_Num[i*4+2]=0; | ||||
|  |         Space_Style[i*4+2]=4; | ||||
|  |     } | ||||
|  |     if((Data_Blocks[i+10]%4)!=1){ | ||||
|  |         Num=Data_Num[Data_Blocks[i+10]-1]; | ||||
|  |         Space_Num[i*4+3]=Num; | ||||
|  |         Space_Style[i*4+3]=Get_Style(Num); | ||||
|  |     } | ||||
|  |     else{ | ||||
|  |         Space_Num[i*4+3]=0; | ||||
|  |         Space_Style[i*4+3]=4; | ||||
|  |     } | ||||
|  |     if((Data_Blocks[i+10]%4)!=0){ | ||||
|  |         Num=Data_Num[Data_Blocks[i+10]+1]; | ||||
|  |         Space_Num[i*4+4]=Num; | ||||
|  |         Space_Style[i*4+4]=Get_Style(Num); | ||||
|  |     } | ||||
|  |     else{ | ||||
|  |         Space_Num[i*4+4]=0; | ||||
|  |         Space_Style[i*4+4]=4; | ||||
|  |     } | ||||
|  |     if(i==0){i++;goto Space_Again;} | ||||
|  | } | ||||
|  | void Analyse(unsigned int Data){ | ||||
|  |     unsigned char Num,Style,i,c,b=1,j=1,k=1; | ||||
|  |     for(i=1;i<=20;i++){ | ||||
|  |         Data_Num[i]=12; | ||||
|  |     } | ||||
|  |     c=Data&0xF; | ||||
|  |     i=1; | ||||
|  |     for(Num=1;Num<=20;Num++){ | ||||
|  |         if(Data_Num[Num]==12){ | ||||
|  |             if(c==i){ | ||||
|  |                 Data_Num[Num]=0; | ||||
|  |                 Data_Num[Num+1]=0; | ||||
|  |                 Data_Num[Num+4]=0; | ||||
|  |                 Data_Num[Num+5]=0; | ||||
|  |                 Data_Blocks[0]=Num; | ||||
|  |                 c=0; | ||||
|  |                 goto Again; | ||||
|  |             } | ||||
|  |             Style=(Data>>(32-i*2))&3; | ||||
|  |             i++; | ||||
|  |             if(Style==0){ | ||||
|  |                 Data_Num[Num]=10; | ||||
|  |                 Data_Blocks[k+9]=Num; | ||||
|  |                 k++; | ||||
|  |             } | ||||
|  |             if(Style==1){ | ||||
|  |                 Data_Num[Num]=j; | ||||
|  |                 Data_Num[Num+1]=j; | ||||
|  |                 Data_Direction[j]=0; | ||||
|  |                 Data_Blocks[j]=Num; | ||||
|  |                 j++; | ||||
|  |             } | ||||
|  |             if(Style==2){ | ||||
|  |                 Data_Num[Num]=j; | ||||
|  |                 Data_Num[Num+4]=j; | ||||
|  |                 Data_Direction[j]=1; | ||||
|  |                 Data_Blocks[j]=Num; | ||||
|  |                 j++; | ||||
|  |             } | ||||
|  |             if(Style==3){ | ||||
|  |                 Data_Num[Num]=b+5; | ||||
|  |                 Data_Blocks[b+5]=Num; | ||||
|  |                 b++; | ||||
|  |             } | ||||
|  |             Again:; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     Search_Space(); | ||||
|  | } | ||||
|  | unsigned char Direction_Back(unsigned char Way){ | ||||
|  |     if(Way==1){return 2;} | ||||
|  |     if(Way==2){return 1;} | ||||
|  |     if(Way==3){return 4;} | ||||
|  |     if(Way==4){return 3;} | ||||
|  | } | ||||
|  | void Move_Block(unsigned char Num,unsigned char Direction){ | ||||
|  |     if(Num==0){ | ||||
|  |         Data_Num[Data_Blocks[Num]]=10; | ||||
|  |         Data_Num[Data_Blocks[Num]+1]=10; | ||||
|  |         Data_Num[Data_Blocks[Num]+4]=10; | ||||
|  |         Data_Num[Data_Blocks[Num]+5]=10; | ||||
|  |     } | ||||
|  |     if(Num>=1&&Num<=5){ | ||||
|  |         if(Data_Direction[Num]==0){ | ||||
|  |             Data_Num[Data_Blocks[Num]]=10; | ||||
|  |             Data_Num[Data_Blocks[Num]+1]=10; | ||||
|  |         } | ||||
|  |         else{ | ||||
|  |             Data_Num[Data_Blocks[Num]]=10; | ||||
|  |             Data_Num[Data_Blocks[Num]+4]=10; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if(Num>=6&&Num<=9){ | ||||
|  |         Data_Num[Data_Blocks[Num]]=10; | ||||
|  |     } | ||||
|  |     if(Direction==1)(Data_Blocks[Num]=Data_Blocks[Num]-4); | ||||
|  |     if(Direction==2)(Data_Blocks[Num]=Data_Blocks[Num]+4); | ||||
|  |     if(Direction==3)(Data_Blocks[Num]=Data_Blocks[Num]-1); | ||||
|  |     if(Direction==4)(Data_Blocks[Num]=Data_Blocks[Num]+1); | ||||
|  |     if(Num==0){ | ||||
|  |         Data_Num[Data_Blocks[Num]]=0; | ||||
|  |         Data_Num[Data_Blocks[Num]+1]=0; | ||||
|  |         Data_Num[Data_Blocks[Num]+4]=0; | ||||
|  |         Data_Num[Data_Blocks[Num]+5]=0; | ||||
|  |     } | ||||
|  |     if(Num>=1&&Num<=5){ | ||||
|  |         if(Data_Direction[Num]==0){ | ||||
|  |             Data_Num[Data_Blocks[Num]]=Num; | ||||
|  |             Data_Num[Data_Blocks[Num]+1]=Num; | ||||
|  |         } | ||||
|  |         else{ | ||||
|  |             Data_Num[Data_Blocks[Num]]=Num; | ||||
|  |             Data_Num[Data_Blocks[Num]+4]=Num; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if(Num>=6&&Num<=9){ | ||||
|  |         Data_Num[Data_Blocks[Num]]=Num; | ||||
|  |     } | ||||
|  | } | ||||
|  | void Create(unsigned char Num,unsigned char Direction_1,unsigned char Direction_2){ | ||||
|  |     unsigned char i,j,n; | ||||
|  |     unsigned int Data_Output,Space_Address[2]; | ||||
|  |     Move_Block(Num,Direction_1); | ||||
|  |     Move_Block(Num,Direction_2); | ||||
|  |     n=0; | ||||
|  |     for(i=1;i<=20;i++){ | ||||
|  |         if(Data_Num[i]==10){Space_Address[n]=i;n++;} | ||||
|  |     } | ||||
|  |     j=0; | ||||
|  |     Data_Output=0; | ||||
|  |     for(n=1;n<=20;n++){ | ||||
|  |         for(i=1;i<10;i++){ | ||||
|  |             if(Data_Blocks[i]==n){ | ||||
|  |                 if(i<=5){Data_Output=Data_Output|((Data_Direction[i]+1)<<(30-j*2));} | ||||
|  |                 if(i>=6){Data_Output=Data_Output|(3<<(30-j*2));} | ||||
|  |                 j++; | ||||
|  |             } | ||||
|  |         } | ||||
|  |         if(Space_Address[0]==n){Data_Output=Data_Output|(0<<(30-j*2));j++;} | ||||
|  |         if(Space_Address[1]==n){Data_Output=Data_Output|(0<<(30-j*2));j++;} | ||||
|  |         if(Data_Blocks[0]==n){Data_Output=Data_Output|(j+1);} | ||||
|  |     } | ||||
|  |     Add(Data_Output); | ||||
|  |     if(Data_Blocks[0]==14){ | ||||
|  |         Result=Data_Output; | ||||
|  |         Found=true; | ||||
|  |     } | ||||
|  |     Move_Block(Num,Direction_Back(Direction_2)); | ||||
|  |     Move_Block(Num,Direction_Back(Direction_1)); | ||||
|  | } | ||||
|  | void Search_Way(unsigned int Data){ | ||||
|  |     Analyse(Data); | ||||
|  |     if((Data_Blocks[11]-Data_Blocks[10])==1){ | ||||
|  |         if((Space_Style[1]==0)&&(Space_Style[5]==0)){Create(Space_Num[1],2,0);} | ||||
|  |         if((Space_Style[1]==1)&&(Space_Style[5]==1)){Create(Space_Num[1],2,0);} | ||||
|  |         if(Space_Style[1]==2){Create(Space_Num[1],2,0);} | ||||
|  |         if(Space_Style[5]==2){Create(Space_Num[5],2,0);} | ||||
|  |         if(Space_Style[1]==3){Create(Space_Num[1],2,0);Create(Space_Num[1],2,4);} | ||||
|  |         if(Space_Style[5]==3){Create(Space_Num[5],2,0);Create(Space_Num[5],2,3);} | ||||
|  |         if((Space_Style[2]==0)&&(Space_Style[6]==0)){Create(Space_Num[2],1,0);} | ||||
|  |         if((Space_Style[2]==1)&&(Space_Style[6]==1)){Create(Space_Num[2],1,0);} | ||||
|  |         if(Space_Style[2]==2){Create(Space_Num[2],1,0);} | ||||
|  |         if(Space_Style[6]==2){Create(Space_Num[6],1,0);} | ||||
|  |         if(Space_Style[2]==3){Create(Space_Num[2],1,0);Create(Space_Num[2],1,4);} | ||||
|  |         if(Space_Style[6]==3){Create(Space_Num[6],1,0);Create(Space_Num[6],1,3);} | ||||
|  |         if(Space_Style[3]==1){Create(Space_Num[3],4,0);Create(Space_Num[3],4,4);} | ||||
|  |         if(Space_Style[3]==3){Create(Space_Num[3],4,0);Create(Space_Num[3],4,4);} | ||||
|  |         if(Space_Style[8]==1){Create(Space_Num[8],3,0);Create(Space_Num[8],3,3);} | ||||
|  |         if(Space_Style[8]==3){Create(Space_Num[8],3,0);Create(Space_Num[8],3,3);} | ||||
|  |     } | ||||
|  |     else if((Data_Blocks[11]-Data_Blocks[10])==4){ | ||||
|  |         if(Space_Style[1]==2){Create(Space_Num[1],2,0);Create(Space_Num[1],2,2);} | ||||
|  |         if(Space_Style[1]==3){Create(Space_Num[1],2,0);Create(Space_Num[1],2,2);} | ||||
|  |         if(Space_Style[6]==2){Create(Space_Num[6],1,0);Create(Space_Num[6],1,1);} | ||||
|  |         if(Space_Style[6]==3){Create(Space_Num[6],1,0);Create(Space_Num[6],1,1);} | ||||
|  |         if((Space_Style[3]==0)&&(Space_Style[7]==0)){Create(Space_Num[3],4,0);} | ||||
|  |         if((Space_Style[3]==2)&&(Space_Style[7]==2)){Create(Space_Num[3],4,0);} | ||||
|  |         if(Space_Style[3]==1){Create(Space_Num[3],4,0);} | ||||
|  |         if(Space_Style[7]==1){Create(Space_Num[7],4,0);} | ||||
|  |         if(Space_Style[3]==3){Create(Space_Num[3],4,0);Create(Space_Num[3],4,2);} | ||||
|  |         if(Space_Style[7]==3){Create(Space_Num[7],4,0);Create(Space_Num[7],4,1);} | ||||
|  |         if((Space_Style[4]==0)&&(Space_Style[8]==0)){Create(Space_Num[4],3,0);} | ||||
|  |         if((Space_Style[4]==2)&&(Space_Style[8]==2)){Create(Space_Num[4],3,0);} | ||||
|  |         if(Space_Style[4]==1){Create(Space_Num[4],3,0);} | ||||
|  |         if(Space_Style[8]==1){Create(Space_Num[8],3,0);} | ||||
|  |         if(Space_Style[4]==3){Create(Space_Num[4],3,0);Create(Space_Num[4],3,2);} | ||||
|  |         if(Space_Style[8]==3){Create(Space_Num[8],3,0);Create(Space_Num[8],3,1);} | ||||
|  |     } | ||||
|  |     else{ | ||||
|  |         if(Space_Style[1]==2){Create(Space_Num[1],2,0);} | ||||
|  |         if(Space_Style[1]==3){Create(Space_Num[1],2,0);} | ||||
|  |         if(Space_Style[2]==2){Create(Space_Num[2],1,0);} | ||||
|  |         if(Space_Style[2]==3){Create(Space_Num[2],1,0);} | ||||
|  |         if(Space_Style[3]==1){Create(Space_Num[3],4,0);} | ||||
|  |         if(Space_Style[3]==3){Create(Space_Num[3],4,0);} | ||||
|  |         if(Space_Style[4]==1){Create(Space_Num[4],3,0);} | ||||
|  |         if(Space_Style[4]==3){Create(Space_Num[4],3,0);} | ||||
|  |         if(Space_Style[5]==2){Create(Space_Num[5],2,0);} | ||||
|  |         if(Space_Style[5]==3){Create(Space_Num[5],2,0);} | ||||
|  |         if(Space_Style[6]==2){Create(Space_Num[6],1,0);} | ||||
|  |         if(Space_Style[6]==3){Create(Space_Num[6],1,0);} | ||||
|  |         if(Space_Style[7]==1){Create(Space_Num[7],4,0);} | ||||
|  |         if(Space_Style[7]==3){Create(Space_Num[7],4,0);} | ||||
|  |         if(Space_Style[8]==1){Create(Space_Num[8],3,0);} | ||||
|  |         if(Space_Style[8]==3){Create(Space_Num[8],3,0);} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Add(unsigned int Data){ | ||||
|  |     for(u=0;u<Data_All.size();u++){ | ||||
|  |         if(Data_All[u]==Data){goto out;} | ||||
|  |     } | ||||
|  |     Data_All.push_back(Data); | ||||
|  |     out:; | ||||
|  | } | ||||
|  | void Calculate(unsigned int Data){ | ||||
|  |     unsigned int i; | ||||
|  |     Data_All.push_back(Data); | ||||
|  |     File_Output.open("Data.txt"); | ||||
|  |     Address=0; | ||||
|  |     Found=false; | ||||
|  |     while(1){ | ||||
|  |         Search_Way(Data_All[Address]); | ||||
|  |         Address++; | ||||
|  |         if(Found==true){break;} | ||||
|  |     } | ||||
|  |     for(i=0;i<Data_All.size();i++){ | ||||
|  |         Output_Data(Data_All[i]); | ||||
|  |         File_Output<<endl; | ||||
|  |     } | ||||
|  |     File_Output.close(); | ||||
|  | } | ||||
|  | int main(){ | ||||
|  |     unsigned int Start_Data=0xA9BF0C02; | ||||
|  |     Calculate(Start_Data); | ||||
|  |     return 0; | ||||
|  | } | ||||
| @ -0,0 +1,551 @@ | |||||
|  | #include<iostream> | ||||
|  | #include<fstream> | ||||
|  | #include<string> | ||||
|  | #include<vector> | ||||
|  | #include<list> | ||||
|  | using namespace std; | ||||
|  | const unsigned char Output_Width=8; | ||||
|  | const string Square_str="\u2588\u2588"; | ||||
|  | struct Block_Data{ | ||||
|  |     unsigned char Address; | ||||
|  |     unsigned char Style; | ||||
|  | }; | ||||
|  | ofstream log_Output; | ||||
|  | ofstream File_Output; | ||||
|  | ifstream File_Input; | ||||
|  | vector<unsigned int> Data_All; | ||||
|  | vector<unsigned int> Source; | ||||
|  | vector<unsigned int> Styles; | ||||
|  | vector<unsigned int> Solve_Data; | ||||
|  | vector<int> Steps; | ||||
|  | list<unsigned int> Hash[0xFFFF]; | ||||
|  | string File_Name; | ||||
|  | string InputFileName; | ||||
|  | struct Block_Data Block[12]; | ||||
|  | unsigned char Table[21]; | ||||
|  | unsigned char Space_1,Space_2,Space_num_1,Space_num_2,Last_Move; | ||||
|  | unsigned int Search_num,Solve_num; | ||||
|  | bool Done,End=false; | ||||
|  | void Solve(unsigned int Data); | ||||
|  | void Find_Next(); | ||||
|  | void Move_Block(unsigned char num,unsigned char Direction_1,unsigned char Direction_2); | ||||
|  | void Add_List(unsigned int Data); | ||||
|  | void Output_str(unsigned int Data); | ||||
|  | unsigned int Input(); | ||||
|  | bool Check_Error(unsigned int Start_Data); | ||||
|  | void Calculate(unsigned int Start_Data); | ||||
|  | void Output(); | ||||
|  | unsigned int InputData(char Data[8]){ | ||||
|  |     unsigned char i; | ||||
|  |     unsigned int Dat; | ||||
|  |     Dat=0; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if(Data[i]=='0'){Dat=Dat|(0x0<<(28-i*4));} | ||||
|  |         if(Data[i]=='1'){Dat=Dat|(0x1<<(28-i*4));} | ||||
|  |         if(Data[i]=='2'){Dat=Dat|(0x2<<(28-i*4));} | ||||
|  |         if(Data[i]=='3'){Dat=Dat|(0x3<<(28-i*4));} | ||||
|  |         if(Data[i]=='4'){Dat=Dat|(0x4<<(28-i*4));} | ||||
|  |         if(Data[i]=='5'){Dat=Dat|(0x5<<(28-i*4));} | ||||
|  |         if(Data[i]=='6'){Dat=Dat|(0x6<<(28-i*4));} | ||||
|  |         if(Data[i]=='7'){Dat=Dat|(0x7<<(28-i*4));} | ||||
|  |         if(Data[i]=='8'){Dat=Dat|(0x8<<(28-i*4));} | ||||
|  |         if(Data[i]=='9'){Dat=Dat|(0x9<<(28-i*4));} | ||||
|  |         if(Data[i]=='A'||Data[i]=='a'){Dat=Dat|(0xA<<(28-i*4));} | ||||
|  |         if(Data[i]=='B'||Data[i]=='b'){Dat=Dat|(0xB<<(28-i*4));} | ||||
|  |         if(Data[i]=='C'||Data[i]=='c'){Dat=Dat|(0xC<<(28-i*4));} | ||||
|  |         if(Data[i]=='D'||Data[i]=='d'){Dat=Dat|(0xD<<(28-i*4));} | ||||
|  |         if(Data[i]=='E'||Data[i]=='e'){Dat=Dat|(0xE<<(28-i*4));} | ||||
|  |         if(Data[i]=='F'||Data[i]=='f'){Dat=Dat|(0xF<<(28-i*4));} | ||||
|  |     } | ||||
|  |     return Dat; | ||||
|  | } | ||||
|  | void OutputData(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){File_Output<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){File_Output<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){File_Output<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){File_Output<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){File_Output<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){File_Output<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){File_Output<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){File_Output<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){File_Output<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){File_Output<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){File_Output<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){File_Output<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){File_Output<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){File_Output<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){File_Output<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){File_Output<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | void log_OutputData(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){log_Output<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){log_Output<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){log_Output<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){log_Output<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){log_Output<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){log_Output<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){log_Output<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){log_Output<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){log_Output<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){log_Output<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){log_Output<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){log_Output<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){log_Output<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){log_Output<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){log_Output<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){log_Output<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Change_String(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     File_Name=""; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){File_Name+='0';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){File_Name+='1';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){File_Name+='2';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){File_Name+='3';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){File_Name+='4';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){File_Name+='5';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){File_Name+='6';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){File_Name+='7';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){File_Name+='8';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){File_Name+='9';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){File_Name+='A';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){File_Name+='B';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){File_Name+='C';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){File_Name+='D';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){File_Name+='E';} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){File_Name+='F';} | ||||
|  |     } | ||||
|  | } | ||||
|  | int main(){ | ||||
|  |     unsigned int i=0; | ||||
|  |     char Name[8]; | ||||
|  |     cout<<"Welcome to the HRD!  (by Dnomd343)"<<endl<<"File Name : "; | ||||
|  |     cin>>InputFileName; | ||||
|  |     File_Input.open(InputFileName+".txt"); | ||||
|  |     InputFileName+="/"; | ||||
|  |     log_Output.open(InputFileName+"log.txt"); | ||||
|  |     Steps.clear(); | ||||
|  |     while(File_Input.eof()!=true){ | ||||
|  |         File_Input>>Name; | ||||
|  |         Styles.push_back(InputData(Name)); | ||||
|  |     } | ||||
|  |     for(i=0;i<Styles.size()-1;i++){Calculate(Styles[i]);} | ||||
|  |     File_Input.close(); | ||||
|  |     int k,nStep_num,Max_Steps=0; | ||||
|  |     for(i=0;i<Steps.size();i++){if(Steps[i]>Max_Steps){Max_Steps=Steps[i];}} | ||||
|  |     log_Output<<"Max-Steps:"<<Max_Steps<<endl; | ||||
|  |     nStep_num=0; | ||||
|  |     for(i=0;i<Steps.size();i++){if(Steps[i]==-2){nStep_num++;}} | ||||
|  |     log_Output<<"Error:"<<nStep_num<<endl; | ||||
|  |     nStep_num=0; | ||||
|  |     for(i=0;i<Steps.size();i++){if(Steps[i]==-1){nStep_num++;}} | ||||
|  |     log_Output<<"No Solve:"<<nStep_num<<endl; | ||||
|  |     for(k=0;k<=Max_Steps;k++){ | ||||
|  |         nStep_num=0; | ||||
|  |         for(i=0;i<Steps.size();i++){ | ||||
|  |             if(Steps[i]==k){nStep_num++;} | ||||
|  |         } | ||||
|  |         log_Output<<k<<"-Step:"<<nStep_num<<endl; | ||||
|  |     } | ||||
|  |     log_Output.close(); | ||||
|  |     return 0; | ||||
|  | } | ||||
|  | void Calculate(unsigned int Start_Data){ | ||||
|  |     unsigned int i; | ||||
|  |     string Path(InputFileName); | ||||
|  |     Change_String(Start_Data); | ||||
|  |     File_Name+=".txt"; | ||||
|  |     Path+=File_Name; | ||||
|  |     File_Output.open(Path.c_str()); | ||||
|  |     File_Output<<"Start:"; | ||||
|  |     OutputData(Start_Data); | ||||
|  |     log_OutputData(Start_Data); | ||||
|  |     log_Output<<" -> "; | ||||
|  |     Data_All.clear(); | ||||
|  |     Source.clear(); | ||||
|  |     Solve_Data.clear(); | ||||
|  |     for(i=0;i<0xFFFF;i++){Hash[i].clear();} | ||||
|  |     Output_str(Start_Data); | ||||
|  |     cout<<endl; | ||||
|  |     if(Check_Error(Start_Data)==false){ | ||||
|  |         File_Output<<endl<<"Something Error!!!"<<endl; | ||||
|  |         log_Output<<"Error!"<<endl; | ||||
|  |         Steps.push_back(-2); | ||||
|  |         goto err; | ||||
|  |     } | ||||
|  |     Solve(Start_Data); | ||||
|  |     if(Block[0].Address==14){ | ||||
|  |         File_Output<<endl<<"Result:"; | ||||
|  |         OutputData(Start_Data); | ||||
|  |         File_Output<<endl<<"Found Style:0"<<endl<<"Step(0):"<<endl; | ||||
|  |         OutputData(Start_Data); | ||||
|  |         File_Output<<endl<<"0 Steps Form "; | ||||
|  |         OutputData(Start_Data); | ||||
|  |         File_Output<<" To "; | ||||
|  |         OutputData(Start_Data); | ||||
|  |         Steps.push_back(0); | ||||
|  |         log_Output<<"0"<<endl; | ||||
|  |         goto err; | ||||
|  |     } | ||||
|  |     Data_All.push_back(Start_Data|0xF0); | ||||
|  |     Source.push_back(0); | ||||
|  |     i=0; | ||||
|  |     Done=false; | ||||
|  |     while(1){ | ||||
|  |         if(i==Data_All.size()){ | ||||
|  |             File_Output<<endl<<"Result:No way could be solve!!!"<<endl; | ||||
|  |             File_Output<<"Found Styles:"<<Data_All.size()<<endl; | ||||
|  |             log_Output<<"No Solve!"<<endl; | ||||
|  |             Steps.push_back(-1); | ||||
|  |             goto err; | ||||
|  |         } | ||||
|  |         Search_num=i; | ||||
|  |         Solve(Data_All[i]); | ||||
|  |         Find_Next(); | ||||
|  |         i++; | ||||
|  |         if(Done==true){break;} | ||||
|  |     } | ||||
|  |     while(1){ | ||||
|  |         Solve_Data.push_back(Solve_num); | ||||
|  |         Solve_num=Source[Solve_num]; | ||||
|  |         if(Solve_num==0){break;} | ||||
|  |     } | ||||
|  |     Solve_Data.push_back(0); | ||||
|  |     for(i=0;i<Solve_Data.size()/2;i++){swap(Solve_Data[i],Solve_Data[Solve_Data.size()-i-1]);} | ||||
|  |     for(i=0;i<Solve_Data.size();i++){Solve_Data[i]=Data_All[Solve_Data[i]];} | ||||
|  |     File_Output<<endl<<"Result:"; | ||||
|  |     OutputData(Solve_Data[Solve_Data.size()-1]); | ||||
|  |     File_Output<<endl<<"Found Styles:"<<Data_All.size()<<endl; | ||||
|  |     File_Output<<"Steps("<<(Solve_Data.size()-1)<<"):"; | ||||
|  |     log_Output<<(Solve_Data.size()-1)<<endl; | ||||
|  |     Steps.push_back(Solve_Data.size()-1); | ||||
|  |     for(i=0;i<Solve_Data.size();i++){ | ||||
|  |         File_Output<<endl; | ||||
|  |         OutputData(Solve_Data[i]); | ||||
|  |     } | ||||
|  |     File_Output<<endl<<(Solve_Data.size()-1)<<" Steps Form "; | ||||
|  |     OutputData(Start_Data); | ||||
|  |     File_Output<<" To "; | ||||
|  |     OutputData(Solve_Data[Solve_Data.size()-1]); | ||||
|  |     err:; | ||||
|  |     File_Output.close(); | ||||
|  | } | ||||
|  | void Add_List(unsigned int Data){ | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     poi=Hash[Data>>16].begin(); | ||||
|  |     while(poi!=Hash[Data>>16].end()){ | ||||
|  |         if((Data&0xFFFFFC0F)==(Data_All[*poi]&0xFFFFFC0F)){goto out;} | ||||
|  |         ++poi; | ||||
|  |     } | ||||
|  |     Hash[Data>>16].push_back(Data_All.size()); | ||||
|  |     Data_All.push_back(Data); | ||||
|  |     Source.push_back(Search_num); | ||||
|  |     out:; | ||||
|  | } | ||||
|  | bool Check_Error(unsigned int Start_Data){ | ||||
|  |     unsigned char addr,i; | ||||
|  |     bool Check[21]; | ||||
|  |     unsigned char Style_0,Style_1,Style_2,Style_3,Style_4; | ||||
|  |     Style_0=Style_1=Style_2=Style_3=Style_4=0; | ||||
|  |     for(i=1;i<=20;i++){Check[i]=false;} | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         Block[i].Address=0; | ||||
|  |         Block[i].Style=5; | ||||
|  |     } | ||||
|  |     Solve(Start_Data); | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         addr=Block[i].Address; | ||||
|  |         if(Block[i].Style==0){ | ||||
|  |             Style_0++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==1){ | ||||
|  |             Style_1++; | ||||
|  |             if(addr<1||addr>19){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==2){ | ||||
|  |             Style_2++; | ||||
|  |             if(addr<1||addr>16){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+4]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==3){ | ||||
|  |             Style_3++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==4){ | ||||
|  |             Style_4++; | ||||
|  |             if(addr<1||addr>15){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true||Check[addr+4]==true||Check[addr+5]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |             Check[addr+5]=true; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if(Style_0!=2){return false;} | ||||
|  |     if((Style_1+Style_2)!=5){return false;} | ||||
|  |     if(Style_3!=4){return false;} | ||||
|  |     if(Style_4!=1){return false;} | ||||
|  |     return true; | ||||
|  | } | ||||
|  | void Move_Block(unsigned char Move_num,unsigned char Direction_1,unsigned char Direction_2){ | ||||
|  |     Table[Block[Move_num].Address]=12; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=12;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=12;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=12;Table[Block[Move_num].Address+4]=12;Table[Block[Move_num].Address+5]=12;} | ||||
|  |     Table[Space_1]=12; | ||||
|  |     Table[Space_2]=12; | ||||
|  |     if(Direction_1==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address++;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address++;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     unsigned int Data=0; | ||||
|  |     unsigned char addr=1,num=1; | ||||
|  |     bool jump=false,Use[13]; | ||||
|  |     for(unsigned char i=0;i<=12;i++){Use[i]=false;} | ||||
|  |     while(1){ | ||||
|  |         while(Use[Table[addr]]==true){addr++;} | ||||
|  |         if(Table[addr]==12){ | ||||
|  |             Data=Data|(0<<((16-num)*2)); | ||||
|  |             num++; | ||||
|  |             addr++; | ||||
|  |             jump=true; | ||||
|  |         } | ||||
|  |         if(jump==false){ | ||||
|  |             if(Block[Table[addr]].Style==4){ | ||||
|  |                 Data=Data|num; | ||||
|  |                 Use[0]=true; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 if(Table[addr]==Move_num){Data=Data|(num<<4);} | ||||
|  |                 Data=Data|(Block[Table[addr]].Style<<((16-num)*2)); | ||||
|  |                 Use[Table[addr]]=true; | ||||
|  |                 num++; | ||||
|  |             } | ||||
|  |         } | ||||
|  |         else{jump=false;} | ||||
|  |         if(num==12){break;} | ||||
|  |     } | ||||
|  |     if((Block[0].Address==15)&&((Data&0x0F)==0)){Data=Data|0x0C;} | ||||
|  |     Add_List(Data); | ||||
|  |     if(Block[0].Address==14){Done=true;Solve_num=Data_All.size()-1;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address--;} | ||||
|  |     if(Direction_1==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address--;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     Table[Space_1]=Space_num_1; | ||||
|  |     Table[Space_2]=Space_num_2; | ||||
|  | } | ||||
|  | void Find_Next(){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<=0x0B;i++){ | ||||
|  |         if(i!=Last_Move){ | ||||
|  |             if(Block[i].Style==4){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)&&(Block[Table[Block[i].Address+9]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)&&(Block[Table[Block[i].Address+6]].Style==0)){Move_Block(i,4,0);} | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==1){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==2){ | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,0);} | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=8)&&(Block[Table[Block[i].Address+12]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==3){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,1,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,4);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,2,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,4);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,3,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,2);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,4,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | void Solve(unsigned int Data){ | ||||
|  |     unsigned char i,k=1; | ||||
|  |     unsigned char dat,addr=Data&0x0F; | ||||
|  |     Space_1=Space_2=Space_num_1=Space_num_2=0; | ||||
|  |     Last_Move=(Data>>4)&0x0F; | ||||
|  |     for(i=1;i<=20;i++){Table[i]=0xFF;} | ||||
|  |     for(i=1;i<=12;i++){ | ||||
|  |         while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         if(i==addr){ | ||||
|  |             Block[0].Address=k; | ||||
|  |             Block[0].Style=4; | ||||
|  |             Table[k]=Table[k+1]=Table[k+4]=Table[k+5]=0; | ||||
|  |             while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         } | ||||
|  |         if(i==12){break;} | ||||
|  |         dat=(Data>>(32-i*2))&0x03; | ||||
|  |         Block[i].Address=k; | ||||
|  |         Table[k]=i; | ||||
|  |         if(dat==0){Block[i].Style=0;if(Space_1==0){Space_1=k;Space_num_1=i;}else{Space_2=k;Space_num_2=i;}} | ||||
|  |         else if(dat==1){Block[i].Style=1;Table[k+1]=i;} | ||||
|  |         else if(dat==2){Block[i].Style=2;Table[k+4]=i;} | ||||
|  |         else if(dat==3){Block[i].Style=3;} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Output(){ | ||||
|  |     unsigned int i,k,m; | ||||
|  |     unsigned int Start_x,Start_y,End_x,End_y; | ||||
|  |     bool Graph[(Output_Width+1)*4+1][(Output_Width+1)*5+1]; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             Graph[i][k]=false; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(m=0;m<=0x0B;m++){ | ||||
|  |         if(Block[m].Style!=0){ | ||||
|  |             Start_x=((Block[m].Address-1)%4)*(Output_Width+1)+1; | ||||
|  |             Start_y=(Block[m].Address-1)/4; | ||||
|  |             Start_y=Start_y*(Output_Width+1)+1; | ||||
|  |             if((Block[m].Style==1)||(Block[m].Style==4)){ | ||||
|  |                 End_x=Start_x+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_x=Start_x+Output_Width-1; | ||||
|  |             } | ||||
|  |             if((Block[m].Style==2)||(Block[m].Style==4)){ | ||||
|  |                 End_y=Start_y+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_y=Start_y+Output_Width-1; | ||||
|  |             } | ||||
|  |             for(i=Start_x;i<=End_x;i++){ | ||||
|  |                 for(k=Start_y;k<=End_y;k++){ | ||||
|  |                     Graph[i][k]=true; | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+3;i++){cout<<Square_str;} | ||||
|  |     cout<<endl<<Square_str; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             if(Graph[i][k]==false){cout<<"  ";}else{cout<<Square_str;} | ||||
|  |         } | ||||
|  |         cout<<Square_str<<endl<<Square_str; | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+2;i++){cout<<Square_str;} | ||||
|  |     cout<<endl; | ||||
|  | } | ||||
|  | void Output_str(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){cout<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){cout<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){cout<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){cout<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){cout<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){cout<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){cout<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){cout<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){cout<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){cout<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){cout<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){cout<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){cout<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){cout<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){cout<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){cout<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | unsigned int Input(){ | ||||
|  |     unsigned int i,Dat=0; | ||||
|  |     char Data_str[8]; | ||||
|  |     cin>>Data_str; | ||||
|  |     if((Data_str[0]=='e')&&(Data_str[1]=='x')&&(Data_str[2]=='i')&&(Data_str[3]=='t')){End=true;} | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if(Data_str[i]=='0'){Dat=Dat|(0x0<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='1'){Dat=Dat|(0x1<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='2'){Dat=Dat|(0x2<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='3'){Dat=Dat|(0x3<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='4'){Dat=Dat|(0x4<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='5'){Dat=Dat|(0x5<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='6'){Dat=Dat|(0x6<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='7'){Dat=Dat|(0x7<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='8'){Dat=Dat|(0x8<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='9'){Dat=Dat|(0x9<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='A'||Data_str[i]=='a'){Dat=Dat|(0xA<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='B'||Data_str[i]=='b'){Dat=Dat|(0xB<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='C'||Data_str[i]=='c'){Dat=Dat|(0xC<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='D'||Data_str[i]=='d'){Dat=Dat|(0xD<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='E'||Data_str[i]=='e'){Dat=Dat|(0xE<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='F'||Data_str[i]=='f'){Dat=Dat|(0xF<<(28-i*4));} | ||||
|  |     } | ||||
|  |     return Dat; | ||||
|  | } | ||||
|  | 
 | ||||
|  | 
 | ||||
| @ -0,0 +1,399 @@ | |||||
|  | #include<iostream> | ||||
|  | #include<vector> | ||||
|  | #include<list> | ||||
|  | using namespace std; | ||||
|  | const unsigned char Output_Width=8; | ||||
|  | const string Square_str="\u2588\u2588"; | ||||
|  | struct Block_Data{ | ||||
|  |     unsigned char Address; | ||||
|  |     unsigned char Style; | ||||
|  | }; | ||||
|  | vector<unsigned int> Data_All; | ||||
|  | vector<unsigned int> Source; | ||||
|  | vector<unsigned int> Solve_Data; | ||||
|  | list<unsigned int> Hash[0xFFFF]; | ||||
|  | struct Block_Data Block[12]; | ||||
|  | unsigned char Table[21]; | ||||
|  | unsigned char Space_1,Space_2,Space_num_1,Space_num_2,Last_Move; | ||||
|  | unsigned int Search_num,Solve_num; | ||||
|  | bool Done,End=false; | ||||
|  | void Solve(unsigned int Data); | ||||
|  | void Find_Next(); | ||||
|  | void Move_Block(unsigned char num,unsigned char Direction_1,unsigned char Direction_2); | ||||
|  | void Add_List(unsigned int Data); | ||||
|  | void Output_str(unsigned int Data); | ||||
|  | unsigned int Input(); | ||||
|  | bool Check_Error(unsigned int Start_Data); | ||||
|  | void Calculate(unsigned int Start_Data); | ||||
|  | void Output(); | ||||
|  | int main(){ | ||||
|  |     unsigned int Start_Data,i=0; | ||||
|  |     cout<<"Welcome to the HRD!  (by Dnomd343)"<<endl<<endl; | ||||
|  |     while(1){ | ||||
|  |         cout<<"HRD style:"; | ||||
|  |         Start_Data=Input(); | ||||
|  | 	if(End==true){return 0;} | ||||
|  |         Calculate(Start_Data); | ||||
|  |         cout<<"Press ENTER to show the Best-Solve..."; | ||||
|  |         cin.get(); | ||||
|  |         for(i=0;i<Solve_Data.size();i++){ | ||||
|  |        	    cin.get(); | ||||
|  |             for(unsigned int k=0;k<=28;k++){cout<<endl;} | ||||
|  |             cout<<"Step "<<i<<" -> "; | ||||
|  |             Output_str(Solve_Data[i]); | ||||
|  |             cout<<endl; | ||||
|  |             Solve(Solve_Data[i]); | ||||
|  |             Output(); | ||||
|  |         } | ||||
|  |         cout<<"Show has been compete!"<<endl<<endl<<endl; | ||||
|  |         cin.clear(); | ||||
|  |     } | ||||
|  |     return 0; | ||||
|  | } | ||||
|  | void Calculate(unsigned int Start_Data){ | ||||
|  |     unsigned int i; | ||||
|  |     Data_All.clear(); | ||||
|  |     Source.clear(); | ||||
|  |     Solve_Data.clear(); | ||||
|  |     for(i=0;i<0xFFFF;i++){Hash[i].clear();} | ||||
|  |     if(Check_Error(Start_Data)==false){cout<<"Something Error!!!"<<endl;goto err;} | ||||
|  |     Data_All.push_back(Start_Data|0xF0); | ||||
|  |     Source.push_back(0); | ||||
|  |     Solve(Data_All[0]); | ||||
|  |     Output(); | ||||
|  |     cout<<"Start to calculate : "; | ||||
|  |     Output_str(Data_All[0]&(~0xF0)); | ||||
|  |     cout<<endl<<"Waiting..."<<endl; | ||||
|  |     i=0; | ||||
|  |     Done=false; | ||||
|  |     while(1){ | ||||
|  |         if(i==Data_All.size()){cout<<"No Solve!"<<endl;goto err;} | ||||
|  |         Search_num=i; | ||||
|  |         Solve(Data_All[i]); | ||||
|  |         Find_Next(); | ||||
|  |         i++; | ||||
|  |         if(Done==true){break;} | ||||
|  |     } | ||||
|  |     while(1){ | ||||
|  |         Solve_Data.push_back(Solve_num); | ||||
|  |         Solve_num=Source[Solve_num]; | ||||
|  |         if(Solve_num==0){break;} | ||||
|  |     } | ||||
|  |     Solve_Data.push_back(0); | ||||
|  |     for(i=0;i<Solve_Data.size()/2;i++){swap(Solve_Data[i],Solve_Data[Solve_Data.size()-i-1]);} | ||||
|  |     for(i=0;i<Solve_Data.size();i++){Solve_Data[i]=Data_All[Solve_Data[i]];} | ||||
|  |     cout<<"Calculate Done!"<<endl; | ||||
|  |     err:; | ||||
|  |     cout<<"Step:"<<Solve_Data.size()-1<<"  Pool:"<<Data_All.size()<<endl; | ||||
|  | } | ||||
|  | void Add_List(unsigned int Data){ | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     poi=Hash[Data>>16].begin(); | ||||
|  |     while(poi!=Hash[Data>>16].end()){ | ||||
|  |         if((Data&0xFFFFFC0F)==(Data_All[*poi]&0xFFFFFC0F)){goto out;} | ||||
|  |         ++poi; | ||||
|  |     } | ||||
|  |     Hash[Data>>16].push_back(Data_All.size()); | ||||
|  |     Data_All.push_back(Data); | ||||
|  |     Source.push_back(Search_num); | ||||
|  |     out:; | ||||
|  | } | ||||
|  | bool Check_Error(unsigned int Start_Data){ | ||||
|  |     unsigned char addr,i; | ||||
|  |     bool Check[21]; | ||||
|  |     unsigned char Style_0,Style_1,Style_2,Style_3,Style_4; | ||||
|  |     Style_0=Style_1=Style_2=Style_3=Style_4=0; | ||||
|  |     for(i=1;i<=20;i++){Check[i]=false;} | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         Block[i].Address=0; | ||||
|  |         Block[i].Style=5; | ||||
|  |     } | ||||
|  |     Solve(Start_Data); | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         addr=Block[i].Address; | ||||
|  |         if(Block[i].Style==0){ | ||||
|  |             Style_0++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==1){ | ||||
|  |             Style_1++; | ||||
|  |             if(addr<1||addr>19){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==2){ | ||||
|  |             Style_2++; | ||||
|  |             if(addr<1||addr>16){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+4]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==3){ | ||||
|  |             Style_3++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==4){ | ||||
|  |             Style_4++; | ||||
|  |             if(addr<1||addr>15){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true||Check[addr+4]==true||Check[addr+5]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |             Check[addr+5]=true; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if(Style_0!=2){return false;} | ||||
|  |     if((Style_1+Style_2)!=5){return false;} | ||||
|  |     if(Style_3!=4){return false;} | ||||
|  |     if(Style_4!=1){return false;} | ||||
|  |     return true; | ||||
|  | } | ||||
|  | void Move_Block(unsigned char Move_num,unsigned char Direction_1,unsigned char Direction_2){ | ||||
|  |     Table[Block[Move_num].Address]=12; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=12;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=12;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=12;Table[Block[Move_num].Address+4]=12;Table[Block[Move_num].Address+5]=12;} | ||||
|  |     Table[Space_1]=12; | ||||
|  |     Table[Space_2]=12; | ||||
|  |     if(Direction_1==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address++;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address++;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     unsigned int Data=0; | ||||
|  |     unsigned char addr=1,num=1; | ||||
|  |     bool jump=false,Use[13]; | ||||
|  |     for(unsigned char i=0;i<=12;i++){Use[i]=false;} | ||||
|  |     while(1){ | ||||
|  |         while(Use[Table[addr]]==true){addr++;} | ||||
|  |         if(Table[addr]==12){ | ||||
|  |             Data=Data|(0<<((16-num)*2)); | ||||
|  |             num++; | ||||
|  |             addr++; | ||||
|  |             jump=true; | ||||
|  |         } | ||||
|  |         if(jump==false){ | ||||
|  |             if(Block[Table[addr]].Style==4){ | ||||
|  |                 Data=Data|num; | ||||
|  |                 Use[0]=true; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 if(Table[addr]==Move_num){Data=Data|(num<<4);} | ||||
|  |                 Data=Data|(Block[Table[addr]].Style<<((16-num)*2)); | ||||
|  |                 Use[Table[addr]]=true; | ||||
|  |                 num++; | ||||
|  |             } | ||||
|  |         } | ||||
|  |         else{jump=false;} | ||||
|  |         if(num==12){break;} | ||||
|  |     } | ||||
|  |     if((Block[0].Address==15)&&((Data&0x0F)==0)){Data=Data|0x0C;} | ||||
|  |     Add_List(Data); | ||||
|  |     if(Block[0].Address==14){Done=true;Solve_num=Data_All.size()-1;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address--;} | ||||
|  |     if(Direction_1==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address--;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     Table[Space_1]=Space_num_1; | ||||
|  |     Table[Space_2]=Space_num_2; | ||||
|  | } | ||||
|  | void Find_Next(){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<=0x0B;i++){ | ||||
|  |         if(i!=Last_Move){ | ||||
|  |             if(Block[i].Style==4){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)&&(Block[Table[Block[i].Address+9]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)&&(Block[Table[Block[i].Address+6]].Style==0)){Move_Block(i,4,0);} | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==1){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==2){ | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,0);} | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=8)&&(Block[Table[Block[i].Address+12]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==3){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,1,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,4);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,2,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,4);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,3,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,2);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,4,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | void Solve(unsigned int Data){ | ||||
|  |     unsigned char i,k=1; | ||||
|  |     unsigned char dat,addr=Data&0x0F; | ||||
|  |     Space_1=Space_2=Space_num_1=Space_num_2=0; | ||||
|  |     Last_Move=(Data>>4)&0x0F; | ||||
|  |     for(i=1;i<=20;i++){Table[i]=0xFF;} | ||||
|  |     for(i=1;i<=12;i++){ | ||||
|  |         while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         if(i==addr){ | ||||
|  |             Block[0].Address=k; | ||||
|  |             Block[0].Style=4; | ||||
|  |             Table[k]=Table[k+1]=Table[k+4]=Table[k+5]=0; | ||||
|  |             while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         } | ||||
|  |         if(i==12){break;} | ||||
|  |         dat=(Data>>(32-i*2))&0x03; | ||||
|  |         Block[i].Address=k; | ||||
|  |         Table[k]=i; | ||||
|  |         if(dat==0){Block[i].Style=0;if(Space_1==0){Space_1=k;Space_num_1=i;}else{Space_2=k;Space_num_2=i;}} | ||||
|  |         else if(dat==1){Block[i].Style=1;Table[k+1]=i;} | ||||
|  |         else if(dat==2){Block[i].Style=2;Table[k+4]=i;} | ||||
|  |         else if(dat==3){Block[i].Style=3;} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Output(){ | ||||
|  |     unsigned int i,k,m; | ||||
|  |     unsigned int Start_x,Start_y,End_x,End_y; | ||||
|  |     bool Graph[(Output_Width+1)*4+1][(Output_Width+1)*5+1]; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             Graph[i][k]=false; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(m=0;m<=0x0B;m++){ | ||||
|  |         if(Block[m].Style!=0){ | ||||
|  |             Start_x=((Block[m].Address-1)%4)*(Output_Width+1)+1; | ||||
|  |             Start_y=(Block[m].Address-1)/4; | ||||
|  |             Start_y=Start_y*(Output_Width+1)+1; | ||||
|  |             if((Block[m].Style==1)||(Block[m].Style==4)){ | ||||
|  |                 End_x=Start_x+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_x=Start_x+Output_Width-1; | ||||
|  |             } | ||||
|  |             if((Block[m].Style==2)||(Block[m].Style==4)){ | ||||
|  |                 End_y=Start_y+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_y=Start_y+Output_Width-1; | ||||
|  |             } | ||||
|  |             for(i=Start_x;i<=End_x;i++){ | ||||
|  |                 for(k=Start_y;k<=End_y;k++){ | ||||
|  |                     Graph[i][k]=true; | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+3;i++){cout<<Square_str;} | ||||
|  |     cout<<endl<<Square_str; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             if(Graph[i][k]==false){cout<<"  ";}else{cout<<Square_str;} | ||||
|  |         } | ||||
|  |         cout<<Square_str<<endl<<Square_str; | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+2;i++){cout<<Square_str;} | ||||
|  |     cout<<endl; | ||||
|  | } | ||||
|  | void Output_str(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){cout<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){cout<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){cout<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){cout<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){cout<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){cout<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){cout<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){cout<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){cout<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){cout<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){cout<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){cout<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){cout<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){cout<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){cout<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){cout<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | unsigned int Input(){ | ||||
|  |     unsigned int i,Dat=0; | ||||
|  |     char Data_str[8]; | ||||
|  |     cin>>Data_str; | ||||
|  |     if((Data_str[0]=='e')&&(Data_str[1]=='x')&&(Data_str[2]=='i')&&(Data_str[3]=='t')){End=true;} | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if(Data_str[i]=='0'){Dat=Dat|(0x0<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='1'){Dat=Dat|(0x1<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='2'){Dat=Dat|(0x2<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='3'){Dat=Dat|(0x3<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='4'){Dat=Dat|(0x4<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='5'){Dat=Dat|(0x5<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='6'){Dat=Dat|(0x6<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='7'){Dat=Dat|(0x7<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='8'){Dat=Dat|(0x8<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='9'){Dat=Dat|(0x9<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='A'||Data_str[i]=='a'){Dat=Dat|(0xA<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='B'||Data_str[i]=='b'){Dat=Dat|(0xB<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='C'||Data_str[i]=='c'){Dat=Dat|(0xC<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='D'||Data_str[i]=='d'){Dat=Dat|(0xD<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='E'||Data_str[i]=='e'){Dat=Dat|(0xE<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='F'||Data_str[i]=='f'){Dat=Dat|(0xF<<(28-i*4));} | ||||
|  |     } | ||||
|  |     return Dat; | ||||
|  | } | ||||
|  | 
 | ||||
| @ -0,0 +1,435 @@ | |||||
|  | #include<iostream> | ||||
|  | #include<fstream> | ||||
|  | #include<vector> | ||||
|  | #include<list> | ||||
|  | using namespace std; | ||||
|  | const unsigned char Output_Width=8; | ||||
|  | const string Square_str="\u2588\u2588"; | ||||
|  | struct Block_Data{ | ||||
|  |     unsigned char Address; | ||||
|  |     unsigned char Style; | ||||
|  | }; | ||||
|  | vector<unsigned int> Data_All; | ||||
|  | vector<unsigned int> Source; | ||||
|  | vector<unsigned int> Solve_Data; | ||||
|  | list<unsigned int> Hash[0xFFFF]; | ||||
|  | ofstream File_Output; | ||||
|  | ifstream File_Input; | ||||
|  | struct Block_Data Block[12]; | ||||
|  | unsigned char Table[21]; | ||||
|  | unsigned char Space_1,Space_2,Space_num_1,Space_num_2,Last_Move; | ||||
|  | unsigned int Search_num,Solve_num; | ||||
|  | bool Done,End=false; | ||||
|  | void Solve(unsigned int Data); | ||||
|  | void Find_Next(); | ||||
|  | void Move_Block(unsigned char num,unsigned char Direction_1,unsigned char Direction_2); | ||||
|  | void Add_List(unsigned int Data); | ||||
|  | void Output_str(unsigned int Data); | ||||
|  | unsigned int Input(char Data_str[8]); | ||||
|  | bool Check_Error(unsigned int Start_Data); | ||||
|  | void Calculate(unsigned int Start_Data); | ||||
|  | void Output(); | ||||
|  | void OutputData(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){File_Output<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){File_Output<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){File_Output<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){File_Output<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){File_Output<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){File_Output<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){File_Output<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){File_Output<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){File_Output<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){File_Output<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){File_Output<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){File_Output<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){File_Output<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){File_Output<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){File_Output<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){File_Output<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | int main(){ | ||||
|  |     char Name[8]; | ||||
|  |     unsigned int Start_Data,i,k; | ||||
|  |     cout<<"Welcome to the HRD!  (by Dnomd343)"<<endl<<endl; | ||||
|  | 
 | ||||
|  | File_Output.open("All HRD.txt"); | ||||
|  | cout<<hex; | ||||
|  |     for(i=0;i<=0x3ffffc;i++){ | ||||
|  |         for(k=1;k<=12;k++){ | ||||
|  |             Start_Data=0; | ||||
|  |             Start_Data=(Start_Data|(i<<10))|k; | ||||
|  |             if(Check_Error(Start_Data)==true){OutputData(Start_Data);File_Output<<endl;}//Output_str(Start_Data);cout<<endl;}
 | ||||
|  |         } | ||||
|  |     } | ||||
|  | return 0; | ||||
|  |     i=0; | ||||
|  |     while(1){ | ||||
|  |         cout<<"HRD style:"; | ||||
|  |         cin>>Name; | ||||
|  |         Start_Data=Input(Name); | ||||
|  | 	if(End==true){return 0;} | ||||
|  |         Calculate(Start_Data); | ||||
|  |         cout<<"Press ENTER to show the Best-Solve..."; | ||||
|  |         cin.get(); | ||||
|  |         for(i=0;i<Solve_Data.size();i++){ | ||||
|  |        	    cin.get(); | ||||
|  |             for(unsigned int k=0;k<=28;k++){cout<<endl;} | ||||
|  |             cout<<"Step "<<i<<" -> "; | ||||
|  |             Output_str(Solve_Data[i]); | ||||
|  |             cout<<endl; | ||||
|  |             Solve(Solve_Data[i]); | ||||
|  |             Output(); | ||||
|  |         } | ||||
|  |         cout<<"Show has been compete!"<<endl<<endl<<endl; | ||||
|  |         cin.clear(); | ||||
|  |     } | ||||
|  |     return 0; | ||||
|  | } | ||||
|  | void Calculate(unsigned int Start_Data){ | ||||
|  |     unsigned int i; | ||||
|  |     Data_All.clear(); | ||||
|  |     Source.clear(); | ||||
|  |     Solve_Data.clear(); | ||||
|  |     for(i=0;i<0xFFFF;i++){Hash[i].clear();} | ||||
|  |     if(Check_Error(Start_Data)==false){cout<<"Something Error!!!"<<endl;goto err;} | ||||
|  |     Data_All.push_back(Start_Data|0xF0); | ||||
|  |     Source.push_back(0); | ||||
|  |     Solve(Data_All[0]); | ||||
|  |     Output(); | ||||
|  |     cout<<"Start to calculate : "; | ||||
|  |     Output_str(Data_All[0]&(~0xF0)); | ||||
|  |     cout<<endl<<"Waiting..."<<endl; | ||||
|  |     i=0; | ||||
|  |     Done=false; | ||||
|  |     while(1){ | ||||
|  |         if(i==Data_All.size()){cout<<"No Solve!"<<endl;goto err;} | ||||
|  |         Search_num=i; | ||||
|  |         Solve(Data_All[i]); | ||||
|  |         Find_Next(); | ||||
|  |         i++; | ||||
|  |         if(Done==true){break;} | ||||
|  |     } | ||||
|  |     while(1){ | ||||
|  |         Solve_Data.push_back(Solve_num); | ||||
|  |         Solve_num=Source[Solve_num]; | ||||
|  |         if(Solve_num==0){break;} | ||||
|  |     } | ||||
|  |     Solve_Data.push_back(0); | ||||
|  |     for(i=0;i<Solve_Data.size()/2;i++){swap(Solve_Data[i],Solve_Data[Solve_Data.size()-i-1]);} | ||||
|  |     for(i=0;i<Solve_Data.size();i++){Solve_Data[i]=Data_All[Solve_Data[i]];} | ||||
|  |     cout<<"Calculate Done!"<<endl; | ||||
|  |     err:; | ||||
|  |     cout<<"Step:"<<Solve_Data.size()-1<<"  Pool:"<<Data_All.size()<<endl; | ||||
|  | } | ||||
|  | void Add_List(unsigned int Data){ | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     poi=Hash[Data>>16].begin(); | ||||
|  |     while(poi!=Hash[Data>>16].end()){ | ||||
|  |         if((Data&0xFFFFFC0F)==(Data_All[*poi]&0xFFFFFC0F)){goto out;} | ||||
|  |         ++poi; | ||||
|  |     } | ||||
|  |     Hash[Data>>16].push_back(Data_All.size()); | ||||
|  |     Data_All.push_back(Data); | ||||
|  |     Source.push_back(Search_num); | ||||
|  |     out:; | ||||
|  | } | ||||
|  | bool Check_Error(unsigned int Start_Data){ | ||||
|  |     unsigned char addr,i; | ||||
|  |     bool Check[21]; | ||||
|  |     unsigned char Style_0,Style_1,Style_2,Style_3,Style_4; | ||||
|  |     Style_0=Style_1=Style_2=Style_3=Style_4=0; | ||||
|  |     for(i=1;i<=20;i++){Check[i]=false;} | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         Block[i].Address=0; | ||||
|  |         Block[i].Style=5; | ||||
|  |     } | ||||
|  |     Solve(Start_Data); | ||||
|  |     for(i=0;i<=11;i++){ | ||||
|  |         addr=Block[i].Address; | ||||
|  |         if(Block[i].Style==0){ | ||||
|  |             Style_0++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==1){ | ||||
|  |             Style_1++; | ||||
|  |             if(addr<1||addr>19){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==2){ | ||||
|  |             Style_2++; | ||||
|  |             if(addr<1||addr>16){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+4]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==3){ | ||||
|  |             Style_3++; | ||||
|  |             if(addr<1||addr>20){return false;} | ||||
|  |             if(Check[addr]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |         } | ||||
|  |         if(Block[i].Style==4){ | ||||
|  |             Style_4++; | ||||
|  |             if(addr<1||addr>15){return false;} | ||||
|  |             if((addr%4)==0){return false;} | ||||
|  |             if(Check[addr]==true||Check[addr+1]==true||Check[addr+4]==true||Check[addr+5]==true){return false;} | ||||
|  |             Check[addr]=true; | ||||
|  |             Check[addr+1]=true; | ||||
|  |             Check[addr+4]=true; | ||||
|  |             Check[addr+5]=true; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if(Style_0!=2){return false;} | ||||
|  |     if((Style_1+Style_2)!=5){return false;} | ||||
|  |     if(Style_3!=4){return false;} | ||||
|  |     if(Style_4!=1){return false;} | ||||
|  |     return true; | ||||
|  | } | ||||
|  | void Move_Block(unsigned char Move_num,unsigned char Direction_1,unsigned char Direction_2){ | ||||
|  |     Table[Block[Move_num].Address]=12; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=12;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=12;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=12;Table[Block[Move_num].Address+4]=12;Table[Block[Move_num].Address+5]=12;} | ||||
|  |     Table[Space_1]=12; | ||||
|  |     Table[Space_2]=12; | ||||
|  |     if(Direction_1==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address++;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address--;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address++;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     unsigned int Data=0; | ||||
|  |     unsigned char addr=1,num=1; | ||||
|  |     bool jump=false,Use[13]; | ||||
|  |     for(unsigned char i=0;i<=12;i++){Use[i]=false;} | ||||
|  |     while(1){ | ||||
|  |         while(Use[Table[addr]]==true){addr++;} | ||||
|  |         if(Table[addr]==12){ | ||||
|  |             Data=Data|(0<<((16-num)*2)); | ||||
|  |             num++; | ||||
|  |             addr++; | ||||
|  |             jump=true; | ||||
|  |         } | ||||
|  |         if(jump==false){ | ||||
|  |             if(Block[Table[addr]].Style==4){ | ||||
|  |                 Data=Data|num; | ||||
|  |                 Use[0]=true; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 if(Table[addr]==Move_num){Data=Data|(num<<4);} | ||||
|  |                 Data=Data|(Block[Table[addr]].Style<<((16-num)*2)); | ||||
|  |                 Use[Table[addr]]=true; | ||||
|  |                 num++; | ||||
|  |             } | ||||
|  |         } | ||||
|  |         else{jump=false;} | ||||
|  |         if(num==12){break;} | ||||
|  |     } | ||||
|  |     Add_List(Data); | ||||
|  |     if(Block[0].Address==14){Done=true;Solve_num=Data_All.size()-1;} | ||||
|  |     if(Direction_2==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_2==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_2==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_2==4){Block[Move_num].Address--;} | ||||
|  |     if(Direction_1==1){Block[Move_num].Address+=4;} | ||||
|  |     else if(Direction_1==2){Block[Move_num].Address-=4;} | ||||
|  |     else if(Direction_1==3){Block[Move_num].Address++;} | ||||
|  |     else if(Direction_1==4){Block[Move_num].Address--;} | ||||
|  |     Table[Block[Move_num].Address]=Move_num; | ||||
|  |     if(Block[Move_num].Style==1){Table[Block[Move_num].Address+1]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==2){Table[Block[Move_num].Address+4]=Move_num;} | ||||
|  |     if(Block[Move_num].Style==4){Table[Block[Move_num].Address+1]=Move_num;Table[Block[Move_num].Address+4]=Move_num;Table[Block[Move_num].Address+5]=Move_num;} | ||||
|  |     Table[Space_1]=Space_num_1; | ||||
|  |     Table[Space_2]=Space_num_2; | ||||
|  | } | ||||
|  | void Find_Next(){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<=0x0B;i++){ | ||||
|  |         if(i!=Last_Move){ | ||||
|  |             if(Block[i].Style==4){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)&&(Block[Table[Block[i].Address+9]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)&&(Block[Table[Block[i].Address+6]].Style==0)){Move_Block(i,4,0);} | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==1){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,0);} | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,0);} | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==2){ | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,0);} | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,0);} | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=8)&&(Block[Table[Block[i].Address+12]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |             else if(Block[i].Style==3){ | ||||
|  |                 if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-4]].Style==0)){ | ||||
|  |                     Move_Block(i,1,0); | ||||
|  |                     if((Block[i].Address>=9)&&(Block[Table[Block[i].Address-8]].Style==0)){Move_Block(i,1,1);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,1,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,1,4);} | ||||
|  |                 } | ||||
|  |                 if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+4]].Style==0)){ | ||||
|  |                     Move_Block(i,2,0); | ||||
|  |                     if((Block[i].Address<=12)&&(Block[Table[Block[i].Address+8]].Style==0)){Move_Block(i,2,2);} | ||||
|  |                     if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,2,3);} | ||||
|  |                     if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,2,4);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=1)&&(Block[Table[Block[i].Address-1]].Style==0)){ | ||||
|  |                     Move_Block(i,3,0); | ||||
|  |                     if(((Block[i].Address%4)!=2)&&(Block[Table[Block[i].Address-2]].Style==0)){Move_Block(i,3,3);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-5]].Style==0)){Move_Block(i,3,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+3]].Style==0)){Move_Block(i,3,2);} | ||||
|  |                 } | ||||
|  |                 if(((Block[i].Address%4)!=0)&&(Block[Table[Block[i].Address+1]].Style==0)){ | ||||
|  |                     Move_Block(i,4,0); | ||||
|  |                     if(((Block[i].Address%4)!=3)&&(Block[Table[Block[i].Address+2]].Style==0)){Move_Block(i,4,4);} | ||||
|  |                     if((Block[i].Address>=5)&&(Block[Table[Block[i].Address-3]].Style==0)){Move_Block(i,4,1);} | ||||
|  |                     if((Block[i].Address<=16)&&(Block[Table[Block[i].Address+5]].Style==0)){Move_Block(i,4,2);} | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | void Solve(unsigned int Data){ | ||||
|  |     unsigned char i,k=1; | ||||
|  |     unsigned char dat,addr=Data&0x0F; | ||||
|  |     Space_1=Space_2=Space_num_1=Space_num_2=0; | ||||
|  |     Last_Move=(Data>>4)&0x0F; | ||||
|  |     for(i=1;i<=20;i++){Table[i]=0xFF;} | ||||
|  |     for(i=1;i<=12;i++){ | ||||
|  |         while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         if(i==addr){ | ||||
|  |             Block[0].Address=k; | ||||
|  |             Block[0].Style=4; | ||||
|  |             Table[k]=Table[k+1]=Table[k+4]=Table[k+5]=0; | ||||
|  |             while(Table[k]!=0xFF){k++;if(k>20){break;}} | ||||
|  |         } | ||||
|  |         if(i==12){break;} | ||||
|  |         dat=(Data>>(32-i*2))&0x03; | ||||
|  |         Block[i].Address=k; | ||||
|  |         Table[k]=i; | ||||
|  |         if(dat==0){Block[i].Style=0;if(Space_1==0){Space_1=k;Space_num_1=i;}else{Space_2=k;Space_num_2=i;}} | ||||
|  |         else if(dat==1){Block[i].Style=1;Table[k+1]=i;} | ||||
|  |         else if(dat==2){Block[i].Style=2;Table[k+4]=i;} | ||||
|  |         else if(dat==3){Block[i].Style=3;} | ||||
|  |     } | ||||
|  | } | ||||
|  | void Output(){ | ||||
|  |     unsigned int i,k,m; | ||||
|  |     unsigned int Start_x,Start_y,End_x,End_y; | ||||
|  |     bool Graph[(Output_Width+1)*4+1][(Output_Width+1)*5+1]; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             Graph[i][k]=false; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(m=0;m<=0x0B;m++){ | ||||
|  |         if(Block[m].Style!=0){ | ||||
|  |             Start_x=((Block[m].Address-1)%4)*(Output_Width+1)+1; | ||||
|  |             Start_y=(Block[m].Address-1)/4; | ||||
|  |             Start_y=Start_y*(Output_Width+1)+1; | ||||
|  |             if((Block[m].Style==1)||(Block[m].Style==4)){ | ||||
|  |                 End_x=Start_x+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_x=Start_x+Output_Width-1; | ||||
|  |             } | ||||
|  |             if((Block[m].Style==2)||(Block[m].Style==4)){ | ||||
|  |                 End_y=Start_y+Output_Width*2; | ||||
|  |             } | ||||
|  |             else{ | ||||
|  |                 End_y=Start_y+Output_Width-1; | ||||
|  |             } | ||||
|  |             for(i=Start_x;i<=End_x;i++){ | ||||
|  |                 for(k=Start_y;k<=End_y;k++){ | ||||
|  |                     Graph[i][k]=true; | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+3;i++){cout<<Square_str;} | ||||
|  |     cout<<endl<<Square_str; | ||||
|  |     for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  |         for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  |             if(Graph[i][k]==false){cout<<"  ";}else{cout<<Square_str;} | ||||
|  |         } | ||||
|  |         cout<<Square_str<<endl<<Square_str; | ||||
|  |     } | ||||
|  |     for(i=1;i<=(Output_Width+1)*4+2;i++){cout<<Square_str;} | ||||
|  |     cout<<endl; | ||||
|  | } | ||||
|  | void Output_str(unsigned int Data){ | ||||
|  |     unsigned char i; | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x0){cout<<"0";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x1){cout<<"1";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x2){cout<<"2";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x3){cout<<"3";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x4){cout<<"4";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x5){cout<<"5";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x6){cout<<"6";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x7){cout<<"7";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x8){cout<<"8";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0x9){cout<<"9";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xA){cout<<"A";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xB){cout<<"B";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xC){cout<<"C";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xD){cout<<"D";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xE){cout<<"E";} | ||||
|  |         if((0x0F&Data>>(7-i)*4)==0xF){cout<<"F";} | ||||
|  |     } | ||||
|  | } | ||||
|  | unsigned int Input(char Data_str[8]){ | ||||
|  |     unsigned int i,Dat=0; | ||||
|  |     if((Data_str[0]=='e')&&(Data_str[1]=='x')&&(Data_str[2]=='i')&&(Data_str[3]=='t')){End=true;} | ||||
|  |     for(i=0;i<8;i++){ | ||||
|  |         if(Data_str[i]=='0'){Dat=Dat|(0x0<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='1'){Dat=Dat|(0x1<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='2'){Dat=Dat|(0x2<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='3'){Dat=Dat|(0x3<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='4'){Dat=Dat|(0x4<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='5'){Dat=Dat|(0x5<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='6'){Dat=Dat|(0x6<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='7'){Dat=Dat|(0x7<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='8'){Dat=Dat|(0x8<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='9'){Dat=Dat|(0x9<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='A'||Data_str[i]=='a'){Dat=Dat|(0xA<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='B'||Data_str[i]=='b'){Dat=Dat|(0xB<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='C'||Data_str[i]=='c'){Dat=Dat|(0xC<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='D'||Data_str[i]=='d'){Dat=Dat|(0xD<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='E'||Data_str[i]=='e'){Dat=Dat|(0xE<<(28-i*4));} | ||||
|  |         if(Data_str[i]=='F'||Data_str[i]=='f'){Dat=Dat|(0xF<<(28-i*4));} | ||||
|  |     } | ||||
|  |     return Dat; | ||||
|  | } | ||||
|  | 
 | ||||
| @ -0,0 +1,361 @@ | |||||
|  | #include "HRD_Calculate.h" | ||||
|  | using namespace std; | ||||
|  | void HRD_Calculate::Calculate(unsigned int Start_Code){ | ||||
|  | 	unsigned int i; | ||||
|  | 	for(i=0;i<0xFFFF;i++){Hash[i].clear();} | ||||
|  | 	List.clear(); | ||||
|  | 	Layer_Num.clear(); | ||||
|  | 	Hash[(Start_Code>>8)&0xFFFF].push_back(0); | ||||
|  | 	List.push_back(Start_Code); | ||||
|  | 	Layer_Num.push_back(0); | ||||
|  | 	Source.push_back(Empty_uint_List); | ||||
|  | 	Now_Move=0; | ||||
|  | 	while(1){ | ||||
|  | 		if(Now_Move==List.size()){break;} | ||||
|  | 		Analyse_Code(List[Now_Move]); | ||||
|  | 		Find_Next(); | ||||
|  | 		Now_Move++; | ||||
|  | 	} | ||||
|  | } | ||||
|  | void HRD_Calculate::Add_Case(unsigned int Code){ | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  | 	poi=Hash[(Code>>8)&0xFFFF].begin(); | ||||
|  | 	while(poi!=Hash[(Code>>8)&0xFFFF].end()){ | ||||
|  | 		if(Code==List[*poi]){ | ||||
|  |             if((Layer_Num[*poi]-Layer_Num[Now_Move])==1){Source[*poi].push_back(Now_Move);} | ||||
|  |             return; | ||||
|  |         } | ||||
|  | 		++poi; | ||||
|  | 	} | ||||
|  | 	Hash[(Code>>8)&0xFFFF].push_back(List.size()); | ||||
|  | 	List.push_back(Code); | ||||
|  | 	Layer_Num.push_back(Layer_Num[Now_Move]+1); | ||||
|  | 	Source.push_back(Empty_uint_List); | ||||
|  | 	Source[Source.size()-1].push_back(Now_Move); | ||||
|  | } | ||||
|  | void HRD_Calculate::Move_Block(unsigned char Block_Num,unsigned char Dir_1,unsigned char Dir_2){ | ||||
|  |     unsigned char Table_bak[21]; | ||||
|  | 	unsigned char i,addr; | ||||
|  | 	if(Dir_1==Up){Block[Block_Num].Address-=4;} | ||||
|  | 	else if(Dir_1==Down){Block[Block_Num].Address+=4;} | ||||
|  | 	else if(Dir_1==Left){Block[Block_Num].Address--;} | ||||
|  | 	else if(Dir_1==Right){Block[Block_Num].Address++;} | ||||
|  | 	if(Dir_2==Up){Block[Block_Num].Address-=4;} | ||||
|  | 	else if(Dir_2==Down){Block[Block_Num].Address+=4;} | ||||
|  | 	else if(Dir_2==Left){Block[Block_Num].Address--;} | ||||
|  | 	else if(Dir_2==Right){Block[Block_Num].Address++;} | ||||
|  | 	for(i=0;i<20;i++){Table_bak[i]=Table[i];Table[i]=0xA;} | ||||
|  | 	for(i=0;i<10;i++){ | ||||
|  | 		addr=Block[i].Address; | ||||
|  | 		if(Block[i].Style==0){Table[addr]=i;Table[addr+1]=i;Table[addr+4]=i;Table[addr+5]=i;} | ||||
|  | 		if(Block[i].Style==1){Table[addr]=i;Table[addr+1]=i;} | ||||
|  | 		if(Block[i].Style==2){Table[addr]=i;Table[addr+4]=i;} | ||||
|  | 		if(Block[i].Style==3){Table[addr]=i;} | ||||
|  | 	} | ||||
|  |     Add_Case(Get_Code()); | ||||
|  | 	for(i=0;i<20;i++){Table[i]=Table_bak[i];} | ||||
|  | 	if(Dir_2==Up){Block[Block_Num].Address+=4;} | ||||
|  | 	else if(Dir_2==Down){Block[Block_Num].Address-=4;} | ||||
|  | 	else if(Dir_2==Left){Block[Block_Num].Address++;} | ||||
|  | 	else if(Dir_2==Right){Block[Block_Num].Address--;} | ||||
|  | 	if(Dir_1==Up){Block[Block_Num].Address+=4;} | ||||
|  | 	else if(Dir_1==Down){Block[Block_Num].Address-=4;} | ||||
|  | 	else if(Dir_1==Left){Block[Block_Num].Address++;} | ||||
|  | 	else if(Dir_1==Right){Block[Block_Num].Address--;} | ||||
|  | } | ||||
|  | void HRD_Calculate::Find_Next(){ | ||||
|  |     bool Can_Move[10]; | ||||
|  |     unsigned char i,addr; | ||||
|  | 	for(i=0;i<10;i++){Can_Move[i]=false;} | ||||
|  | 	for(i=0;i<=1;i++){ | ||||
|  | 		addr=Space[i]; | ||||
|  | 		if(addr>3){if(Table[addr-4]!=0xA){Can_Move[Table[addr-4]]=true;}} | ||||
|  | 		if(addr<16){if(Table[addr+4]!=0xA){Can_Move[Table[addr+4]]=true;}} | ||||
|  | 		if((addr%4)!=0){if(Table[addr-1]!=0xA){Can_Move[Table[addr-1]]=true;}} | ||||
|  | 		if((addr%4)!=3){if(Table[addr+1]!=0xA){Can_Move[Table[addr+1]]=true;}} | ||||
|  | 	} | ||||
|  |     for(i=0;i<10;i++){ | ||||
|  |         if(Can_Move[i]==true){ | ||||
|  | 			addr=Block[i].Address; | ||||
|  | 			if(Block[i].Style==0){ | ||||
|  | 				if((addr>3)&&(Table[addr-4]==0xA)&&(Table[addr-3]==0xA)){Move_Block(i,Up,0);} | ||||
|  | 				if((addr<12)&&(Table[addr+8]==0xA)&&(Table[addr+9]==0xA)){Move_Block(i,Down,0);} | ||||
|  | 				if(((addr%4)!=0)&&(Table[addr-1]==0xA)&&(Table[addr+3]==0xA)){Move_Block(i,Left,0);} | ||||
|  | 				if(((addr%4)!=2)&&(Table[addr+2]==0xA)&&(Table[addr+6]==0xA)){Move_Block(i,Right,0);} | ||||
|  | 			} | ||||
|  | 			else if(Block[i].Style==1){ | ||||
|  | 				if((addr>3)&&(Table[addr-4]==0xA)&&(Table[addr-3]==0xA)){Move_Block(i,Up,0);} | ||||
|  | 				if((addr<16)&&(Table[addr+4]==0xA)&&(Table[addr+5]==0xA)){Move_Block(i,Down,0);} | ||||
|  | 				if(((addr%4)!=0)&&(Table[addr-1]==0xA)){ | ||||
|  | 					Move_Block(i,Left,0); | ||||
|  | 					if(((addr%4)!=1)&&(Table[addr-2]==0xA)){Move_Block(i,Left,Left);} | ||||
|  | 				} | ||||
|  | 				if(((addr%4)!=2)&&(Table[addr+2]==0xA)){ | ||||
|  | 					Move_Block(i,Right,0); | ||||
|  | 					if(((addr%4)!=1)&&(Table[addr+3]==0xA)){Move_Block(i,Right,Right);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  | 			else if(Block[i].Style==2){ | ||||
|  | 				if((addr>3)&&(Table[addr-4]==0xA)){ | ||||
|  | 					Move_Block(i,Up,0); | ||||
|  | 					if((addr>7)&&(Table[addr-8]==0xA)){Move_Block(i,Up,Up);} | ||||
|  | 				} | ||||
|  | 				if((addr<12)&&(Table[addr+8]==0xA)){ | ||||
|  | 					Move_Block(i,Down,0); | ||||
|  | 					if((addr<8)&&(Table[addr+12]==0xA)){Move_Block(i,Down,Down);} | ||||
|  | 				} | ||||
|  | 				if(((addr%4)!=0)&&(Table[addr-1]==0xA)&&(Table[addr+3]==0xA)){Move_Block(i,Left,0);} | ||||
|  | 				if(((addr%4)!=3)&&(Table[addr+1]==0xA)&&(Table[addr+5]==0xA)){Move_Block(i,Right,0);} | ||||
|  | 			} | ||||
|  | 			else if(Block[i].Style==3){ | ||||
|  | 				if((addr>3)&&(Table[addr-4]==0xA)){ | ||||
|  | 					Move_Block(i,Up,0); | ||||
|  | 					if((addr>7)&&(Table[addr-8]==0xA)){Move_Block(i,Up,Up);} | ||||
|  | 					if(((addr%4)!=0)&&(Table[addr-5]==0xA)){Move_Block(i,Up,Left);} | ||||
|  | 					if(((addr%4)!=3)&&(Table[addr-3]==0xA)){Move_Block(i,Up,Right);} | ||||
|  | 				} | ||||
|  | 				if((addr<16)&&(Table[addr+4]==0xA)){ | ||||
|  | 					Move_Block(i,Down,0); | ||||
|  | 					if((addr<12)&&(Table[addr+8]==0xA)){Move_Block(i,Down,Down);} | ||||
|  | 					if(((addr%4)!=0)&&(Table[addr+3]==0xA)){Move_Block(i,Down,Left);} | ||||
|  | 					if(((addr%4)!=3)&&(Table[addr+5]==0xA)){Move_Block(i,Down,Right);} | ||||
|  | 				} | ||||
|  | 				if(((addr%4)!=0)&&(Table[addr-1]==0xA)){ | ||||
|  | 					Move_Block(i,Left,0); | ||||
|  | 					if(((addr%4)!=1)&&(Table[addr-2]==0xA)){Move_Block(i,Left,Left);} | ||||
|  | 					if((addr>3)&&(Table[addr-5]==0xA)){Move_Block(i,Left,Up);} | ||||
|  | 					if((addr<16)&&(Table[addr+3]==0xA)){Move_Block(i,Left,Down);} | ||||
|  | 				} | ||||
|  | 				if(((addr%4)!=3)&&(Table[addr+1]==0xA)){ | ||||
|  | 					Move_Block(i,Right,0); | ||||
|  | 					if(((addr%4)!=2)&&(Table[addr+2]==0xA)){Move_Block(i,Right,Right);} | ||||
|  | 					if((addr>3)&&(Table[addr-3]==0xA)){Move_Block(i,Right,Up);} | ||||
|  | 					if((addr<16)&&(Table[addr+5]==0xA)){Move_Block(i,Right,Down);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | unsigned int HRD_Calculate::Get_Code(){ | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned int Code=0; | ||||
|  | 	unsigned char i,addr,style; | ||||
|  | 	for(i=0;i<20;i++){temp[i]=false;} | ||||
|  | 	temp[Block[0].Address]=temp[Block[0].Address+1]=temp[Block[0].Address+4]=temp[Block[0].Address+5]=true; | ||||
|  | 	Code=Code|(Block[0].Address<<24); | ||||
|  | 	addr=0; | ||||
|  | 	for(i=1;i<=11;i++){ | ||||
|  | 		while(temp[addr]==true){if(addr<19){addr++;}else{return 0;}} | ||||
|  | 		if(Table[addr]==0xA){temp[addr]=true;} | ||||
|  | 		else{ | ||||
|  | 			style=Block[Table[addr]].Style; | ||||
|  | 			if(style==1){ | ||||
|  | 				temp[addr]=temp[addr+1]=true; | ||||
|  | 				Code=Code|(1<<(24-i*2)); | ||||
|  | 			} | ||||
|  | 			else if(style==2){ | ||||
|  | 				temp[addr]=temp[addr+4]=true; | ||||
|  | 				Code=Code|(2<<(24-i*2)); | ||||
|  | 			} | ||||
|  | 			else if(style==3){ | ||||
|  | 				temp[addr]=true; | ||||
|  | 				Code=Code|(3<<(24-i*2)); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	return Code; | ||||
|  | } | ||||
|  | void HRD_Calculate::Analyse_Code(unsigned int Code){ | ||||
|  | 	unsigned char i,addr,style; | ||||
|  | 	unsigned char Type_1=0,Type_2=0,Type_3=5; | ||||
|  | 	for(i=0;i<20;i++){Table[i]=0xFF;} | ||||
|  | 	Block[0].Address=(Code>>24)&0xF; | ||||
|  | 	if(Block[0].Address>14){goto err;} | ||||
|  | 	Block[0].Style=0; | ||||
|  | 	Table[(Code>>24)&0xF]=0; | ||||
|  | 	Table[((Code>>24)&0xF)+1]=0; | ||||
|  | 	Table[((Code>>24)&0xF)+4]=0; | ||||
|  | 	Table[((Code>>24)&0xF)+5]=0; | ||||
|  | 	addr=0; | ||||
|  | 	for(i=0;i<11;i++){ | ||||
|  | 		while(Table[addr]!=0xFF){if(addr<19){addr++;}else{break;}} | ||||
|  | 		style=(Code>>(22-i*2))&0x3; | ||||
|  | 		if(style==0){ | ||||
|  | 			Table[addr]=0xA; | ||||
|  | 			Space[Type_1]=addr; | ||||
|  | 			if(Type_1==0){Type_1=1;} | ||||
|  | 		} | ||||
|  | 		if(style==1){ | ||||
|  | 			if(Type_2<5){Type_2++;} | ||||
|  | 			if(addr>18){goto err;} | ||||
|  | 			Table[addr]=Type_2; | ||||
|  | 			Table[addr+1]=Type_2; | ||||
|  | 			Block[Type_2].Address=addr; | ||||
|  | 			Block[Type_2].Style=1; | ||||
|  | 		} | ||||
|  | 		if(style==2){ | ||||
|  | 			if(Type_2<5){Type_2++;} | ||||
|  | 			if(addr>15){goto err;} | ||||
|  | 			Table[addr]=Type_2; | ||||
|  | 			Table[addr+4]=Type_2; | ||||
|  | 			Block[Type_2].Address=addr; | ||||
|  | 			Block[Type_2].Style=2; | ||||
|  | 		} | ||||
|  | 		if(style==3){ | ||||
|  | 			if(Type_3<9){Type_3++;} | ||||
|  | 			Table[addr]=Type_3; | ||||
|  | 			Block[Type_3].Address=addr; | ||||
|  | 			Block[Type_3].Style=3; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	err:; | ||||
|  | } | ||||
|  | bool HRD_Calculate::Check(unsigned int Code){ | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned char addr,i; | ||||
|  | 	unsigned char Style_0,Style_1,Style_2,Style_3; | ||||
|  | 	Style_0=Style_1=Style_2=Style_3=0; | ||||
|  | 	Analyse_Code(Code); | ||||
|  | 	for(i=0;i<20;i++){temp[i]=false;} | ||||
|  | 	for(i=0;i<20;i++){if(Table[i]>10){return false;}} | ||||
|  | 	if(Space[0]>19){return false;}else{if(temp[Space[0]]==true){return false;}else{temp[Space[0]]=true;}} | ||||
|  | 	if(Space[1]>19){return false;}else{if(temp[Space[1]]==true){return false;}else{temp[Space[1]]=true;}} | ||||
|  | 	for(i=0;i<=9;i++){ | ||||
|  | 		addr=Block[i].Address; | ||||
|  | 		if(Block[i].Style==0){ | ||||
|  | 			Style_0++; | ||||
|  | 			if(addr>14){return false;} | ||||
|  | 			if((addr%4)==3){return false;} | ||||
|  | 			if(temp[addr]==true||temp[addr+1]==true||temp[addr+4]==true||temp[addr+5]==true){return false;} | ||||
|  | 			temp[addr]=true; | ||||
|  | 			temp[addr+1]=true; | ||||
|  | 			temp[addr+4]=true; | ||||
|  | 			temp[addr+5]=true; | ||||
|  | 		} | ||||
|  | 		if(Block[i].Style==1){ | ||||
|  | 			Style_1++; | ||||
|  | 			if(addr>18){return false;} | ||||
|  | 			if((addr%4)==3){return false;} | ||||
|  | 			if(temp[addr]==true||temp[addr+1]==true){return false;} | ||||
|  | 			temp[addr]=true; | ||||
|  | 			temp[addr+1]=true; | ||||
|  | 		} | ||||
|  | 		if(Block[i].Style==2){ | ||||
|  | 			Style_2++; | ||||
|  | 			if(addr>15){return false;} | ||||
|  | 			if(temp[addr]==true||temp[addr+4]==true){return false;} | ||||
|  | 			temp[addr]=true; | ||||
|  | 			temp[addr+4]=true; | ||||
|  | 		} | ||||
|  | 		if(Block[i].Style==3){ | ||||
|  | 			Style_3++; | ||||
|  | 			if(addr>19){return false;} | ||||
|  | 			if(temp[addr]==true){return false;} | ||||
|  | 			temp[addr]=true; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	if(Style_0!=1){return false;} | ||||
|  | 	if((Style_1+Style_2)!=5){return false;} | ||||
|  | 	if(Style_3!=4){return false;} | ||||
|  | 	if(Block[0].Style!=0){return false;} | ||||
|  | 	if(Table[Block[0].Address]!=0){return false;} | ||||
|  | 	if(Table[Block[0].Address+1]!=0){return false;} | ||||
|  | 	if(Table[Block[0].Address+4]!=0){return false;} | ||||
|  | 	if(Table[Block[0].Address+5]!=0){return false;} | ||||
|  | 	for(i=1;i<=5;i++){ | ||||
|  | 		if(Block[i].Style==1){ | ||||
|  | 			if(Table[Block[i].Address]!=i){return false;} | ||||
|  | 			if(Table[Block[i].Address+1]!=i){return false;} | ||||
|  | 		} | ||||
|  | 		else if(Block[i].Style==2){ | ||||
|  | 			if(Table[Block[i].Address]!=i){return false;} | ||||
|  | 			if(Table[Block[i].Address+4]!=i){return false;} | ||||
|  | 		} | ||||
|  | 		else{return false;} | ||||
|  | 	} | ||||
|  | 	for(i=6;i<=9;i++){ | ||||
|  | 		if(Table[Block[i].Address]!=i){return false;} | ||||
|  | 		if(Block[i].Style!=3){return false;} | ||||
|  | 	} | ||||
|  | 	if(Table[Space[0]]!=0xA){return false;} | ||||
|  | 	if(Table[Space[1]]!=0xA){return false;} | ||||
|  | 	return true; | ||||
|  | } | ||||
|  | void HRD_Calculate::Output_Graph(unsigned int Code){ | ||||
|  | 	unsigned int i,k,m; | ||||
|  | 	unsigned int Start_x,Start_y,End_x,End_y; | ||||
|  | 	bool Graph[(Output_Width+1)*4+1][(Output_Width+1)*5+1]; | ||||
|  | 	if(Check(Code)==false){cout<<"The Code is Wrong!"<<endl;return;} | ||||
|  | 	Analyse_Code(Code); | ||||
|  | 	for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  | 		for(i=0;i<=(Output_Width+1)*4;i++){Graph[i][k]=false;} | ||||
|  | 	} | ||||
|  | 	for(m=0;m<=9;m++){ | ||||
|  | 		Start_x=(Block[m].Address%4)*(Output_Width+1)+1; | ||||
|  | 		Start_y=Block[m].Address/4; | ||||
|  | 		Start_y=Start_y*(Output_Width+1)+1; | ||||
|  | 		if((Block[m].Style==1)||(Block[m].Style==0)){End_x=Start_x+Output_Width*2;} | ||||
|  | 		else{End_x=Start_x+Output_Width-1;} | ||||
|  | 		if((Block[m].Style==2)||(Block[m].Style==0)){End_y=Start_y+Output_Width*2;} | ||||
|  | 		else{End_y=Start_y+Output_Width-1;} | ||||
|  | 		for(i=Start_x;i<=End_x;i++){ | ||||
|  | 			for(k=Start_y;k<=End_y;k++){Graph[i][k]=true;} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	for(i=1;i<=(Output_Width+1)*4+3;i++){cout<<Square_str;} | ||||
|  | 	cout<<endl<<Square_str; | ||||
|  | 	for(k=0;k<=(Output_Width+1)*5;k++){ | ||||
|  | 		for(i=0;i<=(Output_Width+1)*4;i++){ | ||||
|  | 			if(Graph[i][k]==false){cout<<"  ";}else{cout<<Square_str;} | ||||
|  | 		} | ||||
|  | 		cout<<Square_str<<endl<<Square_str; | ||||
|  | 	} | ||||
|  | 	for(i=1;i<=(Output_Width+1)*4+2;i++){cout<<Square_str;} | ||||
|  | 	cout<<endl; | ||||
|  | } | ||||
|  | unsigned int HRD_Calculate::Change_int(char Data_str[7]){ | ||||
|  | 	unsigned int i,Dat=0; | ||||
|  | 	for(i=0;i<7;i++){ | ||||
|  | 		if(Data_str[i]=='0'){Dat=Dat|(0x0<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='1'){Dat=Dat|(0x1<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='2'){Dat=Dat|(0x2<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='3'){Dat=Dat|(0x3<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='4'){Dat=Dat|(0x4<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='5'){Dat=Dat|(0x5<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='6'){Dat=Dat|(0x6<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='7'){Dat=Dat|(0x7<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='8'){Dat=Dat|(0x8<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='9'){Dat=Dat|(0x9<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='A'||Data_str[i]=='a'){Dat=Dat|(0xA<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='B'||Data_str[i]=='b'){Dat=Dat|(0xB<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='C'||Data_str[i]=='c'){Dat=Dat|(0xC<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='D'||Data_str[i]=='d'){Dat=Dat|(0xD<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='E'||Data_str[i]=='e'){Dat=Dat|(0xE<<(24-i*4));} | ||||
|  | 		if(Data_str[i]=='F'||Data_str[i]=='f'){Dat=Dat|(0xF<<(24-i*4));} | ||||
|  | 	} | ||||
|  | 	return Dat; | ||||
|  | } | ||||
|  | string HRD_Calculate::Change_str(unsigned int Data_int){ | ||||
|  | 	unsigned char i,bit; | ||||
|  | 	string Dat=""; | ||||
|  | 	for(i=0;i<7;i++){ | ||||
|  | 		bit=(0xF&Data_int>>(6-i)*4); | ||||
|  | 		if(bit==0x0){Dat+='0';} | ||||
|  | 		if(bit==0x1){Dat+='1';} | ||||
|  | 		if(bit==0x2){Dat+='2';} | ||||
|  | 		if(bit==0x3){Dat+='3';} | ||||
|  | 		if(bit==0x4){Dat+='4';} | ||||
|  | 		if(bit==0x5){Dat+='5';} | ||||
|  | 		if(bit==0x6){Dat+='6';} | ||||
|  | 		if(bit==0x7){Dat+='7';} | ||||
|  | 		if(bit==0x8){Dat+='8';} | ||||
|  | 		if(bit==0x9){Dat+='9';} | ||||
|  | 		if(bit==0xA){Dat+='A';} | ||||
|  | 		if(bit==0xB){Dat+='B';} | ||||
|  | 		if(bit==0xC){Dat+='C';} | ||||
|  | 		if(bit==0xD){Dat+='D';} | ||||
|  | 		if(bit==0xE){Dat+='E';} | ||||
|  | 		if(bit==0xF){Dat+='F';} | ||||
|  | 	} | ||||
|  | 	return Dat; | ||||
|  | } | ||||
| @ -0,0 +1,41 @@ | |||||
|  | #ifndef HRD_H | ||||
|  | #define HRD_H | ||||
|  | 
 | ||||
|  | #include<iostream> | ||||
|  | #include<vector> | ||||
|  | #include<list> | ||||
|  | #include<string> | ||||
|  | using namespace std; | ||||
|  | 
 | ||||
|  | class HRD_Calculate{ | ||||
|  | 	public: | ||||
|  |     struct Block_struct{ | ||||
|  |         unsigned char Address; | ||||
|  |         unsigned char Style; | ||||
|  |     }; | ||||
|  |     unsigned char Table[20];//num:Block  0xA:Space  0xFF:Empty
 | ||||
|  |     unsigned char Space[2]; | ||||
|  |     struct Block_struct Block[10];//0:2*2  1~5:1*2,2*1  6~9:1*1
 | ||||
|  |     const unsigned char Output_Width=4; | ||||
|  |     const string Square_str="[]"; | ||||
|  |     const unsigned char Up=1,Down=2,Left=3,Right=4; | ||||
|  |     vector <unsigned int> List; | ||||
|  |     vector <unsigned int> Layer_Num; | ||||
|  |     list <unsigned int> Hash[0xFFFF]; | ||||
|  |     vector< list <unsigned int> > Source; | ||||
|  |     list <unsigned int> Empty_uint_List; | ||||
|  |     unsigned int Now_Move; | ||||
|  | 
 | ||||
|  |     void Calculate(unsigned int Start_Code); | ||||
|  |     void Add_Case(unsigned int Code); | ||||
|  |     void Move_Block(unsigned char Block_Num,unsigned char Dir_1,unsigned char Dir_2); | ||||
|  |     void Find_Next(); | ||||
|  |     unsigned int Get_Code(); | ||||
|  |     void Analyse_Code(unsigned int Code); | ||||
|  |     bool Check(unsigned int Code); | ||||
|  |     void Output_Graph(unsigned int Code); | ||||
|  |     unsigned int Change_int(char Data_str[7]); | ||||
|  | 	string Change_str(unsigned int Data_int); | ||||
|  | }; | ||||
|  | 
 | ||||
|  | #endif | ||||
| @ -0,0 +1,25 @@ | |||||
|  | #include<iostream> | ||||
|  | #include<list> | ||||
|  | #include<string> | ||||
|  | #include<fstream> | ||||
|  | #include "HRD_Calculate.h" | ||||
|  | using namespace std; | ||||
|  | 
 | ||||
|  | ifstream File_Input; | ||||
|  | ofstream File_Output; | ||||
|  | 
 | ||||
|  | int main(){ | ||||
|  | 	cout<<"This is a test of HRD_Calculate"<<endl; | ||||
|  | 	HRD_Calculate HRD; | ||||
|  | 	HRD.Calculate(0x1A9BF0C); | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     File_Output.open("Data_Output.txt"); | ||||
|  |     for(unsigned int i=0;i<HRD.List.size();i++){ | ||||
|  |         File_Output<<i<<" -> "<<HRD.Change_str(HRD.List[i])<<" ("<<HRD.Layer_Num[i]<<")"; | ||||
|  |         poi=HRD.Source[i].begin(); | ||||
|  |         while(poi!=HRD.Source[i].end()){File_Output<<"  ["<<*poi<<"]";++poi;} | ||||
|  |         File_Output<<endl; | ||||
|  |     } | ||||
|  |     File_Output.close(); | ||||
|  | 	return 0; | ||||
|  | } | ||||
| @ -0,0 +1,608 @@ | |||||
|  | #include <iostream> | ||||
|  | #include <vector> | ||||
|  | #include <string> | ||||
|  | #include <list> | ||||
|  | #include <fstream> | ||||
|  | using namespace std; | ||||
|  | 
 | ||||
|  | ifstream File_Input; | ||||
|  | ofstream File_Output; | ||||
|  | const unsigned char Up = 1, Down = 2, Left = 3, Right = 4; | ||||
|  | 
 | ||||
|  | struct block_struct { | ||||
|  | 	unsigned char address;  //0~19
 | ||||
|  | 	unsigned char style;  //0:2*2  1:2*1  2:1*2  3:1*1
 | ||||
|  | }; | ||||
|  | unsigned char table[20];  //0~9:block[?]  0xA:space  0xFF:empty
 | ||||
|  | unsigned char space[2];  //space[0~1]的位置
 | ||||
|  | struct block_struct block[10];  //0:2*2  1~5:1*2,2*1  6~9:1*1
 | ||||
|  | 
 | ||||
|  | list <unsigned int> int_list;  //空列表 给Source用
 | ||||
|  | list <unsigned int> Hash[0x10000];  //哈希索引表
 | ||||
|  | unsigned int Now_Move;  //目前正在进行计算的布局编号
 | ||||
|  | 
 | ||||
|  | vector <unsigned int> List;  //所有情况的队列
 | ||||
|  | vector <unsigned int> Layer_Num;  //所在层的编号
 | ||||
|  | vector <list <unsigned int> > Source;  //父布局编号
 | ||||
|  | 
 | ||||
|  | int group_size;  //整个队列组的大小
 | ||||
|  | int min_steps;  //距离解的最少步骤
 | ||||
|  | int farthest_steps;  //到达最远布局的步数
 | ||||
|  | vector <unsigned int> Solutions;  //所有解
 | ||||
|  | vector <unsigned int> min_Solutions;  //所有最少步解
 | ||||
|  | vector <unsigned int> Solutions_path;  //最少步解法
 | ||||
|  | vector <unsigned int> farthest_cases;  //最远的布局解法
 | ||||
|  | 
 | ||||
|  | int target_steps;  //到达目标布局的最少步骤
 | ||||
|  | vector <unsigned int> target_path;  //到达目标布局的最少步解法
 | ||||
|  | vector <vector <unsigned int> > target_data;  //target_data[Layer_num][num]
 | ||||
|  | vector <vector <unsigned int> > target_source;  //target_source[next_index]
 | ||||
|  | 
 | ||||
|  | vector <unsigned int> all_data;  //所有布局的编码
 | ||||
|  | vector <vector <unsigned int> > style_data;  //style_0 ~ style_5下的所有编码
 | ||||
|  | vector <vector <vector <unsigned int> > > group_data;  //group[style][grout_index]下的所有编码
 | ||||
|  | 
 | ||||
|  | void debug(); | ||||
|  | void Find_All_Case(); | ||||
|  | void Data_Output(); | ||||
|  | unsigned int Change_int (char str[8]); | ||||
|  | string Change_str (unsigned int dat); | ||||
|  | void Output_Graph (unsigned int Code); | ||||
|  | void Analyse_Code (unsigned int Code); | ||||
|  | void Add_Case (unsigned int Code); | ||||
|  | void Calculate (unsigned int Start_Code); | ||||
|  | bool Check (unsigned int Code); | ||||
|  | unsigned int Get_Code(); | ||||
|  | void Find_Next(); | ||||
|  | bool Check_Empty (unsigned char address,unsigned char dir,unsigned char num); | ||||
|  | void Move_Block (unsigned char num,unsigned char dir_1,unsigned char dir_2); | ||||
|  | void Fill_Block (unsigned char addr, unsigned char style, unsigned char filler); | ||||
|  | vector <unsigned int> Search_Path (unsigned int target_num); | ||||
|  | void Analyse_Case (unsigned int Start_Code); | ||||
|  | void Analyse_target (unsigned int target); | ||||
|  | 
 | ||||
|  | int main(){ | ||||
|  | 	Analyse_Case(0x4FEA134); | ||||
|  | 	Analyse_target(0x4F2E9C4); | ||||
|  | 	return 0; | ||||
|  | 
 | ||||
|  | 	cout<<"Welcome to HRD-Calculator by Dnomd343"<<endl; | ||||
|  | 	cout<<"Please Input the Code:"; | ||||
|  | } | ||||
|  | 
 | ||||
|  | vector <unsigned int> Search_Path (unsigned int target_num) {  //搜索到达目标布局的一条最短路径 返回vector类
 | ||||
|  | 	vector <unsigned int> path; | ||||
|  | 	int temp = -1; | ||||
|  | 	path.push_back(target_num);  //路径中加入目标布局
 | ||||
|  | 	while (temp != 0) { | ||||
|  | 		temp = path[path.size() - 1]; | ||||
|  | 		path.push_back(*Source[temp].begin()); | ||||
|  | 	} | ||||
|  | 	path.pop_back();  //去掉重复的根布局
 | ||||
|  | 	temp = path.size() / 2;  //反置整个路径
 | ||||
|  | 	for (int i = 0; i < temp; i++) { | ||||
|  | 		swap(path[i], path[path.size() - i - 1]); | ||||
|  | 	} | ||||
|  | 	for (int  i = 0; i < path.size(); i++){  //将序号改成布局的编码
 | ||||
|  | 		path[i] = List[path[i]]; | ||||
|  | 	} | ||||
|  | 	return path; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Analyse_target (unsigned int target) { | ||||
|  | 	bool get_it = false; | ||||
|  | 	unsigned int temp, target_num; | ||||
|  | 	list <unsigned int>::iterator poi; | ||||
|  | 	target_steps = -1; | ||||
|  | 	target_path.clear(); | ||||
|  | 	web_target.clear(); | ||||
|  | 	web_target_source.clear(); | ||||
|  | 	for (int i = 0; i < List.size(); i++){  //搜索target的编号到target_num
 | ||||
|  | 		if (List[i] == target){ | ||||
|  | 			get_it = true; | ||||
|  | 			target_num = i; | ||||
|  | 			target_steps = Layer_Num[i]; | ||||
|  | 			break; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	if (get_it == false) {return;}  //找不到这个target 退出
 | ||||
|  | 	target_path = Search_Path(target_num); | ||||
|  | 
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Analyse_Case (unsigned int Start_Code) {  //对一个布局进行分析
 | ||||
|  | 	unsigned int i, first_solution; | ||||
|  | 	bool get_it = false; | ||||
|  | 	if (Check(Start_Code) == false) {return;} | ||||
|  | 	Calculate(Start_Code);  //通过计算建立队列表
 | ||||
|  | 	min_steps = -1; | ||||
|  | 	farthest_steps = -1; | ||||
|  | 	group_size=List.size(); | ||||
|  | 	Solutions.clear(); | ||||
|  | 	min_Solutions.clear(); | ||||
|  | 	farthest_cases.clear(); | ||||
|  | 	Solutions_path.clear(); | ||||
|  | 
 | ||||
|  | 	for (i = 0; i < List.size(); i++) {  //遍历队列中所有元素
 | ||||
|  | 		Analyse_Code(List[i]); | ||||
|  | 		if (block[0].address == 13) {  //若当前布局为有效解
 | ||||
|  | 			if (get_it == false){ | ||||
|  | 				min_steps = Layer_Num[i];  //第一个找到的解为最少步解
 | ||||
|  | 				first_solution = i; | ||||
|  | 				get_it = true; | ||||
|  | 			} | ||||
|  | 			Solutions.push_back(List[i]); | ||||
|  | 			if (Layer_Num[i] == min_steps) { | ||||
|  | 				min_Solutions.push_back(List[i]); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	farthest_steps=Layer_Num[Layer_Num.size()-1];  //计算最远布局的步数
 | ||||
|  | 	for (i = Layer_Num.size() - 1; i > 0; i--) {  //找到所有最远的布局
 | ||||
|  | 		if(Layer_Num[i] != farthest_steps) {break;} | ||||
|  | 		farthest_cases.push_back(List[i]); | ||||
|  | 	} | ||||
|  | 	if (min_steps != -1) {Solutions_path = Search_Path(first_solution);} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Calculate (unsigned int Start_Code) {  //启动计算引擎
 | ||||
|  | 	unsigned int i; | ||||
|  | 	for (i = 0; i <= 0xFFFF; i++) {Hash[i].clear();}  //初始化
 | ||||
|  | 	List.clear(); | ||||
|  | 	Layer_Num.clear(); | ||||
|  | 	Source.clear(); | ||||
|  | 
 | ||||
|  | 	Hash[(Start_Code>>4) & 0xFFFF].push_back(0);  //加入初始布局
 | ||||
|  | 	List.push_back(Start_Code); | ||||
|  | 	Layer_Num.push_back(0); | ||||
|  | 	Source.push_back(int_list); | ||||
|  | 	Now_Move = 0;  //搜索目标指向根节点
 | ||||
|  | 	while (Now_Move != List.size()) {  //进行广度优先搜索
 | ||||
|  | 		Analyse_Code(List[Now_Move]);  //解析目标布局
 | ||||
|  | 		Find_Next();  //根据解析结果搜索所有子布局
 | ||||
|  | 		Now_Move++; | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Add_Case (unsigned int Code) {  //将计算结果加入队列
 | ||||
|  |     list <unsigned int>::iterator poi;  //定义迭代器
 | ||||
|  | 	poi = Hash[(Code>>4) & 0xFFFF].begin();  //设置poi为索引表的起始点
 | ||||
|  | 	while (poi != Hash[(Code>>4) & 0xFFFF].end()) {  //遍历索引表
 | ||||
|  | 		if (Code == List[*poi]) {  //若发现重复
 | ||||
|  |             if ((Layer_Num[*poi] - Layer_Num[Now_Move]) == 1) {  //若高一层
 | ||||
|  | 				Source[*poi].push_back(Now_Move);  //加入父节点列表
 | ||||
|  | 			} | ||||
|  |             return;  //重复 退出
 | ||||
|  |         } | ||||
|  | 		++poi; | ||||
|  | 	} | ||||
|  | 	Hash[(Code>>4) & 0xFFFF].push_back(List.size());  //将计算结果添加至索引表
 | ||||
|  | 	List.push_back(Code);  //将计算结果加入队列
 | ||||
|  | 	Layer_Num.push_back(Layer_Num[Now_Move] + 1);  //添加对应的层数
 | ||||
|  | 	Source.push_back(int_list);  //初始化其父节点列表
 | ||||
|  | 	Source[Source.size()-1].push_back(Now_Move);  //将正在进行搜索的布局添加为父节点
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Fill_Block (unsigned char addr, unsigned char style, unsigned char filler) {  //用指定内容填充table中指定的位置
 | ||||
|  | 	if (style == 0) {table[addr] = table[addr + 1] = table[addr + 4] = table[addr + 5] = filler;}  //2*2
 | ||||
|  | 	else if (style == 1) {table[addr] = table[addr + 1] = filler;}  //2*1
 | ||||
|  | 	else if (style == 2) {table[addr] = table[addr + 4] = filler;}  //1*2
 | ||||
|  | 	else if (style == 3) {table[addr] = filler;}  //1*1
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Move_Block (unsigned char num, unsigned char dir_1, unsigned char dir_2) {  //按要求移动块并将移动后的编码传给Add_Case
 | ||||
|  | 	unsigned char i, addr, addr_bak; | ||||
|  | 	addr = block[num].address; | ||||
|  | 	addr_bak = addr; | ||||
|  | 
 | ||||
|  | 	if (dir_1 == Up) {addr -= 4;}  //第一次移动
 | ||||
|  | 	else if (dir_1==Down) {addr += 4;} | ||||
|  | 	else if (dir_1==Left) {addr--;} | ||||
|  | 	else if (dir_1==Right) {addr++;} | ||||
|  | 	if (dir_2 == Up) {addr -= 4;}  //第二次移动
 | ||||
|  | 	else if (dir_2 == Down) {addr += 4;} | ||||
|  | 	else if (dir_2 == Left) {addr--;} | ||||
|  | 	else if (dir_2 == Right) {addr++;} | ||||
|  | 
 | ||||
|  | 	Fill_Block(addr_bak, block[num].style, 0xA);  //修改 table为移动后的状态
 | ||||
|  | 	Fill_Block(addr, block[num].style, num); | ||||
|  | 	block[num].address = addr; | ||||
|  | 
 | ||||
|  | 	Add_Case(Get_Code());  //生成编码并赋予Add_Case
 | ||||
|  | 
 | ||||
|  | 	block[num].address = addr_bak; | ||||
|  | 	Fill_Block(addr, block[num].style, 0xA);  //还原 table原来的状态
 | ||||
|  | 	Fill_Block(addr_bak, block[num].style, num); | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Find_Next() {  //寻找所有移动的方式并提交给Move_Block
 | ||||
|  | 	bool Can_Move[10]; | ||||
|  |     unsigned char i, addr; | ||||
|  | 	for (i = 0; i < 10; i++) {Can_Move[i] = false;} | ||||
|  | 	for (i = 0; i <= 1; i++) {  //寻找位于空格周围的所有块
 | ||||
|  | 		addr = space[i]; | ||||
|  | 		if (addr > 3) | ||||
|  | 			if (table[addr - 4] != 0xA) {Can_Move[table[addr - 4]] = true;} | ||||
|  | 		if (addr < 16) | ||||
|  | 			if (table[addr + 4] != 0xA) {Can_Move[table[addr + 4]] = true;} | ||||
|  | 		if (addr % 4 != 0) | ||||
|  | 			if (table[addr - 1] != 0xA) {Can_Move[table[addr - 1]] = true;} | ||||
|  | 		if (addr % 4 != 3) { | ||||
|  | 			if (table[addr + 1] != 0xA) {Can_Move[table[addr + 1]] = true;}} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (i = 0; i <= 9; i++) { | ||||
|  | 		if (Can_Move[i] == true) {  //若该块可能可以移动
 | ||||
|  | 			addr = block[i].address; | ||||
|  | 			if (block[i].style == 0) {  //2*2
 | ||||
|  | 				if ((Check_Empty(addr, Up, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1,Up, 1) == true)) {Move_Block(i, Up, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Down, 2) == true) && | ||||
|  | 					(Check_Empty(addr + 1,Down, 2) == true)) {Move_Block(i, Down, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Left, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Right, 2) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Right, 2) == true)) {Move_Block(i, Right, 0);} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 1) {  //2*1
 | ||||
|  | 				if ((Check_Empty(addr, Up, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1, Up, 1) == true)) {Move_Block(i, Up, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Down, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1, Down, 1) == true)) {Move_Block(i, Down, 0);} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Left, 1) == true) { | ||||
|  | 					Move_Block(i, Left, 0); | ||||
|  | 					if (Check_Empty(addr, Left, 2) == true) {Move_Block(i, Left, Left);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Right, 2) == true) { | ||||
|  | 					Move_Block(i, Right, 0); | ||||
|  | 					if (Check_Empty(addr, Right, 3) == true) {Move_Block(i, Right, Right);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 2) {  //1*2
 | ||||
|  | 				if (Check_Empty(addr, Up, 1) == true) { | ||||
|  | 					Move_Block(i, Up, 0); | ||||
|  | 					if (Check_Empty(addr, Up, 2) == true) {Move_Block(i, Up, Up);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Down, 2) == true) { | ||||
|  | 					Move_Block(i, Down, 0); | ||||
|  | 					if (Check_Empty(addr, Down, 3) == true) {Move_Block(i, Down, Down);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Left, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Right, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Right, 1) == true)) {Move_Block(i, Right, 0);} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 3) {  //1*1
 | ||||
|  | 				if (Check_Empty(addr, Up, 1) == true) { | ||||
|  | 					Move_Block(i, Up, 0); | ||||
|  | 					if (Check_Empty(addr - 4, Up, 1) == true) {Move_Block(i, Up, Up);} | ||||
|  | 					if (Check_Empty(addr - 4, Left, 1) == true) {Move_Block(i, Up, Left);} | ||||
|  | 					if (Check_Empty(addr - 4, Right, 1) == true) {Move_Block(i, Up, Right);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Down, 1) == true) { | ||||
|  | 					Move_Block(i, Down, 0); | ||||
|  | 					if (Check_Empty(addr + 4, Down, 1) == true) {Move_Block(i, Down, Down);} | ||||
|  | 					if (Check_Empty(addr + 4, Left, 1) == true) {Move_Block(i, Down, Left);} | ||||
|  | 					if (Check_Empty(addr + 4, Right, 1) == true) {Move_Block(i, Down, Right);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Left, 1) == true) { | ||||
|  | 					Move_Block(i, Left, 0); | ||||
|  | 					if (Check_Empty(addr - 1, Up, 1) == true) {Move_Block(i, Left, Up);} | ||||
|  | 					if (Check_Empty(addr - 1, Down, 1) == true) {Move_Block(i, Left, Down);} | ||||
|  | 					if (Check_Empty(addr - 1, Left, 1) == true) {Move_Block(i, Left, Left);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Right, 1) == true) { | ||||
|  | 					Move_Block(i, Right, 0); | ||||
|  | 					if (Check_Empty(addr + 1, Up, 1) == true) {Move_Block(i, Right, Up);} | ||||
|  | 					if (Check_Empty(addr + 1, Down, 1) == true) {Move_Block(i, Right, Down);} | ||||
|  | 					if (Check_Empty(addr + 1, Right, 1) == true) {Move_Block(i, Right, Right);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | bool Check_Empty (unsigned char address, unsigned char dir, unsigned char num) {  //判断指定位置是否为空格 若不是空格或者无效返回false
 | ||||
|  | 	unsigned char x, y, addr; | ||||
|  | 	if (address > 19) {return false;}  //输入位置不存在
 | ||||
|  | 
 | ||||
|  | 	x = address % 4; | ||||
|  | 	y = (address - x) / 4; | ||||
|  | 	if (dir == Up) {  //上方
 | ||||
|  | 		if (y < num) {return false;} | ||||
|  | 		addr = address - num * 4; | ||||
|  | 	} | ||||
|  | 	if (dir == Down) {  //下方
 | ||||
|  | 		if (y + num > 4) {return false;} | ||||
|  | 		addr = address + num * 4; | ||||
|  | 	} | ||||
|  | 	if (dir == Left) {  //左侧
 | ||||
|  | 		if (x < num) {return false;} | ||||
|  | 		addr = address - num; | ||||
|  | 	} | ||||
|  | 	if (dir == Right) {  //右侧
 | ||||
|  | 		if(x + num > 3){return false;} | ||||
|  | 		addr = address + num; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (table[addr] == 0xA) { | ||||
|  | 		return true; | ||||
|  | 	} else { | ||||
|  | 		return false; | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | unsigned int Get_Code() {  //生成编码
 | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned int Code = 0; | ||||
|  | 	unsigned char i, addr, style; | ||||
|  | 
 | ||||
|  | 	for (i = 0; i < 20; i++) {temp[i] = false;}  //初始化
 | ||||
|  | 	temp[block[0].address] = temp[block[0].address + 1] = | ||||
|  | 		temp[block[0].address + 4] = temp[block[0].address + 5] = true; | ||||
|  | 
 | ||||
|  | 	Code |= block[0].address<<24;  //2*2块的位置
 | ||||
|  | 	addr = 0; | ||||
|  | 	for (i = 1; i <= 11; i++) { | ||||
|  | 		while(temp[addr] == true){  //找到下一个未填充的空格
 | ||||
|  | 			if (addr < 19) { | ||||
|  | 				addr++; | ||||
|  | 			} else { | ||||
|  | 				return 0; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		if (table[addr] == 0xA) {  //空格
 | ||||
|  | 			temp[addr] = true; | ||||
|  | 		} else { | ||||
|  | 			style = block[table[addr]].style; | ||||
|  | 			if (style == 1) {  //2*1
 | ||||
|  | 				temp[addr] = temp[addr + 1] = true; | ||||
|  | 				Code |= 1<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 			else if (style == 2) {  //1*2
 | ||||
|  | 				temp[addr] = temp[addr + 4] = true; | ||||
|  | 				Code |= 2<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 			else if (style == 3) {  //1*1
 | ||||
|  | 				temp[addr] = true; | ||||
|  | 				Code |= 3<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	return Code; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Analyse_Code (unsigned int Code) {  //解译编码到 table[20] block[10] space[2]中
 | ||||
|  | 	unsigned char i, addr, style; | ||||
|  | 	unsigned char num_space = 0, num_type_1 = 0, num_type_2 = 5; | ||||
|  | 	space[0] = space[1] = 0xFF;  //初始化
 | ||||
|  | 	for (i = 0; i < 20; i++) {table[i] = 0xFF;} | ||||
|  | 	for (i = 0; i <= 9; i++) { | ||||
|  | 		block[i].address = 0xFF; | ||||
|  | 		block[i].style = 0xFF; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	block[0].address = 0xF & (Code>>24);  //开始解译
 | ||||
|  | 	if (block[0].address > 14) {goto err;}  //2*2块越界 退出
 | ||||
|  | 	block[0].style = 0;  //设置2*2块的参数
 | ||||
|  | 	Fill_Block(block[0].address, 0, 0x0); | ||||
|  | 	addr = 0; | ||||
|  | 	for (i = 0; i < 11; i++) {  //遍历 10个块
 | ||||
|  | 		while (table[addr] != 0xFF){  //向下搜索空块
 | ||||
|  | 			if (addr < 19) { | ||||
|  | 				addr++; | ||||
|  | 			} else { | ||||
|  | 				break; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		style = 0x3 & (Code>>(22 - i * 2));  //0:space  1:2*1  2:1*2  3:1*1
 | ||||
|  | 		if (style == 0) {  //space
 | ||||
|  | 			table[addr] = 0xA; | ||||
|  | 			space[num_space] = addr; | ||||
|  | 			if (num_space == 0) {num_space++;} | ||||
|  | 		} | ||||
|  | 		if (style == 1) {  //2*1
 | ||||
|  | 			if (num_type_1 < 5) {num_type_1++;} | ||||
|  | 			if (addr > 18) {goto err;}  //2*1块越界
 | ||||
|  | 			block[num_type_1].style = 1; | ||||
|  | 			block[num_type_1].address = addr; | ||||
|  | 			table[addr] = table[addr + 1] = num_type_1; | ||||
|  | 		} | ||||
|  | 		if (style == 2) {  //1*2
 | ||||
|  | 			if (num_type_1 < 5) {num_type_1++;} | ||||
|  | 			if (addr > 15) {goto err;}  //1*2块越界
 | ||||
|  | 			block[num_type_1].style = 2; | ||||
|  | 			block[num_type_1].address = addr; | ||||
|  | 			table[addr] = table[addr + 4] = num_type_1; | ||||
|  | 		} | ||||
|  | 		if (style == 3) {  //1*1
 | ||||
|  | 			if (num_type_2 < 9) {num_type_2++;} | ||||
|  | 			block[num_type_2].style = 3; | ||||
|  | 			block[num_type_2].address = addr; | ||||
|  | 			table[addr] = num_type_2; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	err:; | ||||
|  | } | ||||
|  | 
 | ||||
|  | bool Check (unsigned int Code) {  //检查编码是否合法 正确返回true 错误返回false
 | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned char addr, i; | ||||
|  | 	Analyse_Code(Code); | ||||
|  | 
 | ||||
|  | 	for (i = 0; i < 20; i++){temp[i] = false;}  //初始化
 | ||||
|  | 	for (i = 0; i < 20; i++) {  //检查table内容是否合法
 | ||||
|  | 		if (table[i] > 10) {return false;} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (block[0].style != 0) {return false;}  //检查2*2块
 | ||||
|  | 	for (i = 1; i <= 5; i++) {  //检查2*1与1*2块
 | ||||
|  | 		if ((block[i].style != 1) && (block[i].style != 2)) {return false;} | ||||
|  | 	} | ||||
|  | 	for (i = 6; i <= 9; i++) {  //检查1*1块
 | ||||
|  | 		if (block[i].style != 3) {return false;} | ||||
|  | 	} | ||||
|  | 	for (i = 0; i <= 1; i++) { //检查空格
 | ||||
|  | 		if (space[i] > 19) { | ||||
|  | 			return false; | ||||
|  | 		} else { | ||||
|  | 			temp[space[i]] = true; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	addr = block[0].address;  //检查2*2块
 | ||||
|  | 	if ((addr > 14) || (addr%4 == 3)) {return false;} | ||||
|  | 	if ((temp[addr] == true) || (temp[addr + 1] == true) || | ||||
|  | 		(temp[addr + 4] == true) || (temp[addr + 5] == true)) {return false;} | ||||
|  | 	temp[addr] = temp[addr + 1] = temp[addr + 4] = temp[addr + 5] = true; | ||||
|  | 	for (i = 1; i <= 5; i++) {  //检查2*1与1*2块
 | ||||
|  | 		addr = block[i].address; | ||||
|  | 		if (block[i].style == 1) { | ||||
|  | 			if ((addr > 18) || (addr % 4 == 3)) {return false;} | ||||
|  | 			if ((temp[addr] == true) || (temp[addr + 1] == true)) {return false;} | ||||
|  | 			temp[addr] = temp[addr + 1] = true; | ||||
|  | 		} | ||||
|  | 		if (block[i].style == 2) { | ||||
|  | 			if (addr > 15) {return false;} | ||||
|  | 			if ((temp[addr] == true) || (temp[addr + 4] == true)) {return false;} | ||||
|  | 			temp[addr] = temp[addr + 4] = true; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	for (i = 6; i <= 9; i++) {  //检查1*1块
 | ||||
|  | 		addr = block[i].address; | ||||
|  | 		if (addr > 19) {return false;} | ||||
|  | 		if (temp[addr] == true) {return false;} | ||||
|  | 		temp[addr] = true; | ||||
|  | 	} | ||||
|  | 	return true; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Output_Graph (unsigned int Code) {  //命令行下图形化输出布局图
 | ||||
|  | 	const unsigned char Square_Width = 4; | ||||
|  | 	const string Square_str = "[]";  //or "u2588"
 | ||||
|  | 	unsigned int i, k, m; | ||||
|  | 	unsigned int start_x, start_y, end_x, end_y; | ||||
|  | 	bool Graph[(Square_Width + 1) * 4 + 1][(Square_Width + 1) * 5 + 1];  //点阵方式储存输出图像
 | ||||
|  | 	if (Check(Code) == false) { | ||||
|  | 		cout<<"The Code is Wrong!"<<endl; | ||||
|  | 		return; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	Analyse_Code(Code);  //先解析编码
 | ||||
|  | 	for (k = 0; k <= (Square_Width + 1) * 5; k++) {  //初始化
 | ||||
|  | 		for (i = 0; i <= (Square_Width + 1) * 4; i++) { | ||||
|  | 			Graph[i][k] = false; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (m = 0; m <= 9; m++) {  //遍历九个块
 | ||||
|  | 		start_x = (block[m].address % 4) * (Square_Width + 1) + 1;  //计算该块的左上角坐标
 | ||||
|  | 		start_y = int(block[m].address / 4) * (Square_Width + 1) + 1; | ||||
|  | 		if ((block[m].style == 0) || (block[m].style == 1)) {  //计算该块的右下角横坐标
 | ||||
|  | 			end_x = start_x + Square_Width * 2;  //2*2 or 2*1
 | ||||
|  | 		} else { | ||||
|  | 			end_x = start_x + Square_Width - 1;  //1*2 or 1*1
 | ||||
|  | 		} | ||||
|  | 		if ((block[m].style == 0) || (block[m].style == 2)) {  //计算该块的右下角纵坐标
 | ||||
|  | 			end_y = start_y + Square_Width * 2;  //2*2 or 1*2
 | ||||
|  | 		} else { | ||||
|  | 			end_y = start_y + Square_Width - 1;  //2*1 or 1*1
 | ||||
|  | 		} | ||||
|  | 		for (i = start_x; i <= end_x; i++) {  //填充该块覆盖的区域
 | ||||
|  | 			for(k = start_y; k <= end_y; k++) { | ||||
|  | 				Graph[i][k] = true; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (i = 1; i <= (Square_Width + 1) * 4 + 3; i++) {cout<<Square_str;}  //显示上边框
 | ||||
|  | 	cout<<endl<<Square_str; | ||||
|  | 	for (k = 0; k <= (Square_Width + 1) * 5; k++){  //显示图像内容
 | ||||
|  | 		for (i = 0; i <= (Square_Width + 1) * 4; i++) { | ||||
|  | 			if (Graph[i][k] == false){ | ||||
|  | 				cout<<"  "; | ||||
|  | 			} else { | ||||
|  | 				cout<<Square_str; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		cout<<Square_str<<endl<<Square_str;  //显示左右边框
 | ||||
|  | 	} | ||||
|  | 	for (i = 1; i <= (Square_Width + 1) * 4 + 2; i++) {cout<<Square_str;}  //显示下边框
 | ||||
|  | 	cout<<endl; | ||||
|  | } | ||||
|  | 
 | ||||
|  | string Change_str (unsigned int dat) {  //将编码数据转化为字符
 | ||||
|  | 	unsigned char i, bit; | ||||
|  | 	string str = ""; | ||||
|  | 	for (i = 0; i < 7; i++) { | ||||
|  | 		bit = 0xF & dat>>(6 - i)*4;  //分离单个十六进制位
 | ||||
|  | 		if ((bit >= 0) && (bit <= 9)) {str += bit + 48;}  //0~9
 | ||||
|  | 		if ((bit >= 0xA) && (bit <= 0xF)) {str += bit + 55;}  //A~F
 | ||||
|  | 	} | ||||
|  | 	return str; | ||||
|  | } | ||||
|  | 
 | ||||
|  | unsigned int Change_int (char str[8]) {  //将编码字符转化为int
 | ||||
|  | 	unsigned int i, dat = 0; | ||||
|  | 	for (i = 0; i < 7; i++) { | ||||
|  | 		if ((str[i] >= 48) && (str[i] <= 57)) {dat = dat | (str[i] - 48)<<(24 - i * 4);}  //0~9
 | ||||
|  | 		if ((str[i] >= 65) && (str[i] <= 70)) {dat = dat | (str[i] - 55)<<(24 - i * 4);}  //A~F
 | ||||
|  | 		if ((str[i] >= 97) && (str[i] <= 102)) {dat = dat | (str[i] - 87)<<(24 - i * 4);}  //a~f
 | ||||
|  | 	} | ||||
|  | 	return dat; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void debug() {  //输出当前 table[20] block[10] space[2]的状态
 | ||||
|  | 	unsigned int i; | ||||
|  | 	for (i = 0; i < 20; i++) { | ||||
|  | 		if (table[i] != 0xA) { | ||||
|  | 			cout<<int(table[i])<<" "; | ||||
|  | 		} else { | ||||
|  | 			cout<<"A "; | ||||
|  | 		} | ||||
|  | 		if (i == 3) {cout<<"        00 01 02 03"<<endl;} | ||||
|  | 		if (i == 7) {cout<<"        04 05 06 07"<<endl;} | ||||
|  | 		if (i == 11) {cout<<"        08 09 10 11"<<endl;} | ||||
|  | 		if (i == 15) {cout<<"        12 13 14 15"<<endl;} | ||||
|  | 		if (i == 19) {cout<<"        16 17 18 19"<<endl;} | ||||
|  | 	} | ||||
|  | 	cout<<endl<<"space[0] -> address="<<int(space[0])<<endl; | ||||
|  | 	cout<<"space[1] -> address="<<int(space[1])<<endl<<endl; | ||||
|  | 	for (i = 0; i <= 9; i++) { | ||||
|  | 		cout<<"block["<<i<<"] -> address="<<int(block[i].address)<<" style="<<int(block[i].style)<<endl; | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Find_All_Case(){  //Right_File's MD5: 4A0179C6AEF266699A73E41ECB4D87C1
 | ||||
|  | 	File_Output.open("All_Case.txt"); | ||||
|  | 	unsigned int i; | ||||
|  | 	for(i=0;i<0xFFFFFFF;i=i+4){ | ||||
|  | 		if(Check(i)==true){File_Output<<Change_str(i)<<endl;} | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | } | ||||
|  | void Data_Output(){ | ||||
|  |     unsigned int i; | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     File_Output.open("Data_Output.txt"); | ||||
|  |     for(i=0;i<List.size();i++){ | ||||
|  |         File_Output<<i<<" -> "<<Change_str(List[i])<<" ("<<Layer_Num[i]<<")"; | ||||
|  |         poi=Source[i].begin(); | ||||
|  |         while(poi!=Source[i].end()){File_Output<<"  ["<<*poi<<"]";++poi;} | ||||
|  |         File_Output<<endl; | ||||
|  |     } | ||||
|  |     File_Output.close(); | ||||
|  | } | ||||
| @ -0,0 +1,912 @@ | |||||
|  | #include <iostream> | ||||
|  | #include <vector> | ||||
|  | #include <string> | ||||
|  | #include <list> | ||||
|  | #include <fstream> | ||||
|  | using namespace std; | ||||
|  | 
 | ||||
|  | ifstream File_Input; | ||||
|  | ofstream File_Output; | ||||
|  | const unsigned char Up = 1, Down = 2, Left = 3, Right = 4; | ||||
|  | 
 | ||||
|  | struct block_struct { | ||||
|  | 	unsigned char address;  //0~19
 | ||||
|  | 	unsigned char style;  //0:2*2  1:2*1  2:1*2  3:1*1
 | ||||
|  | }; | ||||
|  | unsigned char table[20];  //0~9:block[?]  0xA:space  0xFF:empty
 | ||||
|  | unsigned char space[2];  //space[0~1]的位置
 | ||||
|  | struct block_struct block[10];  //0:2*2  1~5:1*2,2*1  6~9:1*1
 | ||||
|  | 
 | ||||
|  | list <unsigned int> int_list;  //空列表 给Source用
 | ||||
|  | vector <unsigned int> int_vector;  //空vector 给Layer用
 | ||||
|  | list <unsigned int> Hash[0x10000];  //哈希索引表
 | ||||
|  | unsigned int Now_Move;  //目前正在进行计算的布局编号
 | ||||
|  | vector <unsigned int> List;  //所有情况的队列
 | ||||
|  | vector <unsigned int> Layer_Num;  //所在层的编号
 | ||||
|  | vector <unsigned int> Layer_Index;  //层中所属的编号
 | ||||
|  | vector <list <unsigned int> > Source;  //父布局编号
 | ||||
|  | vector <vector <unsigned int> > Layer;  //分层
 | ||||
|  | vector <vector <vector <unsigned int> > > Layer_Next;  //分层链接
 | ||||
|  | vector <bool> bool_vector;  //空vector 给solution_flag用
 | ||||
|  | vector <vector <bool> > solution_flag;  //求不同步数解的标识
 | ||||
|  | 
 | ||||
|  | //布局的基本参数
 | ||||
|  | int group_size;  //整个队列组的大小
 | ||||
|  | int min_solution_step;  //最少的步数
 | ||||
|  | int solution_num;  //解的个数
 | ||||
|  | int min_solution_num;  //最少步解的个数
 | ||||
|  | vector <unsigned int> solution_case;  //所有解
 | ||||
|  | vector <unsigned int> solution_step;  //所有解对应的步数
 | ||||
|  | vector <unsigned int> min_solution_case;  //所有最少步解
 | ||||
|  | int farthest_step;  //最远布局的步数
 | ||||
|  | int farthest_num;  //最远布局的个数
 | ||||
|  | vector <unsigned int> farthest_case;  //所有最远的布局
 | ||||
|  | 
 | ||||
|  | void debug(); | ||||
|  | void Output_Graph(unsigned int Code); | ||||
|  | string Change_str(unsigned int dat); | ||||
|  | unsigned int Change_int(char str[8]); | ||||
|  | bool Check(unsigned int Code); | ||||
|  | void Analyse_Code(unsigned int Code); | ||||
|  | unsigned int Get_Code(); | ||||
|  | bool Check_Empty(unsigned char address,unsigned char dir,unsigned char num); | ||||
|  | void Fill_Block(unsigned char addr, unsigned char style, unsigned char filler); | ||||
|  | void Move_Block(unsigned char num,unsigned char dir_1,unsigned char dir_2); | ||||
|  | void Find_Next(); | ||||
|  | void Add_Case(unsigned int Code); | ||||
|  | void Calculate(unsigned int Start_Code); | ||||
|  | void Split_Layer(); | ||||
|  | vector <unsigned int> Sort(vector <unsigned int> dat); | ||||
|  | void Analyse_Case(unsigned int Start_Code); | ||||
|  | void Output_Detail(unsigned int Code); | ||||
|  | vector <unsigned int> Split_Group(vector <unsigned int> dat); | ||||
|  | 
 | ||||
|  | int main() { | ||||
|  | 	unsigned int i, j, k, index; | ||||
|  | 	struct Case_struct { | ||||
|  | 		unsigned int id; | ||||
|  | 		char Short_Code[5]; | ||||
|  | 		unsigned int Code; | ||||
|  | 		unsigned int Style; | ||||
|  | 		unsigned int Group; | ||||
|  | 		int group_size; | ||||
|  | 		int min_solution_step; | ||||
|  | 		int solution_num; | ||||
|  | 		int min_solution_num; | ||||
|  | 		vector <unsigned int> solution_case; | ||||
|  | 		vector <unsigned int> solution_step; | ||||
|  | 		vector <unsigned int> min_solution_case; | ||||
|  | 		int farthest_step; | ||||
|  | 		int farthest_num; | ||||
|  | 		vector <unsigned int> farthest_case; | ||||
|  | 	}; | ||||
|  | 
 | ||||
|  | 	Case_struct empty_case; | ||||
|  | 	vector <Case_struct> All_Case; | ||||
|  | 
 | ||||
|  | 	cout << "Find all cases..." << endl; | ||||
|  | 	for (i = 0; i < 0xFFFFFFF; i += 4) { | ||||
|  | 		if (Check(i) == true) { | ||||
|  | 			All_Case.push_back(empty_case); | ||||
|  | 			index = All_Case.size() - 1; | ||||
|  | 			All_Case[index].Code = i; | ||||
|  | 			All_Case[index].id = index; | ||||
|  | 			k = 0; | ||||
|  | 			for (j = 1; j <= 5; j++) { | ||||
|  | 				if (block[j].style == 1) {k++;} | ||||
|  | 			} | ||||
|  | 			All_Case[index].Style = k; | ||||
|  | 			All_Case[All_Case.size() - 1].Short_Code[4] = 0; | ||||
|  | 			All_Case[All_Case.size() - 1].Short_Code[3] = index % 26; | ||||
|  | 			index = (index - All_Case[All_Case.size() - 1].Short_Code[3]) / 26; | ||||
|  | 			All_Case[All_Case.size() - 1].Short_Code[2] = index % 26; | ||||
|  | 			index = (index - All_Case[All_Case.size() - 1].Short_Code[2]) / 26; | ||||
|  | 			All_Case[All_Case.size() - 1].Short_Code[1] = index % 26; | ||||
|  | 			index = (index - All_Case[All_Case.size() - 1].Short_Code[1]) / 26; | ||||
|  | 			All_Case[All_Case.size() - 1].Short_Code[0] = index % 26; | ||||
|  | 			for (j = 0; j <= 3; j++) { | ||||
|  | 				All_Case[All_Case.size() - 1].Short_Code[j] += 97; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		if (i % 0x1000000 == 0) {cout << (i >> 24) + 1 << "/16" << endl;} | ||||
|  | 	} | ||||
|  | 	cout << "OK -> Size of All_Case: " << All_Case.size() << endl; | ||||
|  | 	vector <unsigned int> dat; | ||||
|  | 	vector <unsigned int> Group_Index; | ||||
|  | 	for (k = 0; k <= 5; k++) { | ||||
|  | 		dat.clear(); | ||||
|  | 		Group_Index.clear(); | ||||
|  | 		for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 			if (All_Case[i].Style == k) { | ||||
|  | 				dat.push_back(All_Case[i].Code); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		cout << "Style_" << k << " with " << dat.size() << " cases" << endl; | ||||
|  | 		Group_Index = Split_Group(dat); | ||||
|  | 		j = 0; | ||||
|  | 		for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 			if (All_Case[i].Style == k) { | ||||
|  | 				All_Case[i].Group = Group_Index[j]; | ||||
|  | 				j++; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	cout << "Output main.csv..."; | ||||
|  | 	File_Output.open("main.csv"); | ||||
|  | 	File_Output << "id,short_code,code,style,group"; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		File_Output << endl; | ||||
|  | 		File_Output << All_Case[i].id << ","; | ||||
|  | 		File_Output << All_Case[i].Short_Code << ","; | ||||
|  | 		File_Output << Change_str(All_Case[i].Code) << ","; | ||||
|  | 		File_Output << All_Case[i].Style << ","; | ||||
|  | 		File_Output << All_Case[i].Group; | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	cout << "Start analyse all cases..." << endl; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		cout << Change_str(All_Case[i].Code) << "..."; | ||||
|  | 		Analyse_Case(All_Case[i].Code); | ||||
|  | 		All_Case[i].group_size = group_size; | ||||
|  | 		All_Case[i].min_solution_step = min_solution_step; | ||||
|  | 		All_Case[i].solution_num = solution_num; | ||||
|  | 		All_Case[i].min_solution_num = min_solution_num; | ||||
|  | 		All_Case[i].solution_case = solution_case; | ||||
|  | 		All_Case[i].solution_step = solution_step; | ||||
|  | 		All_Case[i].min_solution_case = min_solution_case; | ||||
|  | 		All_Case[i].farthest_step = farthest_step; | ||||
|  | 		All_Case[i].farthest_num = farthest_num; | ||||
|  | 		All_Case[i].farthest_case = farthest_case; | ||||
|  | 		cout << "OK -> " << i + 1 << "/" << All_Case.size() << endl; | ||||
|  | 	} | ||||
|  | 	cout << "Output group.csv..."; | ||||
|  | 	File_Output.open("group.csv"); | ||||
|  | 	File_Output << "id,group_id,group_size"; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		File_Output << endl; | ||||
|  | 		File_Output << All_Case[i].id << ","; | ||||
|  | 		File_Output << All_Case[i].Style << "-" << All_Case[i].Group << ","; | ||||
|  | 		File_Output << All_Case[i].group_size; | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	cout << "Output farthest.csv..."; | ||||
|  | 	File_Output.open("farthest.csv"); | ||||
|  | 	File_Output << "id,farthest_step,farthest_num,farthest_case"; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		File_Output << endl; | ||||
|  | 		File_Output << All_Case[i].id << ","; | ||||
|  | 		File_Output << All_Case[i].farthest_step << ","; | ||||
|  | 		File_Output << All_Case[i].farthest_num << ","; | ||||
|  | 		for (j = 0; j < All_Case[i].farthest_case.size(); j++) { | ||||
|  | 			File_Output << Change_str(All_Case[i].farthest_case[j]); | ||||
|  | 			if (j != All_Case[i].farthest_case.size() - 1) {File_Output << "-";} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	cout << "Output min_solution.csv..."; | ||||
|  | 	File_Output.open("min_solution.csv"); | ||||
|  | 	File_Output << "id,min_solution_step,min_solution_num,min_solution_case"; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		File_Output << endl; | ||||
|  | 		File_Output << All_Case[i].id << ","; | ||||
|  | 		File_Output << All_Case[i].min_solution_step << ","; | ||||
|  | 		File_Output << All_Case[i].min_solution_num << ","; | ||||
|  | 		for (j = 0; j < All_Case[i].min_solution_case.size(); j++) { | ||||
|  | 			File_Output << Change_str(All_Case[i].min_solution_case[j]); | ||||
|  | 			if (j != All_Case[i].min_solution_case.size() - 1) {File_Output << "-";} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	cout << "Output solution.csv..."; | ||||
|  | 	File_Output.open("solution.csv"); | ||||
|  | 	File_Output << "id,solution_num,solution_case"; | ||||
|  | 	for (i = 0; i < All_Case.size(); i++) { | ||||
|  | 		File_Output << endl; | ||||
|  | 		File_Output << All_Case[i].id << ","; | ||||
|  | 		File_Output << All_Case[i].solution_num << ","; | ||||
|  | 		for (j = 0; j < All_Case[i].solution_case.size(); j++) { | ||||
|  | 			File_Output << Change_str(All_Case[i].solution_case[j]); | ||||
|  | 			File_Output << "(" << All_Case[i].solution_step[j] << ")"; | ||||
|  | 			if (j != All_Case[i].solution_case.size() - 1) {File_Output << "-";} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	File_Output.close(); | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	cout << "All Done!" << endl; | ||||
|  |     return 0; | ||||
|  | } | ||||
|  | 
 | ||||
|  | vector <unsigned int> Split_Group(vector <unsigned int> dat) {  //分离群组,要求输入的数据从小到大排列
 | ||||
|  | 	unsigned int i, j; | ||||
|  | 	vector <unsigned int> temp; | ||||
|  | 	vector <vector <unsigned int> > Group_Sorted; | ||||
|  | 	cout << "Input dat with " << dat.size() << " cases" << endl; | ||||
|  | 	cout << "Start to split the group" << endl; | ||||
|  | 	while (1 == 1) { | ||||
|  | 		if (dat.size() == 0) {break;} | ||||
|  | 		cout << "Try to find the group of " << Change_str(dat[0]) << "..."; | ||||
|  | 		Calculate(dat[0]); | ||||
|  | 		cout << "OK -> " << List.size() << " members had been found!" << endl; | ||||
|  | 		cout << "Try to kick them out..."; | ||||
|  | 		for (i = 0; i < List.size(); i++) { | ||||
|  | 			for (j = 0; j < dat.size(); j++) { | ||||
|  | 				if (List[i] == dat[j]) {dat[j] = 0;} | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		cout << "OK" << endl; | ||||
|  | 		cout << "Neaten the group..."; | ||||
|  | 		for (i = 0; i < List.size() - 1; i++) { | ||||
|  | 			for (j = 0; j < List.size() - 1; j++) { | ||||
|  | 				if (List[j] >= List[j + 1]) {swap(List[j], List[j + 1]);} | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		Group_Sorted.push_back(List); | ||||
|  | 		cout << "OK" << endl; | ||||
|  | 		cout << "Refresh dat..."; | ||||
|  | 		temp.clear(); | ||||
|  | 		for (i = 0; i < dat.size(); i++) { | ||||
|  | 			if (dat[i] != 0) { | ||||
|  | 				temp.push_back(dat[i]); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		dat.clear(); | ||||
|  | 		dat = temp; | ||||
|  | 		cout << "OK -> Size of dat:" << dat.size() << endl; | ||||
|  | 	} | ||||
|  | 	cout << "Neaten the Group_Sorted..."; | ||||
|  | 	for (i = 0; i < Group_Sorted.size() - 1; i++) { | ||||
|  | 		for (j = 0; j < Group_Sorted.size() - 1; j++) { | ||||
|  | 			if (Group_Sorted[j].size() < Group_Sorted[j + 1].size()) { | ||||
|  | 				swap(Group_Sorted[j], Group_Sorted[j + 1]); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	cout << "OK -> Size of Group_Sorted: " << Group_Sorted.size() << endl; | ||||
|  | 	dat.clear(); | ||||
|  | 	temp.clear(); | ||||
|  | 	for (i = 0; i < Group_Sorted.size(); i++) { | ||||
|  | 		for (j = 0; j < Group_Sorted[i].size(); j++) { | ||||
|  | 			dat.push_back(Group_Sorted[i][j]); | ||||
|  | 			temp.push_back(i); | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	cout << "Record the Group_num..."; | ||||
|  | 	for (i = 0; i < dat.size() - 1; i++) { | ||||
|  | 		for (j = 0; j < dat.size() - 1; j++) { | ||||
|  | 			if (dat[j] >= dat[j + 1]) { | ||||
|  | 				swap(dat[j], dat[j + 1]); | ||||
|  | 				swap(temp[j], temp[j + 1]); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	cout << "OK" << endl; | ||||
|  | 	return temp; | ||||
|  | } | ||||
|  | void Output_Detail(unsigned int Code) {  //输出某一布局的具体数据
 | ||||
|  |     unsigned int i, j, layer; | ||||
|  |     Analyse_Case(Code);  //进行分析
 | ||||
|  |     cout << "Code: " << Change_str(Code) << endl << endl; | ||||
|  |     cout << "farthest_step: " << farthest_step << endl; | ||||
|  |     cout << "farthest_num: " << farthest_num << endl; | ||||
|  |     cout << "farthest_case: "; | ||||
|  |     for (i = 0; i < farthest_case.size(); i++) { | ||||
|  |          cout << Change_str(farthest_case[i]) << " "; | ||||
|  |     } | ||||
|  |     cout << endl << endl; | ||||
|  |     cout << "min_solution_step: " << min_solution_step << endl; | ||||
|  |     cout << "min_solution_num: " << min_solution_num << endl; | ||||
|  |     cout << "min_solution_case: "; | ||||
|  |     for (i = 0; i < min_solution_case.size(); i++) { | ||||
|  |          cout << Change_str(min_solution_case[i]) << " "; | ||||
|  |     } | ||||
|  |     cout << endl << endl; | ||||
|  |     cout << "solution_num: " << solution_num << endl; | ||||
|  |     cout << "solution_case(solution_step): "; | ||||
|  |     for (i = 0; i < solution_case.size(); i++) { | ||||
|  |          cout << Change_str(solution_case[i]) << "(" << solution_step[i] << ") "; | ||||
|  |     } | ||||
|  |     cout << endl << endl; | ||||
|  |     string File_Name; | ||||
|  |     File_Name = Change_str(Code) + ".txt"; | ||||
|  |     cout << "Data save at " << File_Name << endl << endl; | ||||
|  |     File_Output.open(File_Name.c_str()); | ||||
|  |     File_Output << "[Group_size]" << endl << group_size << endl; | ||||
|  |     File_Output << "[Min_Solution_step]" << endl << min_solution_step << endl; | ||||
|  |     File_Output << "[Farthest_step]" << endl << farthest_step << endl; | ||||
|  |     File_Output << "[Min_Solution]" << endl; | ||||
|  |     for (i = 0; i < min_solution_case.size(); i++) { | ||||
|  |         File_Output << Change_str(min_solution_case[i]) << endl; | ||||
|  |     } | ||||
|  |     File_Output << "[Farthest]" << endl; | ||||
|  |     for (i = 0; i < farthest_case.size(); i++) { | ||||
|  |         File_Output << Change_str(farthest_case[i]) << endl; | ||||
|  |     } | ||||
|  |     File_Output << "[Solution]" << endl; | ||||
|  |     for (i = 0; i < solution_case.size(); i++) { | ||||
|  |         File_Output << Change_str(solution_case[i]) << " (" << solution_step[i] << ")" << endl; | ||||
|  |     } | ||||
|  |     File_Output << "[List]" << endl; | ||||
|  |     for (i = 0; i < List.size(); i++) { | ||||
|  |         File_Output << i << " -> " << Change_str(List[i]) << " (" << Layer_Num[i] << "," << Layer_Index[i] << ")" << endl; | ||||
|  |     } | ||||
|  |     File_Output << "[Layer]" << endl; | ||||
|  |     for (layer = 0; layer < Layer.size(); layer++) { | ||||
|  |         for (i = 0; i < Layer_Next[layer].size(); i++) { | ||||
|  |             File_Output << "(" << layer << "," << i << ")" << " -> "; | ||||
|  |             for (j = 0; j < Layer_Next[layer][i].size(); j++) { | ||||
|  |                 File_Output << "(" << (layer + 1) << "," << Layer_Next[layer][i][j] << ") "; | ||||
|  |             } | ||||
|  |             File_Output << endl; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     list<unsigned int>::iterator poi; | ||||
|  |     File_Output << "[Source]" << endl; | ||||
|  |     for (i = 0; i < List.size(); i++){ | ||||
|  |         File_Output << i << " -> " << Change_str(List[i]) << " (" << Layer_Num[i] << ")"; | ||||
|  |         poi = Source[i].begin(); | ||||
|  |         while (poi != Source[i].end()) { | ||||
|  |             File_Output << "  [" << *poi << "]"; | ||||
|  |             ++poi; | ||||
|  |         } | ||||
|  |         File_Output<<endl; | ||||
|  |     } | ||||
|  |     File_Output.close(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Analyse_Case(unsigned int Code) {  //对一个布局进行分析
 | ||||
|  | 	unsigned int i, j, k; | ||||
|  | 	vector <unsigned int> temp; | ||||
|  |     min_solution_step = -1;  //初始化
 | ||||
|  | 	solution_num = 0; | ||||
|  |     min_solution_num = 0; | ||||
|  |     farthest_step = -1; | ||||
|  |     farthest_num = 0; | ||||
|  | 	solution_case.clear(); | ||||
|  |     solution_step.clear(); | ||||
|  | 	min_solution_case.clear(); | ||||
|  | 	farthest_case.clear(); | ||||
|  |     Layer.clear(); | ||||
|  |     Layer_Next.clear(); | ||||
|  |     Layer_Index.clear(); | ||||
|  |     solution_flag.clear(); | ||||
|  | 	if (Check(Code) == false) {return;}  //若输入编码无效则退出
 | ||||
|  | 	Calculate(Code);  //通过计算建立队列表
 | ||||
|  |     Split_Layer();  //分层并计算链接
 | ||||
|  | 
 | ||||
|  | 	group_size = List.size();  //得到整个队列树大小
 | ||||
|  |     farthest_step = Layer_Num[Layer_Num.size() - 1];  //计算最远布局的步数
 | ||||
|  |     for (i = 0; i < Layer[farthest_step].size(); i++) {  //找到所有最远的布局
 | ||||
|  |         farthest_case.push_back(Layer[farthest_step][i]); | ||||
|  |     } | ||||
|  |     farthest_num = farthest_case.size(); | ||||
|  | 	farthest_case = Sort(farthest_case);  //得到的结果进行排序
 | ||||
|  | 
 | ||||
|  |     for (i = 0; i < List.size(); i++) { | ||||
|  |         if ((0xF & (List[i] >> 24)) == 0xD) { | ||||
|  |             min_solution_step = Layer_Num[i];  //找到最少步数
 | ||||
|  |             break; | ||||
|  |         } | ||||
|  |     } | ||||
|  |     if (min_solution_step == -1) {return;}  //无解则退出
 | ||||
|  |     for (i = 0; i < Layer[min_solution_step].size(); i++) {  //遍历最少步所在层
 | ||||
|  |         if ((0xF & (Layer[min_solution_step][i] >> 24)) == 0xD) {  //判断是否为解
 | ||||
|  |             min_solution_case.push_back(Layer[min_solution_step][i]); | ||||
|  |             solution_flag[min_solution_step][i] = true;  //标识
 | ||||
|  |         } | ||||
|  |     } | ||||
|  |     min_solution_num = min_solution_case.size(); | ||||
|  | 	min_solution_case = Sort(min_solution_case);  //得到的结果进行排序
 | ||||
|  | 
 | ||||
|  |     solution_case = min_solution_case; | ||||
|  |     for (i = 0; i < solution_case.size(); i++) {  //初始化已知部分的solution_step
 | ||||
|  |         solution_step.push_back(min_solution_step); | ||||
|  |     } | ||||
|  |     for (i = 0; i < Layer.size() - 1; i++) {  //遍历除最后一层外的所有层
 | ||||
|  |         for (j = 0; j < Layer[i].size(); j++) {  //遍历层内元素
 | ||||
|  |             if (solution_flag[i][j] == true) {  //若该元素被标识
 | ||||
|  |                 for (k = 0; k < Layer_Next[i][j].size(); k++) {  //遍历其下一步
 | ||||
|  |                     solution_flag[i + 1][Layer_Next[i][j][k]] = true;  //标识
 | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  | 		temp.clear();  //初始化temp
 | ||||
|  |         for (j = 0; j < Layer[i + 1].size(); j++) {  //遍历下一层内元素
 | ||||
|  |             if (solution_flag[i + 1][j] == false) {  //得到未被标识的元素
 | ||||
|  |                 if ((0xF & (Layer[i + 1][j] >> 24)) == 0xD) {  //若为解的布局
 | ||||
|  |                     //solution_case.push_back(Layer[i + 1][j]);
 | ||||
|  | 					temp.push_back(Layer[i + 1][j]);  //为了方便排序,先加入到temp中
 | ||||
|  |                     solution_step.push_back(i + 1); | ||||
|  |                     solution_flag[i + 1][j] = true;  //进行标识
 | ||||
|  |                 } | ||||
|  |             } | ||||
|  |         } | ||||
|  | 		temp = Sort(temp);  //将得到的数据进行处理
 | ||||
|  | 		for (k = 0; k < temp.size(); k++) {  //将temp内容加入solution_case中
 | ||||
|  | 			solution_case.push_back(temp[k]); | ||||
|  | 		} | ||||
|  |     } | ||||
|  |     solution_num = solution_case.size(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | vector <unsigned int> Sort(vector <unsigned int> dat) {  //将输入的vector排序为从小到大
 | ||||
|  | 	unsigned int i, j; | ||||
|  | 	if (dat.size() == 0) {return dat;}  //空的则退出
 | ||||
|  | 	for (i = 0; i < dat.size() - 1; i++) {  //冒泡排序
 | ||||
|  | 		for (j = 0; j < dat.size() - 1; j++) { | ||||
|  | 			if (dat[j] >= dat[j + 1]) {swap(dat[j], dat[j + 1]);} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	return dat; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Split_Layer() {  //分割得到不同层并进行链接
 | ||||
|  | 	vector <vector <unsigned int> > temp; | ||||
|  | 	int i, num, index; | ||||
|  | 	num = -1; | ||||
|  | 	index = 0; | ||||
|  | 	for (i = 0; i < Layer_Num.size(); i++) {  //遍历全部布局
 | ||||
|  | 		if (Layer_Num[i] != num) {  //到了新的层
 | ||||
|  |             solution_flag.push_back(bool_vector); | ||||
|  | 			Layer.push_back(int_vector); | ||||
|  | 			Layer_Next.push_back(temp); | ||||
|  | 			num = Layer_Num[i]; | ||||
|  | 			index = 0; | ||||
|  | 		} | ||||
|  |         solution_flag[num].push_back(false); | ||||
|  | 		Layer_Index.push_back(index); | ||||
|  | 		index++; | ||||
|  | 		Layer[num].push_back(List[i]); | ||||
|  | 		Layer_Next[num].push_back(int_vector);  //初始化链接数据
 | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	list <unsigned int>::iterator poi;  //声明迭代器
 | ||||
|  | 	for (i = 1; i < List.size(); i++) {  //遍历除根布局外的额全部布局
 | ||||
|  | 		poi = Source[i].begin(); | ||||
|  | 		while (poi != Source[i].end()) {  //遍历其上一步
 | ||||
|  | 			Layer_Next[Layer_Num[*poi]][Layer_Index[*poi]].push_back(Layer_Index[i]);  //加入链接表中
 | ||||
|  | 			++poi; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Calculate(unsigned int Start_Code) {  //启动计算引擎
 | ||||
|  | 	unsigned int i; | ||||
|  | 	for (i = 0; i <= 0xFFFF; i++) {Hash[i].clear();}  //初始化
 | ||||
|  | 	List.clear(); | ||||
|  | 	Layer_Num.clear(); | ||||
|  | 	Source.clear(); | ||||
|  | 	Hash[(Start_Code >> 4) & 0xFFFF].push_back(0);  //加入初始布局
 | ||||
|  | 	List.push_back(Start_Code); | ||||
|  | 	Layer_Num.push_back(0); | ||||
|  | 	Source.push_back(int_list); | ||||
|  | 	Now_Move = 0;  //搜索目标指向根节点
 | ||||
|  | 	while (Now_Move != List.size()) {  //进行广度优先搜索
 | ||||
|  | 		Analyse_Code(List[Now_Move]);  //解析目标布局
 | ||||
|  | 		Find_Next();  //根据解析结果搜索所有子布局
 | ||||
|  | 		Now_Move++; | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Add_Case(unsigned int Code) {  //将计算结果加入队列
 | ||||
|  |     list <unsigned int>::iterator poi;  //定义迭代器
 | ||||
|  | 	poi = Hash[(Code >> 4) & 0xFFFF].begin();  //设置poi为索引表的起始点
 | ||||
|  | 	while (poi != Hash[(Code >> 4) & 0xFFFF].end()) {  //遍历索引表
 | ||||
|  | 		if (Code == List[*poi]) {  //若发现重复
 | ||||
|  |             if ((Layer_Num[*poi] - Layer_Num[Now_Move]) == 1) {  //若高一层
 | ||||
|  | 				Source[*poi].push_back(Now_Move);  //加入父节点列表
 | ||||
|  | 			} | ||||
|  |             return;  //重复 退出
 | ||||
|  |         } | ||||
|  | 		++poi; | ||||
|  | 	} | ||||
|  | 	Hash[(Code >> 4) & 0xFFFF].push_back(List.size());  //将计算结果添加至索引表
 | ||||
|  | 	List.push_back(Code);  //将计算结果加入队列
 | ||||
|  | 	Layer_Num.push_back(Layer_Num[Now_Move] + 1);  //添加对应的层数
 | ||||
|  | 	Source.push_back(int_list);  //初始化其父节点列表
 | ||||
|  | 	Source[Source.size() - 1].push_back(Now_Move);  //将正在进行搜索的布局添加为父节点
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Move_Block(unsigned char num, unsigned char dir_1, unsigned char dir_2) {  //按要求移动块并将移动后的编码传给Add_Case
 | ||||
|  | 	unsigned char i, addr, addr_bak; | ||||
|  | 	addr = block[num].address; | ||||
|  | 	addr_bak = addr; | ||||
|  | 	if (dir_1 == Up) {addr -= 4;}  //第一次移动
 | ||||
|  | 	else if (dir_1==Down) {addr += 4;} | ||||
|  | 	else if (dir_1==Left) {addr--;} | ||||
|  | 	else if (dir_1==Right) {addr++;} | ||||
|  | 	if (dir_2 == Up) {addr -= 4;}  //第二次移动
 | ||||
|  | 	else if (dir_2 == Down) {addr += 4;} | ||||
|  | 	else if (dir_2 == Left) {addr--;} | ||||
|  | 	else if (dir_2 == Right) {addr++;} | ||||
|  | 
 | ||||
|  | 	Fill_Block(addr_bak, block[num].style, 0xA);  //修改 table为移动后的状态
 | ||||
|  | 	Fill_Block(addr, block[num].style, num); | ||||
|  | 	block[num].address = addr; | ||||
|  | 	Add_Case(Get_Code());  //生成编码并赋予Add_Case
 | ||||
|  | 	block[num].address = addr_bak; | ||||
|  | 	Fill_Block(addr, block[num].style, 0xA);  //还原 table原来的状态
 | ||||
|  | 	Fill_Block(addr_bak, block[num].style, num); | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Find_Next() {  //寻找所有移动的方式并提交给Move_Block
 | ||||
|  | 	bool Can_Move[10]; | ||||
|  |     unsigned char i, addr; | ||||
|  | 	for (i = 0; i < 10; i++) {Can_Move[i] = false;} | ||||
|  | 	for (i = 0; i <= 1; i++) {  //寻找位于空格周围的所有块
 | ||||
|  | 		addr = space[i]; | ||||
|  | 		if (addr > 3) | ||||
|  | 			if (table[addr - 4] != 0xA) {Can_Move[table[addr - 4]] = true;} | ||||
|  | 		if (addr < 16) | ||||
|  | 			if (table[addr + 4] != 0xA) {Can_Move[table[addr + 4]] = true;} | ||||
|  | 		if (addr % 4 != 0) | ||||
|  | 			if (table[addr - 1] != 0xA) {Can_Move[table[addr - 1]] = true;} | ||||
|  | 		if (addr % 4 != 3) { | ||||
|  | 			if (table[addr + 1] != 0xA) {Can_Move[table[addr + 1]] = true;}} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (i = 0; i <= 9; i++) { | ||||
|  | 		if (Can_Move[i] == true) {  //若该块可能可以移动
 | ||||
|  | 			addr = block[i].address; | ||||
|  | 			if (block[i].style == 0) {  //2*2
 | ||||
|  | 				if ((Check_Empty(addr, Up, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1,Up, 1) == true)) {Move_Block(i, Up, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Down, 2) == true) && | ||||
|  | 					(Check_Empty(addr + 1,Down, 2) == true)) {Move_Block(i, Down, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Left, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Right, 2) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Right, 2) == true)) {Move_Block(i, Right, 0);} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 1) {  //2*1
 | ||||
|  | 				if ((Check_Empty(addr, Up, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1, Up, 1) == true)) {Move_Block(i, Up, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Down, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 1, Down, 1) == true)) {Move_Block(i, Down, 0);} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Left, 1) == true) { | ||||
|  | 					Move_Block(i, Left, 0); | ||||
|  | 					if (Check_Empty(addr, Left, 2) == true) {Move_Block(i, Left, Left);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Right, 2) == true) { | ||||
|  | 					Move_Block(i, Right, 0); | ||||
|  | 					if (Check_Empty(addr, Right, 3) == true) {Move_Block(i, Right, Right);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 2) {  //1*2
 | ||||
|  | 				if (Check_Empty(addr, Up, 1) == true) { | ||||
|  | 					Move_Block(i, Up, 0); | ||||
|  | 					if (Check_Empty(addr, Up, 2) == true) {Move_Block(i, Up, Up);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if (Check_Empty(addr, Down, 2) == true) { | ||||
|  | 					Move_Block(i, Down, 0); | ||||
|  | 					if (Check_Empty(addr, Down, 3) == true) {Move_Block(i, Down, Down);} | ||||
|  | 				} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Left, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Left, 1) == true)) {Move_Block(i, Left, 0);} | ||||
|  | 
 | ||||
|  | 				if ((Check_Empty(addr, Right, 1) == true) && | ||||
|  | 					(Check_Empty(addr + 4, Right, 1) == true)) {Move_Block(i, Right, 0);} | ||||
|  | 			} | ||||
|  | 			else if (block[i].style == 3) {  //1*1
 | ||||
|  | 				if (Check_Empty(addr, Up, 1) == true) { | ||||
|  | 					Move_Block(i, Up, 0); | ||||
|  | 					if (Check_Empty(addr - 4, Up, 1) == true) {Move_Block(i, Up, Up);} | ||||
|  | 					if (Check_Empty(addr - 4, Left, 1) == true) {Move_Block(i, Up, Left);} | ||||
|  | 					if (Check_Empty(addr - 4, Right, 1) == true) {Move_Block(i, Up, Right);} | ||||
|  | 				} | ||||
|  | 				if (Check_Empty(addr, Down, 1) == true) { | ||||
|  | 					Move_Block(i, Down, 0); | ||||
|  | 					if (Check_Empty(addr + 4, Down, 1) == true) {Move_Block(i, Down, Down);} | ||||
|  | 					if (Check_Empty(addr + 4, Left, 1) == true) {Move_Block(i, Down, Left);} | ||||
|  | 					if (Check_Empty(addr + 4, Right, 1) == true) {Move_Block(i, Down, Right);} | ||||
|  | 				} | ||||
|  | 				if (Check_Empty(addr, Left, 1) == true) { | ||||
|  | 					Move_Block(i, Left, 0); | ||||
|  | 					if (Check_Empty(addr - 1, Up, 1) == true) {Move_Block(i, Left, Up);} | ||||
|  | 					if (Check_Empty(addr - 1, Down, 1) == true) {Move_Block(i, Left, Down);} | ||||
|  | 					if (Check_Empty(addr - 1, Left, 1) == true) {Move_Block(i, Left, Left);} | ||||
|  | 				} | ||||
|  | 				if (Check_Empty(addr, Right, 1) == true) { | ||||
|  | 					Move_Block(i, Right, 0); | ||||
|  | 					if (Check_Empty(addr + 1, Up, 1) == true) {Move_Block(i, Right, Up);} | ||||
|  | 					if (Check_Empty(addr + 1, Down, 1) == true) {Move_Block(i, Right, Down);} | ||||
|  | 					if (Check_Empty(addr + 1, Right, 1) == true) {Move_Block(i, Right, Right);} | ||||
|  | 				} | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Fill_Block(unsigned char addr, unsigned char style, unsigned char filler) {  //用指定内容填充table中指定的位置
 | ||||
|  | 	if (style == 0) {table[addr] = table[addr + 1] = table[addr + 4] = table[addr + 5] = filler;}  //2*2
 | ||||
|  | 	else if (style == 1) {table[addr] = table[addr + 1] = filler;}  //2*1
 | ||||
|  | 	else if (style == 2) {table[addr] = table[addr + 4] = filler;}  //1*2
 | ||||
|  | 	else if (style == 3) {table[addr] = filler;}  //1*1
 | ||||
|  | } | ||||
|  | 
 | ||||
|  | bool Check_Empty(unsigned char address, unsigned char dir, unsigned char num) {  //判断指定位置是否为空格 若不是空格或者无效返回false
 | ||||
|  | 	unsigned char x, y, addr; | ||||
|  | 	if (address > 19) {return false;}  //输入位置不存在
 | ||||
|  | 	x = address % 4; | ||||
|  | 	y = (address - x) / 4; | ||||
|  | 	if (dir == Up) {  //上方
 | ||||
|  | 		if (y < num) {return false;} | ||||
|  | 		addr = address - num * 4; | ||||
|  | 	} | ||||
|  | 	if (dir == Down) {  //下方
 | ||||
|  | 		if (y + num > 4) {return false;} | ||||
|  | 		addr = address + num * 4; | ||||
|  | 	} | ||||
|  | 	if (dir == Left) {  //左侧
 | ||||
|  | 		if (x < num) {return false;} | ||||
|  | 		addr = address - num; | ||||
|  | 	} | ||||
|  | 	if (dir == Right) {  //右侧
 | ||||
|  | 		if(x + num > 3){return false;} | ||||
|  | 		addr = address + num; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (table[addr] == 0xA) { | ||||
|  | 		return true; | ||||
|  | 	} else { | ||||
|  | 		return false; | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | unsigned int Get_Code() {  //生成编码
 | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned int Code = 0; | ||||
|  | 	unsigned char i, addr, style; | ||||
|  | 	for (i = 0; i < 20; i++) {temp[i] = false;}  //初始化
 | ||||
|  | 	temp[block[0].address] = temp[block[0].address + 1] = | ||||
|  | 		temp[block[0].address + 4] = temp[block[0].address + 5] = true; | ||||
|  | 
 | ||||
|  | 	Code |= block[0].address<<24;  //2*2块的位置
 | ||||
|  | 	addr = 0; | ||||
|  | 	for (i = 1; i <= 11; i++) { | ||||
|  | 		while(temp[addr] == true){  //找到下一个未填充的空格
 | ||||
|  | 			if (addr < 19) { | ||||
|  | 				addr++; | ||||
|  | 			} else { | ||||
|  | 				return 0; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		if (table[addr] == 0xA) {  //空格
 | ||||
|  | 			temp[addr] = true; | ||||
|  | 		} else { | ||||
|  | 			style = block[table[addr]].style; | ||||
|  | 			if (style == 1) {  //2*1
 | ||||
|  | 				temp[addr] = temp[addr + 1] = true; | ||||
|  | 				Code |= 1<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 			else if (style == 2) {  //1*2
 | ||||
|  | 				temp[addr] = temp[addr + 4] = true; | ||||
|  | 				Code |= 2<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 			else if (style == 3) {  //1*1
 | ||||
|  | 				temp[addr] = true; | ||||
|  | 				Code |= 3<<(24 - i * 2); | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	return Code; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Analyse_Code(unsigned int Code) {  //解译编码到 table[20] block[10] space[2]中
 | ||||
|  | 	unsigned char i, addr, style; | ||||
|  | 	unsigned char num_space = 0, num_type_1 = 0, num_type_2 = 5; | ||||
|  | 	space[0] = space[1] = 0xFF;  //初始化
 | ||||
|  | 	for (i = 0; i < 20; i++) {table[i] = 0xFF;} | ||||
|  | 	for (i = 0; i <= 9; i++) { | ||||
|  | 		block[i].address = 0xFF; | ||||
|  | 		block[i].style = 0xFF; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	block[0].address = 0xF & (Code >> 24);  //开始解译
 | ||||
|  | 	if (block[0].address > 14) {goto err;}  //2*2块越界 退出
 | ||||
|  | 	block[0].style = 0;  //设置2*2块的参数
 | ||||
|  | 	Fill_Block(block[0].address, 0, 0x0); | ||||
|  | 	addr = 0; | ||||
|  | 	for (i = 0; i < 11; i++) {  //遍历 10个块
 | ||||
|  | 		while (table[addr] != 0xFF){  //向下搜索空块
 | ||||
|  | 			if (addr < 19) { | ||||
|  | 				addr++; | ||||
|  | 			} else { | ||||
|  | 				break; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		style = 0x3 & (Code >> (22 - i * 2));  //0:space  1:2*1  2:1*2  3:1*1
 | ||||
|  | 		if (style == 0) {  //space
 | ||||
|  | 			table[addr] = 0xA; | ||||
|  | 			space[num_space] = addr; | ||||
|  | 			if (num_space == 0) {num_space++;} | ||||
|  | 		} | ||||
|  | 		if (style == 1) {  //2*1
 | ||||
|  | 			if (num_type_1 < 5) {num_type_1++;} | ||||
|  | 			if (addr > 18) {goto err;}  //2*1块越界
 | ||||
|  | 			block[num_type_1].style = 1; | ||||
|  | 			block[num_type_1].address = addr; | ||||
|  | 			table[addr] = table[addr + 1] = num_type_1; | ||||
|  | 		} | ||||
|  | 		if (style == 2) {  //1*2
 | ||||
|  | 			if (num_type_1 < 5) {num_type_1++;} | ||||
|  | 			if (addr > 15) {goto err;}  //1*2块越界
 | ||||
|  | 			block[num_type_1].style = 2; | ||||
|  | 			block[num_type_1].address = addr; | ||||
|  | 			table[addr] = table[addr + 4] = num_type_1; | ||||
|  | 		} | ||||
|  | 		if (style == 3) {  //1*1
 | ||||
|  | 			if (num_type_2 < 9) {num_type_2++;} | ||||
|  | 			block[num_type_2].style = 3; | ||||
|  | 			block[num_type_2].address = addr; | ||||
|  | 			table[addr] = num_type_2; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	err:; | ||||
|  | } | ||||
|  | 
 | ||||
|  | bool Check(unsigned int Code) {  //检查编码是否合法 正确返回true 错误返回false
 | ||||
|  | 	bool temp[20]; | ||||
|  | 	unsigned char addr, i; | ||||
|  | 	Analyse_Code(Code); | ||||
|  | 
 | ||||
|  | 	for (i = 0; i < 20; i++) { | ||||
|  |         temp[i] = false;  //初始化
 | ||||
|  | 		if (table[i] > 10) {return false;}  //检查table内容是否合法
 | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	if (block[0].style != 0) {return false;}  //检查2*2块
 | ||||
|  | 	for (i = 1; i <= 5; i++) {  //检查2*1与1*2块
 | ||||
|  | 		if ((block[i].style != 1) && (block[i].style != 2)) { | ||||
|  |             return false; | ||||
|  |         } | ||||
|  | 	} | ||||
|  | 	for (i = 6; i <= 9; i++) {  //检查1*1块
 | ||||
|  | 		if (block[i].style != 3) { | ||||
|  |             return false; | ||||
|  |         } | ||||
|  | 	} | ||||
|  | 	for (i = 0; i <= 1; i++) { //检查空格
 | ||||
|  | 		if (space[i] > 19) { | ||||
|  | 			return false; | ||||
|  | 		} else { | ||||
|  | 			temp[space[i]] = true; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	addr = block[0].address;  //检查2*2块
 | ||||
|  | 	if ((addr > 14) || (addr % 4 == 3)) {return false;} | ||||
|  | 	if ((temp[addr] == true) || (temp[addr + 1] == true) || | ||||
|  | 		(temp[addr + 4] == true) || (temp[addr + 5] == true)) {return false;} | ||||
|  | 	temp[addr] = temp[addr + 1] = temp[addr + 4] = temp[addr + 5] = true; | ||||
|  | 	for (i = 1; i <= 5; i++) {  //检查2*1与1*2块
 | ||||
|  | 		addr = block[i].address; | ||||
|  | 		if (block[i].style == 1) { | ||||
|  | 			if ((addr > 18) || (addr % 4 == 3)) {return false;} | ||||
|  | 			if ((temp[addr] == true) || (temp[addr + 1] == true)) {return false;} | ||||
|  | 			temp[addr] = temp[addr + 1] = true; | ||||
|  | 		} | ||||
|  | 		if (block[i].style == 2) { | ||||
|  | 			if (addr > 15) {return false;} | ||||
|  | 			if ((temp[addr] == true) || (temp[addr + 4] == true)) {return false;} | ||||
|  | 			temp[addr] = temp[addr + 4] = true; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 	for (i = 6; i <= 9; i++) {  //检查1*1块
 | ||||
|  | 		addr = block[i].address; | ||||
|  | 		if (addr > 19) {return false;} | ||||
|  | 		if (temp[addr] == true) {return false;} | ||||
|  | 		temp[addr] = true; | ||||
|  | 	} | ||||
|  | 	return true; | ||||
|  | } | ||||
|  | 
 | ||||
|  | string Change_str(unsigned int dat) {  //将编码数据转化为字符
 | ||||
|  | 	unsigned char i, bit; | ||||
|  | 	string str = ""; | ||||
|  | 	for (i = 0; i < 7; i++) { | ||||
|  | 		bit = 0xF & dat >> (6 - i) * 4;  //分离单个十六进制位
 | ||||
|  | 		if ((bit >= 0) && (bit <= 9)) {str += bit + 48;}  //0~9
 | ||||
|  | 		if ((bit >= 0xA) && (bit <= 0xF)) {str += bit + 55;}  //A~F
 | ||||
|  | 	} | ||||
|  | 	return str; | ||||
|  | } | ||||
|  | 
 | ||||
|  | unsigned int Change_int(char str[8]) {  //将编码字符转化为int
 | ||||
|  | 	unsigned int i, dat = 0; | ||||
|  | 	for (i = 0; i < 7; i++) { | ||||
|  |         if ((str[i] >= 48) && (str[i] <= 57)) {dat |= (str[i] - 48) << (24 - i * 4);}  //0~9
 | ||||
|  | 		if ((str[i] >= 65) && (str[i] <= 70)) {dat |= (str[i] - 55) << (24 - i * 4);}  //A~F
 | ||||
|  | 		if ((str[i] >= 97) && (str[i] <= 102)) {dat |= (str[i] - 87) << (24 - i * 4);}  //a~f
 | ||||
|  | 	} | ||||
|  | 	return dat; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void Output_Graph(unsigned int Code) {  //命令行下图形化输出布局图
 | ||||
|  | 	const unsigned char Square_Width = 4;  //方块宽度
 | ||||
|  | 	const string Square_str = "[]";  //or "u2588"
 | ||||
|  | 	unsigned int i, k, m; | ||||
|  | 	unsigned int start_x, start_y, end_x, end_y; | ||||
|  | 	bool Graph[(Square_Width + 1) * 4 + 1][(Square_Width + 1) * 5 + 1];  //点阵方式储存输出图像
 | ||||
|  | 	if (Check(Code) == false) { | ||||
|  | 		cout << "The Code is Wrong!" << endl; | ||||
|  | 		return; | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	Analyse_Code(Code);  //先解析编码
 | ||||
|  | 	for (k = 0; k <= (Square_Width + 1) * 5; k++) {  //初始化
 | ||||
|  | 		for (i = 0; i <= (Square_Width + 1) * 4; i++) { | ||||
|  | 			Graph[i][k] = false; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (m = 0; m <= 9; m++) {  //遍历九个块
 | ||||
|  | 		start_x = (block[m].address % 4) * (Square_Width + 1) + 1;  //计算该块的左上角坐标
 | ||||
|  | 		start_y = int(block[m].address / 4) * (Square_Width + 1) + 1; | ||||
|  | 		if ((block[m].style == 0) || (block[m].style == 1)) {  //计算该块的右下角横坐标
 | ||||
|  | 			end_x = start_x + Square_Width * 2;  //2*2 or 2*1
 | ||||
|  | 		} else { | ||||
|  | 			end_x = start_x + Square_Width - 1;  //1*2 or 1*1
 | ||||
|  | 		} | ||||
|  | 		if ((block[m].style == 0) || (block[m].style == 2)) {  //计算该块的右下角纵坐标
 | ||||
|  | 			end_y = start_y + Square_Width * 2;  //2*2 or 1*2
 | ||||
|  | 		} else { | ||||
|  | 			end_y = start_y + Square_Width - 1;  //2*1 or 1*1
 | ||||
|  | 		} | ||||
|  | 		for (i = start_x; i <= end_x; i++) {  //填充该块覆盖的区域
 | ||||
|  | 			for(k = start_y; k <= end_y; k++) { | ||||
|  | 				Graph[i][k] = true; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | 
 | ||||
|  | 	for (i = 1; i <= (Square_Width + 1) * 4 + 3; i++) {cout << Square_str;}  //显示上边框
 | ||||
|  | 	cout << endl << Square_str; | ||||
|  | 	for (k = 0; k <= (Square_Width + 1) * 5; k++){  //显示图像内容
 | ||||
|  | 		for (i = 0; i <= (Square_Width + 1) * 4; i++) { | ||||
|  | 			if (Graph[i][k] == false){ | ||||
|  | 				cout << "  "; | ||||
|  | 			} else { | ||||
|  | 				cout << Square_str; | ||||
|  | 			} | ||||
|  | 		} | ||||
|  | 		cout << Square_str << endl << Square_str;  //显示左右边框
 | ||||
|  | 	} | ||||
|  | 	for (i = 1; i <= (Square_Width + 1) * 4 + 2; i++) {cout << Square_str;}  //显示下边框
 | ||||
|  | 	cout<<endl; | ||||
|  | } | ||||
|  | 
 | ||||
|  | void debug() {  //输出当前 table[20] block[10] space[2]的状态
 | ||||
|  | 	unsigned int i; | ||||
|  | 	for (i = 0; i < 20; i++) {  //输出table状态
 | ||||
|  | 		if (table[i] != 0xA) { | ||||
|  | 			cout << int(table[i]) << " "; | ||||
|  | 		} else { | ||||
|  | 			cout << "A "; | ||||
|  | 		} | ||||
|  | 		if (i == 3) {cout << "    00 01 02 03" << endl;} | ||||
|  | 		if (i == 7) {cout << "    04 05 06 07" << endl;} | ||||
|  | 		if (i == 11) {cout << "    08 09 10 11" << endl;} | ||||
|  | 		if (i == 15) {cout << "    12 13 14 15" << endl;} | ||||
|  | 		if (i == 19) {cout << "    16 17 18 19" << endl;} | ||||
|  | 	} | ||||
|  |     cout << endl; | ||||
|  | 	cout << "space[0] -> address=" << int(space[0]) << endl;  //输出space状态
 | ||||
|  | 	cout << "space[1] -> address=" << int(space[1]) << endl; | ||||
|  |     cout << endl; | ||||
|  | 	for (i = 0; i <= 9; i++) {  //输出block状态
 | ||||
|  | 		cout << "block[" << i << "] -> address=" << int(block[i].address); | ||||
|  |         cout << " style=" << int(block[i].style) << endl; | ||||
|  | 	} | ||||
|  | } | ||||
| @ -0,0 +1,7 @@ | |||||
|  | ### 以前的代码 | ||||
|  | 
 | ||||
|  | 很久以前就写过华容道的算法,后来基本是有需求就更新一下代码,中间断断续续有了三四个版本;之前写基本都是直接冲着需求去的,代码基本没啥注释,函数也没进行封装;前段时间由于要建数据库就全部重写了,也支持了非标布局,老代码这里就留个纪念吧。 | ||||
|  | 
 | ||||
|  | *by Dnomd343* | ||||
|  | 
 | ||||
|  | *2020.07.15* | ||||
					Loading…
					
					
				
		Reference in new issue