#include <iostream> #include <ctime> #include <cstdlib> using namespace std; #define Len 4//连连看矩阵长与宽 #define White -1//格子无图案 #define Black -11 //有图案 #define Line_Connect 99//可以直线连通或者可以从源直线连通 #define Line_Un_Connect 98//不能从源直线连通 #define Two_Connect 88//拐弯1次 #define Three_Connect 77//拐弯2次 #define Possible 66//仍有可能连通,只有0拐,1拐返回这种标示 #define Bound 1 //格子属于连连看矩阵的周边界,没有图案,但连线可以经过 #define Not_Bound -1 //格子不属于边界,可以有图案,连线也可以通过 #define No_Solution 55 //没有任何一种连通方式 typedef struct _Cell_Node //节点 { int value; //代表图案类型:用0....25表示A....Z图案,(char)(value+65)表示相应字母,-1(White)表示无图案 int row; int col; int con_flag; //从源开始的十字形上的节点是否可以到达,这对3次拐弯检测起作用 int bou_flag; struct _Cell_Node *next; }Cell_Node; typedef struct _Cell_List //相同图案链表 { int count; Cell_Node *first; }Cell_List; typedef struct _Path { Cell_Node *from; Cell_Node *to; Cell_Node *corner1; Cell_Node *corner2; }Path; Cell_Node gra_cell[Len+2][Len+2];// 连连看矩阵,存放的是节点指针 Cell_List gra_list[26]; //同类图形链表数组. Cell_Node* get_cell(int row,int col) //row,col皆为实际数组下标 { //return reinterpret_cast<Cell_Node*>(gra_cell+row*(Len+2)+col); return &gra_cell[row][col]; } // 直线连通判断 int check_line_connect(Cell_Node *from,Cell_Node *to) { int row1=from->row; int row2=to->row; int col1=from->col; int col2=to->col; int step; if(row1==row2) { step=col1<col2? 1:-1; } else if(col1==col2) { step=row1<row2? (Len+2):-(Len+2); } else { return Possible; } Cell_Node *temp=from+step; while(temp!=to) { if(temp->value!=White) { return Possible; } temp=temp+step; } return Line_Connect; } int check_two_connect(Cell_Node *from,Cell_Node *to,Cell_Node *&turn) { if(from->row==to->row) { return Possible; } if(from->col==to->col) { return Possible; } Cell_Node* corner; //拐角点 corner=get_cell(from->row,to->col); if(corner->value==White) { if(check_line_connect(from,corner)==Line_Connect&&check_line_connect(corner,to)==Line_Connect) { turn=corner; return Two_Connect; } } corner=get_cell(to->row,from->col); if(corner->value==White) { if(check_line_connect(from,corner)==Line_Connect&&check_line_connect(corner,to)==Line_Connect) { turn=corner; return Two_Connect; } } return Possible; } void make_line_connect_flag(Cell_Node *s) { int row=s->row; int col=s->col; Cell_Node *temp; int step; for(int i=0;i<=3;++i) { switch(i) { case 0:step=1;break; case 1:step=-1;break; case 2:step=Len+2;break; case 3:step=-Len-2;break; } temp=s+step; while(temp->value==White) { temp->con_flag=Line_Connect; if(temp->bou_flag==Bound) { break; } temp=temp+step; } } } void clear_flag() { for(int i=0;i<Len+2;++i) { for(int j=0;j<Len+2;++j) { gra_cell[i][j].con_flag=Line_Un_Connect; } } } int check_three_connect(Cell_Node *from,Cell_Node *to,Cell_Node *&turn1,Cell_Node *&turn2) { clear_flag(); make_line_connect_flag(from); make_line_connect_flag(to); int row1=from->row; int row2=to->row; int col1=from->col; int col2=to->col; //沿横向平行线自左至右检测,但是如果所在行相同,那么这样就没意义了 if(row1!=row2) { for(int col=0;col<Len+2;++col) { Cell_Node *p=get_cell(row1,col); Cell_Node *q=get_cell(row2,col); if(p->con_flag==Line_Connect&&q->con_flag==Line_Connect&&check_line_connect(p,q)==Line_Connect) { turn1=p; turn2=q; return Three_Connect; } } } //沿纵向平行线自顶向下检测,如果所在列相同,那么这样就没意义了 if(col1!=col2) { for(int row=0;row<Len+2;++row) { Cell_Node *p=get_cell(row,col1); Cell_Node *q=get_cell(row,col2); if(p->con_flag==Line_Connect&&q->con_flag==Line_Connect&&check_line_connect(p,q)==Line_Connect) { turn1=p; turn2=q; return Three_Connect; } } } return No_Solution; } int check_input(Cell_Node *from,Cell_Node *to) { if(from->value==White||to->value==White||from==to||from->row==0||from->row==Len+1||from->col==0||from->col==Len+1|| to->row==0||to->row==Len+1||to->col==0||to->col==Len+1) { return No_Solution; } else { return Possible; } } void set_path(Path *path,Cell_Node *from,Cell_Node *to,Cell_Node *turn1,Cell_Node *turn2) { path->from=from; path->to=to; path->corner1=turn1; path->corner2=turn2; } int check_connect(Cell_Node *from,Cell_Node *to,Path *path) { Cell_Node *turn1=NULL; Cell_Node *turn2=NULL; if(check_input(from,to)==No_Solution) { return No_Solution; } else { if(check_line_connect(from,to)==Line_Connect) { set_path(path,from,to,turn1,turn2); return Line_Connect; } if(check_two_connect(from,to,turn1)==Two_Connect) { set_path(path,from,to,turn1,turn2); return Two_Connect; } if(check_three_connect(from,to,turn1,turn2)==Three_Connect) { set_path(path,from,to,turn1,turn2); return Three_Connect; } return No_Solution; } } int check_die(Path *path) { srand((unsigned int)time(0)); int rand_gra=rand()%26; for(int k=0;k<26;++k) { if(rand_gra==26) { rand_gra=0; } if(gra_list[rand_gra].count!=0) { Cell_Node *temp=gra_list[rand_gra].first; while(temp!=NULL&&temp->next!=NULL) { Cell_Node *next_temp=temp->next; while(next_temp!=NULL) { int flag=check_connect(temp,next_temp,path); if(flag!=No_Solution) { return flag; } next_temp=next_temp->next; } temp=temp->next; } } ++rand_gra; } return No_Solution; } void create_gra() { cout<<"Game starts!"<<endl; srand((unsigned int)time(0)); for(int i=0;i<26;++i) { gra_list[i].count=0; gra_list[i].first=NULL; } for(int i=0;i<Len+2;++i) { for(int j=0;j<Len+2;++j) { gra_cell[i][j].bou_flag=(i==0||j==0||i==Len+1||j==Len+1) ? Bound:Not_Bound; gra_cell[i][j].row=i; gra_cell[i][j].col=j; gra_cell[i][j].next=NULL; gra_cell[i][j].con_flag=Line_Un_Connect; gra_cell[i][j].value=(i==0||j==0||i==Len+1||j==Len+1) ? White:rand()%26; if(!(i==0||j==0||i==Len+1||j==Len+1)) { ++gra_list[gra_cell[i][j].value].count; gra_cell[i][j].next=gra_list[gra_cell[i][j].value].first; gra_list[gra_cell[i][j].value].first=&gra_cell[i][j]; } } } } void exchange(int max,int min) { --gra_list[max].count; Cell_Node *temp=gra_list[max].first; gra_list[max].first=gra_list[max].first->next; temp->next=gra_list[min].first; gra_list[min].first=temp; temp->value=min; //更改图片! ++gra_list[min].count; } void adjust_average(int differ) //修正连连看平衡性 { int max_gra,min_gra,max_cnt=-1,min_cnt=999; while(true) { for(int i=0;i<26;++i) { if(gra_list[i].count>=max_cnt) { max_gra=i; max_cnt=gra_list[i].count; } if(gra_list[i].count<min_cnt) { min_gra=i; min_cnt=gra_list[i].count; } } if(max_cnt-min_cnt<=differ) { break; } exchange(max_gra,min_gra); max_cnt=-1; min_cnt=999; } } void adjust_even()//修正每种图片为偶数个 { int min_gra,max_gra,min_cnt=999,max_cnt=-1,total=0; while(true) { total=0; max_cnt=-1; min_cnt=999; for(int i=0;i<26;++i) { if(gra_list[i].count%2==1) { if(gra_list[i].count>=max_cnt) { max_cnt=gra_list[i].count; max_gra=i; } if(gra_list[i].count<min_cnt) { min_cnt=gra_list[i].count; min_gra=i; } ++total; } } if(total==0) { break; } exchange(max_gra,min_gra); } } void clear_connect(Path *path) { Cell_Node *temp=gra_list[path->from->value].first; if(temp==path->from) { gra_list[path->from->value].first=gra_list[path->from->value].first->next; } else { while(temp->next!=NULL) { if(temp->next==path->from) { temp->next=temp->next->next; break; } temp=temp->next; } } temp=gra_list[path->to->value].first; if(temp==path->to) { gra_list[path->to->value].first=gra_list[path->to->value].first->next; } else { while(temp->next!=NULL) { if(temp->next==path->from) { temp->next=temp->next->next; break; } temp=temp->next; } } path->from->value=White; path->to->value=White; } void print_gra() { for(int i=0;i<Len+2;++i) { if(i==Len+1) { break; } for(int j=0;j<Len+2;++j) { if(j==Len+1) {continue;} if(i==0&&j==0) { cout<<" "; continue; } if(i==0&&j!=0) { cout<<" "<<j; continue; } if(i!=0&&j==0) { if(i!=10) { cout<<" "; cout<<i; continue; } else { cout<<i; continue; } } if(i!=Len+1&&j!=Len+1) { if(gra_cell[i][j].value!=White) { cout<<" "<<(char)(gra_cell[i][j].value+65); } else { cout<<" "<<" "; } } } cout<<endl; } } int main() { int row1,col1,row2,col2; Cell_Node *f,*t; Path path1,path2; int count=Len*Len; create_gra(); cout<<"平衡调整前-->地图显示:"<<endl; print_gra(); cout<<"图片数量平衡调整后-->地图显示:"<<endl; adjust_average(1); print_gra(); cout<<"图片偶数性平衡调整后-->地图显示:"<<endl; adjust_even(); print_gra(); cout<<"初次检查此图是否可解,Loading........"<<endl; while(check_die(&path2)==No_Solution) { cout<<"此图无解,现在重新生成地图!"<<endl; create_gra(); cout<<"平衡调整前-->地图显示:"<<endl; print_gra(); cout<<"图片数量平衡调整后-->地图显示:"<<endl; adjust_average(4); print_gra(); cout<<"图片偶数性平衡调整后-->地图显示:"<<endl; adjust_even(); print_gra(); cout<<"检查此图是否可解,Loading........"<<endl; } cout<<"游戏现在开始!请按提示录入您要消去的两个同图案的格子!"<<endl; while(count!=0) { int choose; cout<<"您可以选择系统提示您,需要输入1,否则输入0:"; cin>>choose; if(choose==1) { clear_connect(&path2); cout<<"帮你清理一对了哦!"<<endl; print_gra(); if(check_die(&path2)==No_Solution) { cout<<"没有可以消的格子了,游戏结束吧!"<<endl; return 0; } else { continue; } } else { cout<<"输入x1,y1,x2,y2,按回车结束!"<<endl; cin>>row1>>col1>>row2>>col2; f=get_cell(row1,col1); t=get_cell(row2,col2); if(check_connect(f,t,&path1)!=No_Solution) { clear_connect(&path1); cout<<"消除成功!"<<endl; print_gra(); if(f==path2.from||t==path2.to||f==path2.to||t==path2.from) { if(check_die(&path2)==No_Solution) { cout<<"没有可以消的格子了,游戏结束吧!"<<endl; return 0; } } } else { cout<<"无法消去,重新输入,"; } } } return 0; } 当然,我没能力分析出整个问题,还是参考别人的思想实现的:http://blog.sina.com.cn/wyw1976.