C语言构建连连看游戏(矩阵方式)

时间:2021-11-30 04:50:48

C语言构建连连看游戏的具体代码,供大家参考,具体内容如下

设计要求

用数字+英文字母,采用文本输出的方式。每次输出一个8*10的矩形,然后等待玩家输入两个数字或字母的坐标,如果满足消除规则就输出新的矩形。
注意:考虑类似迷宫的处理方式,在8 * 10矩形之外加一层空心围墙,可以用来连接。大家体验一下连连看游戏就可以发现这个规则。判断是否能连,用的是10 *12的数组,最外层添加的是空格,可用来辅助连接。

分析

大纲(简化):

/**********************************/
 //1生成游戏桌面*
  //1.1选项
 //2生成游戏局*
 //3游戏操作
  //3.1选择方块
  //3.2判断是否有路径*
  //3.3修改矩阵图层和迷宫图层
  //3.4刷新页面
 //4游戏胜利条件
  //4.1时间限制
  //4.2游戏结束
  //4.3结算游戏*

/********************************/

本设计采用了双图层的思路,分别设计显示图层与连连看内部游戏图层。
显示图层方便用户操作,
内部游戏图层方便进行连连看消除处理。

设计

生成游戏桌面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<Windows.h>    //生成游戏界面
#include<stdio.h>
#define GameWindoHight 16
#define GameWindoWidth 75
 
void GameInit()  //生成游戏主界面
{
 //界定游戏桌面大小
 char chCmd[32];
 sprintf(chCmd,"mode con cols=%d lines=%d",GameWindoWidth,GameWindoHight);
 system(chCmd);
 
 //游戏引导
 printf("\t\t\t欢迎进入矩阵连连看游戏");    printf("\n\n");
 printf("\t\t\t---- 游戏开始----\t\t");     printf("\n\n");
 printf("\t\t\t  请选择游戏模式 \t\t");     printf("\n\n");
 printf("\t\t\t----1基本模式----\t\t");     printf("\n");  //正向计时
 printf("\t\t\t----2休闲模式----\t\t");     printf("\n");  //不计时
 printf("\t\t\t----3关卡模式----\t\t");     printf("\n\n");  //倒计时
 printf("\t\t\t----4退出游戏----\t\t");     printf("\n");  //退出程序
}

生成游戏局

内部(迷宫)图层:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define MaxSize 100
int mg[10][12]= {  //迷宫图层
 {0,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,0,0,0,0,0,0,0,0,0,0,0}
 };
 struct MMP
{
 int i,j;   //位置
 int di;    //下一步可走
} St[MaxSize];
 
bool mgpath(int xi, int yi, int xe, int ye)   //判断是否有路径
int i,j, i1,j1,di;
 int mg1[10][12];
 memcpy(mg1,mg,sizeof(mg));
 bool find;
 int top=-1;
 top++;
 St[top].i=xi;
 St[top].j=yi;
 St[top].di=-1;
 mg1[xi][yi]=-1;
 mg1[xe][ye]=0;
 while (top>-1)
 {  i= St[top].i;j= St[top].j;
  di=St[top].di;
  if (i==xe&& j== ye)
  {
   return true;
  }
  find= false;
  while (di<4 && !find)
  {
   di++;
   switch(di)
   {
    case 0:i1=i-1; j1=j;break;
    case 1:i1=i;j1=j+1; break;
    case 2:i1=i+1; j1=j;break;
    case 3:i1=i;j1=j-1; break;
   }
   if(i1<12&&j1<10)
   {
    if (mg1[i1][j1]==0) find=true;
   }
  }
  if (find)
  { St[top].di=di;
   top++;St[top].i=i1;St[top].j=j1;
   St[top].di= - 1;
   mg1[i1][j1]= -1;
  }
  else
  {
   mg1[i][j]=0;
   top-- ;
  }
 }
 return false;
}

用户(棋局)图层:

棋子生成阶段:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
typedef struct pieces
{
 int data_num;
 int data_letter;
} Piece;    //棋子
 
