zoukankan      html  css  js  c++  java
  • 2048-控制台版本

    /最近修改2017/6/26/
    /修改2017/7/4,修改之前各自填满之后无法移动的错误,暂时未发现大的错误/
    /最后修改2017/7/5,添加前景色,添加模式选择,改善界面/
    一.实现目标:
    2048游戏
    二.要求:
    1、在屏幕上显示4*4的表格
    2、随机生成2、4数字及位置
    3、颜色设置
    三.运行环境和工具:
    VC++6.0
    四.实现步骤
    0.游戏逻辑:
    把游戏画面想象成4*4的数组,其中数值为0的位置表示空的格子,
    有数值的位置代表对应的格子。然后对于每一行按列来遍历,或者每一列按行来遍历,实现每一行每一列的对应数字合并,直到出现2048的格子就胜利,否则就失败.
    1.编写用于实现数字移动的方向函数
    以向左移动为例:
    把游戏画面想象成4*4的数组,其中数值为0的位置表示空的格子,
    先看其中一行,有四列,用一个变量k=0,从第一列开始,另一个变量j=1开始,代表k之后的列,开始遍历。
    如果第j列这个位置不为0的话,那么之后可以分为3种情况:
    第一种情况:第k列和第j列相同,这个时候就将第k列的数字加倍,第j列重置为0.
    第二种情况:第k列为0,那么就交换第k列和第j列的数字。
    第三种情况:第k列和第j列都不为0,但是两者不相等,这个时候,就把两个数紧挨在一起,如果j和k原本就紧挨在一起,那么什么也不做。
    而如果第j列为,也什么也不做。
    在向左移动的时候,每一行都向左移动,所以逐行相加,然后按列遍历。
    同理,向右移动,区别在于,向右是反向的按列遍历,向上是逐列相加,按行遍历,向右于向左移动是行列相反的遍历。
    每次移动,步数就+1,每次合并,就会加上当前合并的格子的数值。
    2.编写用于实现随机数字和随机位置的函数,以及游戏结束函数,显示格子函数,初始化函数,退出函数等
    #define TARGET 2048
    标记最终的目标,同时也是判断游戏是否结束的标志之一,如果在格子中出现了2048的格子,玩家胜利,游戏结束。另一种结束方式是,当所有的格子都被填满的时候,同时不存在可以相互合并的格子,并且没有2048的格子,游戏结束,玩家失败。
    3.困难模式下随机函数用来随机出现数字2和4,使得出现的概率之比为1:10,保证游戏时间不至于过短。
    正常模式下随机函数2和4出现概率之比为1:4
    4.Begin()函数用来将数组初始化为0,包括分数和步数的清零
    但是这个只在游戏开始的时候执行一次。
    5.显示格子函数:设置好打印颜色,以及格子间距
    五.程序运行:


    这里写图片描述
    这里写图片描述
    六.以下为完整代码

    #include<conio.h>
    #include<time.h>
    #include<Windows.h>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    #define TARGET 2048         //最终目标
    HANDLE myHandle;            //控制句柄,对象
    const WORD FORE_BLUE    =FOREGROUND_BLUE;           //蓝色文本
    const WORD FORE_GREEN   =FOREGROUND_GREEN;          //绿色文本
    const WORD FORE_RED     =FOREGROUND_RED;            //红色文本  
    const WORD FORE_YELLOW  =FORE_RED|FORE_GREEN;       //黄色文本,其他颜色用三原色搭配
    const WORD FORE_GRAY    =FORE_BLUE|FORE_GREEN;      //紫色文本
    const WORD BACK_BLUE    =BACKGROUND_BLUE;           //蓝色背景
    const WORD BACK_GREEN   =BACKGROUND_GREEN;          //绿色背景
    const WORD BACK_RED     =BACKGROUND_RED;            //红色背景  
    const WORD BACK_YELLOW  =BACK_RED|BACK_GREEN;       //黄色背景,其他颜色用三原色搭配
    const WORD BACK_GRAY    =BACK_BLUE|BACK_GREEN;      //紫色背景
    int pass=0;                     //用来判断是否需要返回
    int Game;                       //标记游戏是否结束
    int ax[4][4];                   //控制的二维数组
    int score=0;                    //记录分数
    int step=0;                     //记录所花费的步数
    void Up();                      //向上移动数字,使其相同的合成,不同的紧凑
    void Down();                    //向下
    void Right();                   //向右    
    void Left();                    //向左
    void Movement();                //正常移动
    void Movement_2();              //困难移动
    void GAME_OVER();               //标记游戏是否结束
    void Exit();                    //退出函数
    void Begin();                   //初始化数组
    void Run();                     //将随机出现的数字放入随机的坐标当中,概率修改
    void Run_2();                   //概率之比为1:10
    void Show();                    //显示格子
    void Mode1();                   //正常模式
    void Mode2();                   //困难模式
    void Help();                    //帮助手册
    void choice();                  //选择
    void Menu();                    //菜单
    
    void Help()
    {
        system("cls");
        HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE);      //获取标准输入设备句柄
        CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体
        GetConsoleScreenBufferInfo(handle_out,&csbi);           //获得窗口缓冲区信息
        SetConsoleTextAttribute(handle_out,FORE_YELLOW);            //设置打印颜色为绿色
        printf("            --------------------------------------------
    ");
        printf("            ********************************************
    
    ");
        printf("            操作说明:
    ↓:下   ←:左  ↑:上  →:右  ESC键:退出
    
    ");
        printf("            游戏介绍:每次选择一个方向滑动,每次滑动,除了数字向该方向靠拢之外,系统会在空格处生成随机数字2或者4,
    ");
        printf("            相同数字可以相加。如果拼凑出“2048”这个数字,则游戏胜利!
    ");
        system("pause");
        system("cls");
    }
    
    void Left()
    {
        int i,j,k;
        for(i=0;i<4;i++)            //行数
        {       
            for(j=1,k=0;j<4;j++)    //每一行按列来遍历
            {
                if(ax[i][j]!=0)
                {
                    if(ax[i][k]==ax[i][j])
                    {
                        ax[i][k]<<=1;
                        score+=ax[i][k];
                        ax[i][j]=0;
                        k++;
                    }
                    else if(ax[i][k]==0)
                    {
                        ax[i][k]=ax[i][j];
                        ax[i][j]=0;
                        k++;
                    }
                    else
                    {
                        k++;
                        ax[i][k]=ax[i][j];
                        if(k!=j)
                        {
                            ax[i][j]=0;
                        }
                    }
                }
            }
        }
        step++;
    }
    
    void Right()
    {
        int i,j,k;
        for(i=0;i<4;i++)
        {
            for(j=2,k=3;j>=0;j--)
            {
                if(ax[i][j]!=0)
                {
                    if(ax[i][j]==ax[i][k])
                    {
                        ax[i][k]<<=1;
                        score+=ax[i][k];
                        ax[i][j]=0;
                        k--;
                    }
                    else if(ax[i][k]==0)
                    {
                        ax[i][k]=ax[i][j];
                        ax[i][j]=0;
                        k--;
                    }
                    else 
                    {
                        k--;
                        ax[i][k]=ax[i][j];
                        if(j!=k)
                        {
                            ax[i][j]=0;
                        }
                    }
                }
            }
        }
        step++;
    }
    
    void Up()
    {
        int n,i,j,k;
        for(n=0;n<4;n++)
        {
            k=0;
            for(i=0;i<4;i++)
            {
                if(ax[i][n]!=0)
                {
                    for(j=i;j>k;j--)
                    {
                        if(ax[j-1][n]==0)       //上一行没有数字
                        {
                            ax[j-1][n]=ax[j][n];
                            ax[j][n]=0;
                        }
                        else if(ax[j-1][n]==ax[j][n])
                        {
                            ax[j-1][n]=2*ax[j-1][n];
                            score+=ax[j-1][n];
                            ax[j][n]=0;
                            k=j;
                            Sleep(1);
                            break;
                        }
                        else
                            break;
                    }
                }
            }
        }
        step++;
    }
    
    void Down()
    {
        int i,j,k;
        for(j=0;j<4;j++)
        {
            for(i=2,k=3;i>=0;i--)
            {
                if(ax[i][j]!=0)
                {
                    if(ax[i][j]==ax[k][j])
                    {
                        ax[k][j]<<=1;
                        score+=ax[k][j];
                        ax[i][j]=0;
                        k--;
                    }
                    else if(ax[k][j]==0)
                    {
                        ax[k][j]=ax[i][j];
                        ax[i][j]=0;
                        k--;
                    }
                    else 
                    {
                        k--;
                        ax[k][j]=ax[i][j];
                        if(k!=i)
                        {
                            ax[i][j]=0;
                        }
                    }
                }
            }
        }
        step++;
    }
    
    void Movement()
    {
        if(kbhit())
        {
            switch(getch())
            {
                case 27:
                    Exit();
                    break;
                case 75:        //向左
                    Left();
                    Run();
                    Show();
                    break;
                case 72:        //向上
                    Up();
                    Run();
                    Show();
                    break;
                case 77:        //向右
                    Right();
                    Run();
                    Show();
                    break;
                case 80:        //向下
                    Down();
                    Run();
                    Show();
                    break;
                default:
                    break;
            }
        }
    }
    void Movement_2()
    {
        if(kbhit())
        {
            switch(getch())
            {
                case 27:
                    Exit();
                    break;
                case 75:        //向左
                    Left();
                    Run_2();
                    Show();
                    break;
                case 72:        //向上
                    Up();
                    Run_2();
                    Show();
                    break;
                case 77:        //向右
                    Right();
                    Run_2();
                    Show();
                    break;
                case 80:        //向下
                    Down();
                    Run_2();
                    Show();
                    break;
                default:
                    break;
            }
        }
    }
    void Exit()
    {
        int i=0;
        printf("
    退出中");
        for(i=4;i>0;--i)
        {
            Sleep(200);
            printf(".");
        }
        exit(0);
    }
    
    void Begin()
    {
        int i=0,j=0;
        score=0;        //分数清零
        Game=0;         //初始游戏
        step=0;         //步数清零
        SetConsoleTitleA("游戏:2048");
        for(i=0;i<4;i++)
        {
            for(j=0;j<4;j++)
            {
                ax[i][j]=0;
            }
        }
    }
    
    void Run()
    {
        int x,y,temp,num;
        srand((int)time(0));
        while(1)
        {
            x=rand()%4;
            y=rand()%4;
            temp=rand()%5;      //概率之比为1:4
            if(temp==1)
                num=4;
            else
                num=2;
            if(ax[x][y]==0)
            {
                ax[x][y]=num;
                break;
            }
        }
    }
    
    void Run_2()
    {
        int x,y,temp,num;
        srand((int)time(0));
        while(1)
        {
            x=rand()%4;
            y=rand()%4;
            temp=rand()%10;     //概率之比为1:10
            if(temp==1)
                num=4;
            else
                num=2;
            if(ax[x][y]==0)
            {
                ax[x][y]=num;
                break;
            }
        }
    }
    
    void GAME_OVER()
    {
        int i,j;
        for(i=0;i<4;i++)
        {
            for(j=0;j<3;j++)
            {
                if(ax[i][j]==ax[i][j+1]||ax[j][i]==ax[j+1][i])
                {
                    Game=0;//同列中的存在刻意继续合并的数字,游戏继续
                    return ;
                }
                else if(ax[i][j]==0||ax[i][j+1]==0||ax[j][i]==0||ax[j+1][i]==0)
                {
                    Game=0;
                    return ;
                }
                else if(ax[i][j]==TARGET||ax[i][j+1]==TARGET||ax[j][i]==TARGET||ax[j+1][i]==TARGET)
                {
                    Game=2;
                    return;         //存在2048,游戏结束
                }
            }
        }
        Game =1;                    //不存在2048,但是同行同列中没有能够合并的数字,并且没有空位置,游戏结束
    }
    
    
    void Show()
    {
        int i,j;
        HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE);      //获取标准输入设备句柄
        CONSOLE_SCREEN_BUFFER_INFO csbi;                        //定义窗口缓冲区信息结构体
        GetConsoleScreenBufferInfo(handle_out,&csbi);           //获得窗口缓冲区信息
        system("cls");
        SetConsoleTextAttribute(handle_out,FORE_GREEN);         //设置打印颜色为绿色
        printf("            --------------------------------------------
    ");
        printf("            ********************************************
    ");       
    
        //上界
        SetConsoleTextAttribute(handle_out,FORE_RED);           //设置打印颜色为红色
        printf("                      |----|----|----|----|
    ");            
    
            //格子上半部分
        for(i=0;i<4;i++)
        {
            SetConsoleTextAttribute(handle_out,FORE_RED);       //设置打印颜色为红色
            printf("                      |");
            for(j=0;j<4;j++)
            {
                if(ax[i][j]!=0)
                {
                    SetConsoleTextAttribute(handle_out,FORE_YELLOW);        //设置打印颜色为黄色
                    printf("%4d|",ax[i][j]);
                }
                else
                {
                    SetConsoleTextAttribute(handle_out,FORE_YELLOW);        //设置打印颜色为黄色
                    printf("    |");
                }
            }
            printf("
    ");
            SetConsoleTextAttribute(handle_out,FORE_RED);                   //设置打印颜色为红色
            printf("                      |----|----|----|----|
    ");
        }
                        //格子下半部分        
        SetConsoleTextAttribute(handle_out,FORE_GREEN);                     //设置打印颜色为绿色
        printf("            --------------------------------------------
    ");
        printf("            ********************************************
    ");   
        printf("            ↓:下   ←:左  ↑:上  →:右  ESC键:退出
    
    ");
        SetConsoleTextAttribute(handle_out,FORE_RED);                       //设置打印颜色为红色
        printf("            ■▲□■○□■○□            ■○□■○□■○□
    ");
        printf("            ▲▲");
        SetConsoleTextAttribute(handle_out,FORE_YELLOW);                    //设置答应颜色为黄色
        printf("分数:%-3d ",score);
        SetConsoleTextAttribute(handle_out,FORE_RED);
        printf("▲□             ■○"); 
        SetConsoleTextAttribute(handle_out,FORE_YELLOW);
        printf("步数:%-3d ",step);
        SetConsoleTextAttribute(handle_out,FORE_RED);
        printf("○□
    ");
        printf("            ■▲          ○□            ■○          ○□
    ");
        printf("            ■▲▲■▲□■○□            ■○□■○□■○□
    ");
    
        //下界
        if(Game==1)                             //游戏结束,失败
        {   printf("
                Sorry,you losed!!!!!!!!!!!!!!!!!!!!!!
    ");
            system("pause");
            Exit();
        }
         if(Game==2)                            //游戏成功,胜利
        {       
            printf("
                Good!YOU  WIN!!!!!!!!!!!!!!!!!!!!!!!!
    ");
            system("pause");
            Exit();
        }
    }
    
    void Mode1()
    {
        Begin();                    //游戏初始化
        Run();                      //随机一个数字
        Run();
        Show();
        while(1)
        {       
            GAME_OVER();            //每次都判断一次游戏是否结束
            if(Game==1||Game==2)
            {
                break;
            }
            Movement();
        }
        Show();
        return ;
    }
    
    void Mode2()
    {
        Begin();
        Run_2();
        Run_2();
        Show();
        while(1)
        {
            GAME_OVER();
            if(Game==1||Game==2)
            {
                break;
            }
            Movement_2();
        }
        Show();
        return ;
    }
    
    void Menu()
    {
        SetConsoleTitleA("游戏:2048");
        HANDLE handle_out=GetStdHandle(STD_OUTPUT_HANDLE);      //获取标准输入设备句柄
        SetConsoleTextAttribute(handle_out,FORE_GREEN);         //设置打印颜色为绿色
        printf("            --------------------------------------------
    ");
        printf("            ********************************************
    ");
        SetConsoleTextAttribute(handle_out,FORE_YELLOW);            //设置打印颜色为绿色
        printf("                              菜单
    ");
        SetConsoleTextAttribute(handle_out,FORE_GREEN|FORE_YELLOW);         //设置打印颜色为青色
        printf("                          a.正常模式
    ");
        printf("                          b.困难模式
    ");
        printf("                          c.帮助手册
    ");
        printf("                          d.游戏结束
    ");
        printf("                          请输入你的选择
    ");
    }
    
    void choice()
    {
        char ch='0';
        scanf(" %c",&ch);
            switch(ch)
            {
            case 'a':
                Mode1();
                break;
            case'b':
                Mode2();
                break;
            case'c':
                Help();
                break;
            case'd':
                exit(0);
                break;
            default:
                break;
            }
    }
    
    int main(void)
    {
        while(1)
        {
            Menu();
            choice();
        }
        return 0;
    }
    (。・∀・)ノ
  • 相关阅读:
    SQL GUID和自增列做主键的优缺点
    python __future__ 的几种特性
    数据库中文乱码处理
    Android_Intent意图详解
    Windows Server 2012 R2超级虚拟化之六 Hyper-v Replica 2.0和Live migrations
    如今网站定位,需立足于用户
    Hibernate 数据的批量插入、更新和删除
    paip.提升用户体验---论文本编辑器的色彩方案
    时间管理方法学习
    网站优化:从搜索引擎到社交网络的艰难转变
  • 原文地址:https://www.cnblogs.com/FlyerBird/p/9052585.html
Copyright © 2011-2022 走看看