zoukankan      html  css  js  c++  java
  • 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;
    }
    




  • 相关阅读:
    401. Binary Watch
    46. Permutations
    61. Rotate List
    142. Linked List Cycle II
    86. Partition List
    234. Palindrome Linked List
    19. Remove Nth Node From End of List
    141. Linked List Cycle
    524. Longest Word in Dictionary through Deleting
    android ListView详解
  • 原文地址:https://www.cnblogs.com/tryitboy/p/4231156.html
Copyright © 2011-2022 走看看