当前位置: 首页 > news >正文

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("            --------------------------------------------\n");
    printf("            ********************************************\n\n");
    printf("            操作说明:\n↓:下   ←:左  ↑:上  →:右  ESC键:退出\n\n");
    printf("            游戏介绍:每次选择一个方向滑动,每次滑动,除了数字向该方向靠拢之外,系统会在空格处生成随机数字2或者4,\n");
    printf("            相同数字可以相加。如果拼凑出“2048”这个数字,则游戏胜利!\n");
    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("\n退出中");
    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("            --------------------------------------------\n");
    printf("            ********************************************\n");       

    //上界
    SetConsoleTextAttribute(handle_out,FORE_RED);           //设置打印颜色为红色
    printf("                      |----|----|----|----|\n");            

        //格子上半部分
    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("\n");
        SetConsoleTextAttribute(handle_out,FORE_RED);                   //设置打印颜色为红色
        printf("                      |----|----|----|----|\n");
    }
                    //格子下半部分        
    SetConsoleTextAttribute(handle_out,FORE_GREEN);                     //设置打印颜色为绿色
    printf("            --------------------------------------------\n");
    printf("            ********************************************\n");   
    printf("            ↓:下   ←:左  ↑:上  →:右  ESC键:退出\n\n");
    SetConsoleTextAttribute(handle_out,FORE_RED);                       //设置打印颜色为红色
    printf("            ■▲□■○□■○□            ■○□■○□■○□\n");
    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("○□\n");
    printf("            ■▲          ○□            ■○          ○□\n");
    printf("            ■▲▲■▲□■○□            ■○□■○□■○□\n");

    //下界
    if(Game==1)                             //游戏结束,失败
    {   printf("\n            Sorry,you losed!!!!!!!!!!!!!!!!!!!!!!\n");
        system("pause");
        Exit();
    }
     if(Game==2)                            //游戏成功,胜利
    {       
        printf("\n            Good!YOU  WIN!!!!!!!!!!!!!!!!!!!!!!!!\n");
        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("            --------------------------------------------\n");
    printf("            ********************************************\n");
    SetConsoleTextAttribute(handle_out,FORE_YELLOW);            //设置打印颜色为绿色
    printf("                              菜单\n");
    SetConsoleTextAttribute(handle_out,FORE_GREEN|FORE_YELLOW);         //设置打印颜色为青色
    printf("                          a.正常模式\n");
    printf("                          b.困难模式\n");
    printf("                          c.帮助手册\n");
    printf("                          d.游戏结束\n");
    printf("                          请输入你的选择\n");
}

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

转载于:https://www.cnblogs.com/FlyerBird/p/9052585.html

相关文章:

  • 第一章 深入理解Magento - Magento强大的配置系统
  • Directx9.0 学习教程3 -图形学之创建点 线 三角形 等
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • maven管理项目用junit测试遇到的找不到编译类问题
  • 2017中国手机趋势报告:天猫手机客单价2104元,品质时代来临
  • docker 在Windows下使用遇到的坑
  • CSS鼠标属性值
  • django-1.11.3 源码详解 -- 0001 django-admin.py 的调用逻辑
  • JMeter中返回Json数据的处理方法
  • getopts命令行参数处理
  • SparkSQL架构
  • 两个fragment之间简单的跳转
  • Spring《六》管理Bean
  • Python开发【第四篇】:Python基础之函数
  • 【cocos2d-x 3.7 飞机大战】 决战南海I (四) 敌机管理
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 分享一款快速APP功能测试工具
  • 0x05 Python数据分析,Anaconda八斩刀
  • Angular6错误 Service: No provider for Renderer2
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • golang 发送GET和POST示例
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • java正则表式的使用
  • PHP变量
  • PHP的类修饰符与访问修饰符
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • SSH 免密登录
  • 闭包--闭包之tab栏切换(四)
  • 工作中总结前端开发流程--vue项目
  • 排序算法之--选择排序
  • 鱼骨图 - 如何绘制?
  • 正则与JS中的正则
  • gunicorn工作原理
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​HTTP与HTTPS:网络通信的安全卫士
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (顺序)容器的好伴侣 --- 容器适配器
  • (算法)Game
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • ./和../以及/和~之间的区别
  • .NET BackgroundWorker
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .net和jar包windows服务部署
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • 。Net下Windows服务程序开发疑惑
  • @Not - Empty-Null-Blank
  • @ResponseBody
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [acm算法学习] 后缀数组SA
  • [bzoj1006]: [HNOI2008]神奇的国度(最大势算法)