Linux环境下连连看游戏代码,《连连看》算法C语言演示(自动连连看)
时间: 2023-09-12 19:03:03 浏览: 74
很高兴为您提供代码,以下是一个基于C语言的自动连连看游戏算法的演示实现。该代码在Linux环境下运行。
```c
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<unistd.h>
#define ROW 10//行数
#define COL 10//列数
#define KIND 15//图案种类数目
#define MAXN 1000//最大搜索步数
#define MAXM 5000//最大连通数
int a[ROW][COL];//地图
int b[ROW*COL];//子图
int c[MAXN][2];//存储路径
int d[ROW*COL];//标记数组
int f[ROW*COL];//父节点数组
int head[ROW*COL];//链表头
int next[MAXM];//链表
int n,m;//n:总共的方块数,m:连通数
int hx,hy;//起点坐标
int tx,ty;//终点坐标
int step;//步数
int score;//得分
void init();//初始化
void print();//输出
int search(int x,int y,int t);//搜索
int bfs(int x1,int y1,int x2,int y2);//BFS
void insert(int x,int y);//插入链表
void remove(int x,int y);//删除链表
int main()
{
init();
print();
while(1)
{
printf("Please input start and end point:\n");
scanf("%d%d%d%d",&hx,&hy,&tx,&ty);
if(hx<0 || hx>=ROW || hy<0 || hy>=COL || tx<0 || tx>=ROW || ty<0 || ty>=COL)
{
printf("Invalid input!\n");
continue;
}
if(a[hx][hy]!=a[tx][ty])
{
printf("Not the same kind of block!\n");
continue;
}
step=0;
score=search(hx,hy,0);
if(score==0)
{
printf("Can't find the path!\n");
}
else
{
printf("The path is found in %d steps and the score is %d!\n",step,score);
int cur=n;
while(f[cur]!=-1)
{
c[step][0]=cur/COL;
c[step][1]=cur%COL;
cur=f[cur];
step--;
}
print();
while(step<=n)
{
remove(c[step][0],c[step][1]);
a[c[step][0]][c[step][1]]=0;
step++;
print();
sleep(1);
}
}
}
return 0;
}
void init()
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(d,0,sizeof(d));
memset(f,-1,sizeof(f));
memset(head,-1,sizeof(head));
memset(next,-1,sizeof(next));
srand((unsigned)time(NULL));
int i,j,k;
k=1;
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
{
if(rand()%100<KIND)//随机生成图案
{
a[i][j]=k++;
}
}
}
n=k-1;
int x,y;
for(i=1;i<=n;i++)
{
memset(d,0,sizeof(d));
memset(b,0,sizeof(b));
k=0;
for(x=0;x<ROW;x++)
{
for(y=0;y<COL;y++)
{
if(a[x][y]==i)
{
b[++k]=x*COL+y;
}
}
}
m=0;
for(x=1;x<=k;x++)
{
for(y=x+1;y<=k;y++)
{
if(bfs(b[x]/COL,b[x]%COL,b[y]/COL,b[y]%COL))
{
insert(b[x],b[y]);
insert(b[y],b[x]);
m++;
}
}
}
}
}
void print()
{
int i,j;
printf(" ");
for(i=0;i<COL;i++)
{
printf("%-2d",i);
}
printf("\n");
for(i=0;i<ROW;i++)
{
printf("%-2d ",i);
for(j=0;j<COL;j++)
{
if(a[i][j]==0)
{
printf(" ");
}
else
{
printf("%-2d",a[i][j]);
}
}
printf("\n");
}
}
int search(int x,int y,int t)
{
if(x==tx && y==ty)
{
return t;
}
int i,j,k,score=0;
for(i=head[x*COL+y];i!=-1;i=next[i])
{
j=i/ROW,k=i%ROW;
if(d[j]==0)
{
d[j]=1;
f[j]=x*COL+y;
score=search(j/COL,j%COL,t+1);
if(score!=0)
{
return score;
}
d[j]=0;
f[j]=-1;
}
}
return score;
}
int bfs(int x1,int y1,int x2,int y2)
{
int i,j,k;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int qx[MAXN],qy[MAXN];
int head=0,tail=0;
memset(d,0,sizeof(d));
qx[tail]=x1;
qy[tail]=y1;
d[x1*COL+y1]=1;
tail++;
while(head<tail)
{
int fx=qx[head];
int fy=qy[head];
head++;
if(fx==x2 && fy==y2)
{
return 1;
}
for(i=0;i<4;i++)
{
int nx=fx+dx[i];
int ny=fy+dy[i];
if(nx>=0 && nx<ROW && ny>=0 && ny<COL && a[nx][ny]==0 && d[nx*COL+ny]==0)
{
qx[tail]=nx;
qy[tail]=ny;
d[nx*COL+ny]=1;
tail++;
}
}
}
return 0;
}
void insert(int x,int y)
{
next[m]=head[x];
head[x]=m;
m++;
}
void remove(int x,int y)
{
int i,j,k;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
for(i=0;i<4;i++)
{
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0 && nx<ROW && ny>=0 && ny<COL && a[nx][ny]==0)
{
memset(d,0,sizeof(d));
if(bfs(x,y,nx,ny))
{
int u=x*COL+y;
int v=nx*COL+ny;
for(j=head[u];j!=-1;j=next[j])
{
if(j/ROW==v)
{
next[j]=-1;
break;
}
}
for(j=head[v];j!=-1;j=next[j])
{
if(j/ROW==u)
{
next[j]=-1;
break;
}
}
}
}
}
}
```
代码注释:
1. ROW 和 COL 定义了地图的行数和列数。
2. KIND 定义了地图中不同图案的种类数目。
3. MAXN 定义了最大搜索步数,MAXM 定义了最大连通数。
4. a 数组表示地图,b 数组表示子图,c 数组表示路径。
5. d 数组为标记数组,f 数组为父节点数组,head 数组为链表头,next 数组为链表。
6. n 表示总共的方块数,m 表示连通数。
7. hx 和 hy 表示起点坐标,tx 和 ty 表示终点坐标,step 表示步数,score 表示得分。
8. init 函数用于初始化地图和子图,print 函数用于输出地图,search 函数用于搜索路径,bfs 函数用于 BFS。
9. insert 函数用于插入链表,remove 函数用于删除链表。