C++项目实战-小游戏-连连看(CUI)

简介

最近在学可视化程序设计,选定的项目是做一个小游戏——连连看,本篇主要整理下该游戏的控制台窗口实现过程。

程序框架

main.cpp	//整个程序的入口

gamedata.h	//管理游戏数据
gamedata.cpp

gameview.h	//管理游戏界面
gameview.cpp

gamerule.h	//管理游戏规则
gamerule.cpp

因为实现过程比较简单,只贴出最终代码

main.cpp
#include <cstdlib>
#include <iostream>

#include "gamedata.h"
#include "gameview.h"
#include "gamerule.h"

using namespace std;

int main(int argc, char *argv[])
{
    //生成游戏数据
    GameData data;
    data.initData();
    
    //循环 
    int x1,y1,x2,y2;
    while(true)
    {
        //显示游戏界面
        GameView view;
        view.display();
        //用户输入坐标
        for(int j=0; j<(80-4*COL)/2; ++j)
        {
            cout<<" ";
        }
        cout<<"请输入要消除的坐标(x1 y1 x2 y2):";
        cin>>x1>>y1>>x2>>y2;
        //判断能否消除,如果可以,消除之 
        GameRule rule;
        if( rule.canClear(x1,y1,x2,y2) )
        {
            gameData[y1][x1] = 0;
            gameData[y2][x2] = 0;    
        }
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

gameview.h
class GameView
{
public:

    /***************************************************************
    *函数名:displayTitle 
    *用  途:显示游戏标题 
    *参  数:无 
    *返回值:无
    ****************************************************************/
    void displayTitle();
       
    /***************************************************************
    *函数名:display 
    *用  途:显示游戏界面 
    *参  数:无 
    *返回值:无
    ****************************************************************/
    void display();   
};

gameview.cpp
#include "gameview.h"

#include <iostream>

#include "gamedata.h"

using namespace std;

void GameView::displayTitle()
{
     cout<<"                      ***********************************"<<endl;
     cout<<"                      *      连连看游戏 ver0.1.0        *"<<endl;
     cout<<"                      *                                 *"<<endl;
     cout<<"                      *      UI设计  :赖炜             *"<<endl;
     cout<<"                      *                                 *"<<endl;
     cout<<"                      ***********************************"<<endl;
     cout<<endl;     
}

void GameView::display()
{
     system("cls");                        //执行系统清屏命令                                              
     displayTitle();
     for(int i=0; i<ROW; ++i)
        {
             for(int j=0; j<(80-4*COL)/2; ++j)
             {
                 cout<<" ";
             }
             
             for(int j=0; j<COL; ++j)
             {
                 //如果数字为0,说明已经消除,输出空格代替 
                 if(gameData[i][j]==0)
                 {
                     cout<<"    ";
                 } 
                 else 
                 {
                     //cout<<gameData[i][j];
                     printf("%4d",gameData[i][j]);
                 }
             }
             cout<<endl;
        }
}

gamedata.h
const int ROW = 4;      //游戏界面总行数 
const int COL = 4;      //游戏界面总列数 
extern int gameData[ROW][COL];

class GameData
{      
public:
    /***************************************************************
    *函数名:initData 
    *用  途:初始化游戏数据,存入数组。确保数字成对出现,顺序混乱 
    *参  数:无 
    *返回值:无
    ****************************************************************/
    void initData();
};

gamedata.cpp
#include "gamedata.h"

#include <cstdlib>
#include <iostream>

int gameData[ROW][COL];

void GameData::initData()
{   
   //成对产生数据
   int number = 0;
   for(int i=0; i<ROW; ++i)
   {
       for(int j=0; j<COL; ++j)
       {
           gameData[i][j] = number/2+1;
           ++number;    
       }
   }
   //打乱顺序 
   srand(time(NULL));   //使用当前系统时间作为随机数种子 
   for(int i=0; i<ROW*COL/2; ++i)
   {
       //随机得到两个数的坐标
       int x1 = rand()%COL;
       int y1 = rand()%ROW;
       int x2 = rand()%COL;
       int y2 = rand()%ROW;
       
       int temp = gameData[y1][x1];
       gameData[y1][x1] = gameData[y2][x2];
       gameData[y2][x2] = temp;
   }
}

gamerule.h
class GameRule
{
private:
    /***************************************************************
    *函数名:connect0 
    *用  途:判断给定的两个坐标处的数能否不转变连通 
    *参  数:int x1 - 第一个数的横坐标 
    *        int y1 - 第一个数的纵坐标
    *        int x2 - 第二个数的横坐标
    *        int y2 - 第二个数的纵坐标
    *返回值:如果可以不转变连通,返回true;否则返回false 
    ****************************************************************/
    bool connect0(int x1, int y1, int x2, int y2);

    /***************************************************************
    *函数名:connect1 
    *用  途:判断给定的两个坐标处的数能否不转变连通 
    *参  数:int x1 - 第一个数的横坐标 
    *        int y1 - 第一个数的纵坐标
    *        int x2 - 第二个数的横坐标
    *        int y2 - 第二个数的纵坐标
    *返回值:如果可以不转变连通,返回true;否则返回false 
    ****************************************************************/
    bool connect1(int x1, int y1, int x2, int y2);


public:
    /***************************************************************
    *函数名:canClear 
    *用  途:判断给定的两个坐标处的数能否消除 
    *参  数:int x1 - 第一个数的横坐标 
    *        int y1 - 第一个数的纵坐标
    *        int x2 - 第二个数的横坐标
    *        int y2 - 第二个数的纵坐标
    *返回值:如果可以消,返回true;否则返回false 
    ****************************************************************/
    bool canClear(int x1, int y1, int x2, int y2);
};

gamerule.cpp
#include "gamerule.h"
#include "gamedata.h"

bool GameRule::canClear(int x1, int y1, int x2, int y2)
{
    //如果两次选择的坐标相同,不能消
    if( x1 == x2 && y1 == y2 )
    {
        return false;
    }
     
    //如果两个数字不一样,不能消
    if(gameData[y1][x1]!=gameData[y2][x2])
    {
        return false;
    }
     
    //如果可以不转弯连通 
    if( connect0(x1,y1,x2,y2) )
    {
        return true;
    }
    
    //如果可以转一次弯连通
    if( connect1(x1,y1,x2,y2) )
    {
        return true;
    } 
    
    return false;
}  
    
bool GameRule::connect0(int x1, int y1, int x2, int y2)
{
    //如果在同一行
    if(y1 == y2)
    {
        int y = y1;
        //循环遍历中间所有数的坐标,累加
        int sum = 0;
        //确保x1一定小于x2
        if(x1>x2)
        {
            int temp = x1;
            x1 = x2;
            x2 = temp;        
        } 
        for(int x=x1+1; x<x2; ++x)
        {
            sum += gameData[y][x];        
        } 
        if(0==sum)      //说明中间所有数都为0
        {
            return true;
        } 
    }  
    //如果在同一列
    if(x1 == x2)
    {
        int x = x1;
        //循环遍历中间所有数的坐标,累加
        int sum = 0;
        //确保y1一定小于y2
        if(y1>y2)
        {
            int temp = y1;
            y1 = y2;
            y2 = temp;        
        } 
        for(int y=y1+1; y<y2; ++y)
        {
            sum += gameData[y][x];        
        } 
        if(0==sum)      //说明中间所有数都为0
        {
            return true;
        } 
    }  
     
    return false;            
}

bool GameRule::connect1(int x1, int y1, int x2, int y2)
{
    //通过x2,y1转
    // (x1,y1)~(x2,y1) && (x2,y1)~(x2,y2) && (x2,y1)==0
    if(connect0(x1,y1,x2,y1) && connect0(x2,y1,x2,y2) && gameData[y1][x2]==0 )
    {
        return true;
    }
    
    //通过x1,y2转 
    if(connect0(x1,y1,x1,y2) && connect0(x1,y2,x2,y2) && gameData[y2][x1]==0)
    {
        return true;                         
    }
    
    return false;
}




转载于:https://www.cnblogs.com/tryitboy/p/4231156.html

连连看c 是一款基于C语言开发的连连看游戏。下面是一段简单的连连看c 的源代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define ROW 4 #define COLUMN 4 char gameBoard[ROW][COLUMN] = { // 游戏棋盘 {'A', 'B', 'C', 'D'}, {'A', 'C', 'B', 'D'}, {'E', 'F', 'G', 'H'}, {'E', 'H', 'G', 'F'} }; bool visited[ROW][COLUMN] = {false}; // 记录是否已访问的数组 bool checkConnection(int r1, int c1, int r2, int c2) { // 检查两个方块是否可以连接 if (r1 == r2 && c1 == c2) return false; if (gameBoard[r1][c1] != gameBoard[r2][c2]) return false; if (r1 == r2) { // 在同一行 int minC = c1 < c2 ? c1 : c2; int maxC = c1 > c2 ? c1 : c2; for (int j = minC + 1; j < maxC; j++) { if (visited[r1][j] == true || gameBoard[r1][j] != ' ') return false; } } else if (c1 == c2) { // 在同一列 int minR = r1 < r2 ? r1 : r2; int maxR = r1 > r2 ? r1 : r2; for (int i = minR + 1; i < maxR; i++) { if (visited[i][c1] == true || gameBoard[i][c1] != ' ') return false; } } else { // 不在同一行也不在同一列 if (visited[r1][c2] == false && gameBoard[r1][c2] == ' ') { if (checkConnection(r1, c1, r1, c2) && checkConnection(r1, c2, r2, c2)) return true; } if (visited[r2][c1] == false && gameBoard[r2][c1] == ' ') { if (checkConnection(r1, c1, r2, c1) && checkConnection(r2, c1, r2, c2)) return true; } return false; } return true; } bool dfs(int r1, int c1, int r2, int c2) { // 深度优先搜索查找连接路径 if (checkConnection(r1, c1, r2, c2)) { return true; } visited[r1][c1] = true; visited[r2][c2] = true; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COLUMN; j++) { if (i == r1 && j == c1) continue; if (i == r2 && j == c2) continue; if (visited[i][j] == true || gameBoard[i][j] == ' ') continue; if (dfs(r1, c1, i, j) && dfs(i, j, r2, c2)) { return true; } } } visited[r1][c1] = false; visited[r2][c2] = false; return false; } int main() { int r1, c1, r2, c2; // 需要连接的两个方块的坐标 printf("请输入需要连接的两个方块的坐标(示例:1 2 3 2):"); scanf("%d %d %d %d", &r1, &c1, &r2, &c2); if (dfs(r1, c1, r2, c2)) { printf("可以连接。\n"); } else { printf("无法连接。\n"); } return 0; } ``` 以上代码实现了一个简单的连连看游戏,包括棋盘的初始化、连接验证、深度优先搜索等功能。可以通过输入两个方块的坐标,判断它们是否可以连通。该示例中的游戏棋盘是一个4x4的二维数组,每个方块用字符表示。游戏的核心逻辑在函数`checkConnection`和`dfs`中实现。在运行程序时,需要输入两个方块的坐标来进行验证。如果可以连接,则输出"可以连接",否则输出"无法连接"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值