typedef struct rand_factor
{
 int data;
 int data_times;
} factor;    //随机因子属性——用于随机棋子
 
 void Rand_Num(int a[],int Num_Range,int T)  //生成棋子属性——作为棋子生成阶段的一部分
{
 srand((unsigned)time(NULL));//生成随机数种子
 int n=0;
 int i=0;
 factor b[Num_Range];
 for(int ii=0;ii<Num_Range;ii++)
 {
//  b[ii].data=ii;    
  b[ii].data_times=0;
 }
 while(n<Num_Range*T){
  int m=rand()%Num_Range;
  if(b[m].data_times<T){
   a[i]=m;
   b[m].data_times++;
   m=rand()%Num_Range;
   i++;
   n++;
  }
  else
   continue;
 }
 }
 
 void ChesspiecesInit(Piece* pieces)  //棋子生成
{
 
 int data_num[80];
 Rand_Num(data_num,10,8);
 int Num_Range=10;
 for(int num=0;num<Num_Range*8;num++)
 {
  pieces[num].data_num=data_num[num];   //数值
 }
 
 for(int i=0;i<Num_Range;i++)
 {
  int letter[8];
  Rand_Num(letter,8,1);
  int k=0;
  int j=0;
  while(k<8)
  {
   if(pieces[j].data_num==i)
   {
    pieces[j].data_letter=letter[k]; //颜色
    k++;
   }
   j++;
  }
 }
}

棋盘生成阶段

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void CameBordInit(Piece* pieces)
{
 for(int i=0;i<10;i++)
  printf("------%d",i+1);
 printf("\n");
 for(int i=0;i<8;i++)
 {
  printf("[%d]",i+1);
  for(int j=0;j<10;j++)
  {
   if(pieces[j+i*10].data_num!=10&&pieces[j+i*10].data_letter!=10)
    printf(" <%d,%c> ",pieces[j+i*10].data_num,35+pieces[j+i*10].data_letter%4);
   else
    printf(" <*v*> ");   //本来想打空格的,可是这个表情太可爱了!(可以选择全空格输出,界面会清晰一点
  }
  printf("\n");
 }
}

游戏操作

选择——简单粗暴

?
1
2
scanf("%d,%d",&x1,&y1);
scanf("%d,%d",&x2,&y2);

判断路径等行为发生在迷宫图层:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
bool mgpath(int xi, int yi, int xe, int ye)
int i,j, i1,j1,di;
 int mg1[10][12];
 memcpy(mg1,mg,sizeof(mg));
 bool find;
 int top=-1;
 top++;
 St[top].i=xi;
 St[top].j=yi;
 St[top].di=-1;
 mg1[xi][yi]=-1;
 mg1[xe][ye]=0;
 while (top>-1)
 {  i= St[top].i;j= St[top].j;
  di=St[top].di;
  if (i==xe&& j== ye)
  {
   return true;
  }
  find= false;
  while (di<4 && !find)
  {
   di++;
   switch(di)
   {
    case 0:i1=i-1; j1=j;break;
    case 1:i1=i;j1=j+1; break;
    case 2:i1=i+1; j1=j;break;
    case 3:i1=i;j1=j-1; break;
   }
   if(i1<12&&j1<10)
   {
    if (mg1[i1][j1]==0) find=true;
   }
  }
  if (find)
  { St[top].di=di;
   top++;St[top].i=i1;St[top].j=j1;
   St[top].di= - 1;
   mg1[i1][j1]= -1;
  }
  else
  {
   mg1[i][j]=0;
   top-- ;
  }
 }
 return false;
}

修改显示图层:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void GamePlay(int x1,int y1,int x2,int y2,Piece* pieces)
{
 if(pieces[y1*10+x1].data_num==pieces[y2*10+x2].data_num)
  if(abs(pieces[y1*10+x1].data_letter-pieces[y2*10+x2].data_letter)==4)
  {
   if(mgpath(x1+1, y1+1, x2+1, y2+1))
   {
    pieces[y1*10+x1].data_letter=pieces[y1*10+x1].data_num=pieces[y2*10+x2].data_letter=pieces[y2*10+x2].data_num=10;
    mg[x1+1][y1+1]=mg[x2+1][y2+1]=0;
   }
  }
}
  //配合上棋盘生成函数中的
 else
  printf(" <*v*> ");

刷新界面用:

?
1
system("cls");  //简单粗暴

