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

 更新时间:2021年09月10日 10:36:39   作者:晴松-  
这篇文章主要为大家详细介绍了C语言构建连连看游戏,采用矩阵方式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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结算游戏*

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

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

设计

生成游戏桌面

#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");  //退出程序
}

生成游戏局

内部(迷宫)图层:

#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;
}

用户(棋局)图层:

棋子生成阶段:

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++;
  }
 }
} 

棋盘生成阶段

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");
 }
}

游戏操作

选择——简单粗暴

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

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

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;
   } 
  }
}
  //配合上棋盘生成函数中的
 else
  printf(" <*v*> "); 

刷新界面用:

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

游戏胜利(结束)

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

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

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

游戏结算:输出分数

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生成游戏桌面
  //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;
} 

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

相关文章

  • C语言中网络地址与二进制数之间转换的函数小结

    C语言中网络地址与二进制数之间转换的函数小结

    这篇文章主要介绍了C语言中网络地址与二进制数之间转换的函数小结,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • 详解C语言的exp()函数和ldexp()函数以及frexp()函数

    详解C语言的exp()函数和ldexp()函数以及frexp()函数

    这篇文章主要介绍了详解C语言的exp()函数和ldexp()函数以及frexp()函数,注意这三个函数虽然看起来相似但实际功能却大相径庭!需要的朋友可以参考下
    2015-08-08
  • C++中的RAII机制详解

    C++中的RAII机制详解

    这篇文章主要介绍了C++中的RAII机制详解,RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源、避免泄漏的惯用法,需要的朋友可以参考下
    2014-09-09
  • C++中双冒号::用法案例详解

    C++中双冒号::用法案例详解

    这篇文章主要介绍了C++中双冒号::用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • CRITICAL_SECTION用法案例详解

    CRITICAL_SECTION用法案例详解

    这篇文章主要介绍了CRITICAL_SECTION用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • c++通过引用实现三个数字求最大值

    c++通过引用实现三个数字求最大值

    下面我们将通过这个例子来说明引用的作为函数参数的使用方法。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • C++实现屏幕截图

    C++实现屏幕截图

    这篇文章主要为大家详细介绍了C++实现屏幕截图功能,截图自动保存为png格式文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • 实例解析C++中类的成员函数指针

    实例解析C++中类的成员函数指针

    这篇文章主要介绍了C++中类的成员函数指针,例子中以讨论用函数指针调用类的成员函数为主,需要的朋友可以参考下
    2016-04-04
  • C语言字符串快速压缩算法代码

    C语言字符串快速压缩算法代码

    这篇文章主要介绍了C语言字符串快速压缩算法代码,将字符串中连续出席的重复字母进行压缩,其主要的压缩字段的格式为”字符重复的次数+字符”。有需要的小伙伴参考下吧。
    2015-03-03
  • 深入分析Linux下如何对C语言进行编程

    深入分析Linux下如何对C语言进行编程

    本篇文章介绍了,如何在Linux下对C语言进行编程的详细概述。需要的朋友参考下
    2013-05-05

最新评论