游戏胜利(结束)

判断结束:(暂不解释,看代码理解)

1.时间限制
2.自主退出

时间限制使用系统计时
自动退出引导用户输入特定符号

游戏结算:输出分数

?
1
2
3
4
5
6
7
8
void Game_Score()
{
 int score=80;
 for(int i=0;i<10;i++)
  for(int j=0;j<12;j++)
   score=score-mg[i][j];
 printf("\t\t\t您现在的得分是:%d \n",score);
}

完整程序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/*******************************************************************/
 //1生成游戏桌面
  //1.1选项
 //2生成游戏局
 //3游戏操作
  //3.1选择方块
  //3.2判断是否有路径
  //3.3判断是否消除
  //3.4消除并刷新页面
 //4游戏胜利条件
  //4.1时间限制
  //4.2游戏结束
  //4.3判断是否胜利
 
/*******************************************************************/
#include<Windows.h>    //生成游戏界面
#include<stdio.h>
#define GameWindoHight 16
#define GameWindoWidth 75
 
#include<stdio.h>  //生成棋局图层
#include<time.h>
#include<stdlib.h>
 
#include"sqstack.cpp"
 
#include<time.h>
 
#define MaxSize 100
typedef struct rand_factor
{
 int data;
 int data_times;
} factor;    //随机到你了吗?
 
typedef struct pieces
{
 int data_num;
 int data_letter;
} Piece;
 
int mg[10][12]= {  //路径图层
 {0,0,0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,1,1,1,1,1,1,1,1,1,1,0},
 {0,0,0,0,0,0,0,0,0,0,0,0}
 };
 
struct MMP
{
 int i,j;
 int di;
} St[MaxSize];
 
double DDL=600;
 
 //1生成游戏桌面
void GameInit()
{
 //界定游戏桌面大小
 char chCmd[32];
 sprintf(chCmd,"mode con cols=%d lines=%d",GameWindoWidth,GameWindoHight);
 system(chCmd);
 
// printf("-----------------李云龙应约召唤而来!---------------");printf("\n");
// printf("-------------你他娘的就是老子的Master吗?-----------");printf("\n\n");
 //游戏引导
 printf("\t\t      欢迎进入矩阵连连看游戏");    printf("\n\n");
 printf("\t\t\t---- 游戏开始----\t\t");     printf("\n\n");
 printf("\t\t\t  请选择游戏模式 \t\t");     printf("\n\n");
 printf("\t\t\t----1基本模式----\t\t");     printf("\n");  //正向计时
 printf("\t\t\t----2休闲模式----\t\t");     printf("\n");  //不计时
 printf("\t\t\t----3关卡模式----\t\t");     printf("\n");  //倒计时
// printf("\t\t----4米斯达骂骂咧咧地退出房间了……"); printf("\n");  //退出程序
 printf("\t\t\t----4退出游戏----\t\t");     printf("\n");  //退出程序
}
 //生成棋局
void Rand_Num(int a[],int Num_Range,int T)
{
 srand((unsigned)time(NULL));//生成随机数的种子
 int n=0;
 int i=0;
 factor b[Num_Range];
 for(int ii=0;ii<Num_Range;ii++)
 {
//  b[ii].data=ii;    
  b[ii].data_times=0;
 }
 while(n<Num_Range*T){
  int m=rand()%Num_Range;
  if(b[m].data_times<T){
   a[i]=m;
   b[m].data_times++;
   m=rand()%Num_Range;
   i++;
   n++;
  }
  else
   continue;
 }
 }
 
void ChesspiecesInit(Piece* pieces)
{
 
 int data_num[80];
 Rand_Num(data_num,10,8);
 int Num_Range=10;
 for(int num=0;num<Num_Range*8;num++)
 {
  pieces[num].data_num=data_num[num];   //数值
 }
 
 for(int i=0;i<Num_Range;i++)
 {
  int letter[8];
  Rand_Num(letter,8,1);
  int k=0;
  int j=0;
  while(k<8)
  {
   if(pieces[j].data_num==i)
   {
    pieces[j].data_letter=letter[k]; //颜色
    k++;
   }
   j++;
  }
 }
}
 
void CameBordInit(Piece* pieces)
{
 for(int i=0;i<10;i++)
  printf("------%d",i+1);
 printf("\n");
 for(int i=0;i<8;i++)
 {
  printf("[%d]",i+1);
  for(int j=0;j<10;j++)
  {
   if(pieces[j+i*10].data_num!=10&&pieces[j+i*10].data_letter!=10)
    printf(" <%d,%c> ",pieces[j+i*10].data_num,35+pieces[j+i*10].data_letter%4);
   else
    printf(" <*v*> ");
  }
  printf("\n");
 }
}
 
bool mgpath(int xi, int yi, int xe, int ye)
int i,j, i1,j1,di;
 int mg1[10][12];
 memcpy(mg1,mg,sizeof(mg));
 bool find;
 int top=-1;
 top++;
 St[top].i=xi;
 St[top].j=yi;
 St[top].di=-1;
 mg1[xi][yi]=-1;
 mg1[xe][ye]=0;
 while (top>-1)
 {  i= St[top].i;j= St[top].j;
  di=St[top].di;
  if (i==xe&& j== ye)
  {
   return true;
  }
  find= false;
  while (di<4 && !find)
  {
   di++;
   switch(di)
   {
    case 0:i1=i-1; j1=j;break;
    case 1:i1=i;j1=j+1; break;
    case 2:i1=i+1; j1=j;break;
    case 3:i1=i;j1=j-1; break;
   }
   if(i1<12&&j1<10)
   {
    if (mg1[i1][j1]==0) find=true;
   }
  }
  if (find)
  { St[top].di=di;
   top++;St[top].i=i1;St[top].j=j1;
   St[top].di= - 1;
   mg1[i1][j1]= -1;
  }
  else
  {
   mg1[i][j]=0;
   top-- ;
  }
 }
 return false;
}
 
void GamePlay(int x1,int y1,int x2,int y2,Piece* pieces)
{
 if(pieces[y1*10+x1].data_num==pieces[y2*10+x2].data_num)
  if(abs(pieces[y1*10+x1].data_letter-pieces[y2*10+x2].data_letter)==4)
  {
   if(mgpath(x1+1, y1+1, x2+1, y2+1))
   {
    pieces[y1*10+x1].data_letter=pieces[y1*10+x1].data_num=pieces[y2*10+x2].data_letter=pieces[y2*10+x2].data_num=10;
    mg[x1+1][y1+1]=mg[x2+1][y2+1]=0;
   }
  }
}
 
void Game_Score()
{
 int score=80;
 for(int i=0;i<10;i++)
  for(int j=0;j<12;j++)
   score=score-mg[i][j];
 printf("\t\t\t您现在的得分是:%d \n",score);
}
 
int main()
{
 //生成游戏桌面
 GameInit();
 //选择游戏模式
 int Gmode;
 int x1,y1,x2,y2;
 double time,end;
 scanf("%d",&Gmode);
 //刷新界面->进入游戏
 clock_t start;
 start=clock();
 Piece pieces[80];
 ChesspiecesInit(pieces);
 while(1)
 {
  end = clock();
  system("cls");
/***************************************************/
 switch(Gmode)                           //其他模式配件
 {
  case 1:
   printf("当前游戏时间:%f s\n\n",(double)(end-start)/CLK_TCK);break;
  case 3:
   time=DDL-(double)(end-start)/CLK_TCK;
   printf("剩余游戏时间:%f\t\t\t(输入qqqq结束游戏\n\n",time);
   if(time<0)
   {
    printf("游戏结束!交作业的小伙伴给个三连吧,要不评论区下次一定?<*v*>\n");
    Game_Score();
    return 0;
   };break;
  case 4:
   printf("?!?!?!?\n");
   printf("  我自闭了!");
   return 0;
 }
 
 
/****************娱乐模式主体***********************/
  Game_Score();
  CameBordInit(pieces); 
  scanf("%d,%d",&x1,&y1);
  scanf("%d,%d",&x2,&y2);
  if(x1=='q')
  {
   Game_Score();
   return 0;
  }
  x1=x1-1;y1=y1-1;
  x2=x2-1;y2=y2-1;
  GamePlay(x1,y1,x2,y2,pieces);
 
 }
 
 return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/weixin_44486547/article/details/105804874