C++实现控制台版2048

前言

  之前做过一个JavaScript版本的2048游戏,最近在学习C++,昨天晚上突然心血来潮,想用C++来实现,因为核心算法已十分理解,所以两个小时撸出来一个C++的简易版本。


简介

  二维数组遍历,C++基本数据类型,string类,控制结构,函数。

  本方法不涉及指针以及面向对象思想,所以可作为刚入门C++的新人的第一个小project。


效果图


实现思路

1.背景

  游戏的背景即一个4*4的二维数组,通过每次运动中二维数组中值的变化以及数字的位置的变化,完成该游戏。

2.随机数字及位置

  游戏的开始阶段需要随机出两个数字,之后每次移动都需要在空白处随机出一个新的数字(2 / 4)。


    //随机一个位置
    int randX = rand()%4;
    int randY = rand()%4;
    int times = 0;
    while (times < 50)
    {
        if (0 == board[randX][randY])
            break;
        randX = rand()%4;
        randY = rand()%4;
        times++;
    }
    if (50 == times)
    {
        for (int i=0; i<4; i++)
            for (int j=0; j<4; j++)
                if (0 == board[i][j])
                {
                    randX = i;
                    randY = j;
                }
    }

  首先随机得到一个空白处(即二维数组等于0),在算法方面做了优化,先由系统随意选择50次,若没能找到空白处,则手动找到一个位置,可一定程度地加快位置随机的速度。


    //随机一个数字
    int randomNumber = rand()%100*0.01 < 0.5 ? 2 : 4;

  在0~1之间任意取值,如果小于0.5即随机得到2,反之随机得到4,保证出现2和4的可能性相同。

3.运动算法

  四个方向上的运动大致相同,只不过在临界处有细微区别,下面以向左移动进行解释。


//判断水平路径上是否有障碍物
bool noBlock1(int row, int col1, int col2, int board[][4])
{
    for (int i=col1+1; i<col2; i++)
        if (0 != board[row][i])
            return false;

    return true;
}

  对每个物体进行判断,在第row排,从col1到col2的范围内是否有障碍物。


//判断能否向左移动
bool canMoveLeft(int board[][4])
{
    for (int i=0; i<4; i++)
        for (int j=1; j<4; j++)
            if (0 != board[i][j])
                if (0 == board[i][j-1] || board[i][j-1] == board[i][j])
                   return true;

    return false;
}

  按下←时,判断整个画布是否可以向左移动。


//左移函数
bool moveLeft()
{
    if (!canMoveLeft(board))
        return false;
    //moveLeft
    //落脚位置是否为空
    //落脚位置数字是否相等
    //移动路径中是否有障碍物
    for (int i=0; i<4; i++)
        for (int j=0; j<4; j++)
            if (0 != board[i][j])
                for (int k=0; k<j; k++)
                    if (0 == board[i][k] && noBlock1(i, k, j, board))
                    {
                        //move
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    else if (board[i][k] == board[i][j] && noBlock1(i, k, j, board))
                    {
                        //move and add
                        board[i][k] *= 2;
                        board[i][j] = 0;
                        continue;
                    }

    initial();
}

  由以上两种判断为基础,构建左移核心算法。


完整代码

  https://files.cnblogs.com/files/henuzyx/2048.zip



  C++版本意在复习基本游戏算法,熟悉C++语法,并没有在细节方面考虑,比如没有添加游戏结束的判定等。

  不过,我的JavaScript版本功能完善,包括游戏结束显示,动画效果,记录当前步数,记录当前分数,保存最高分,撤销回上一步。

  希望可以交流讨论。

  JavaScript版本github链接:

  https://github.com/henuzyx/2048-by-JavaScript

原文地址:https://www.cnblogs.com/henuzyx/p/8586526.html

时间: 2024-08-03 12:11:11

C++实现控制台版2048的相关文章

Windows控制台版2048

上一篇说了Linux控制台版的2048,这次是对代码进行简单修改后的Windows版2048. 运行效果如下: 与Linux版本相比,核心代码没有改动,只是改变终端颜色函数的部分做了调整. 不过,在Windows下,使用VS2013 Express,与GCC有所不同,所以做了一些处理,并对原有代码做了整理,使之No Warning.代码同样放在在Github,可以点这里查看. 

C++ 控制台版 2048小游戏

先说说2048游戏的规则: 开始的时候空格中会出现两个数字(只能为2或者4),用户可以选择上下左右键进行移动,数字们整体沿着方向移动,中间不存在空格,如果相邻的两个数字相等,那么合并至沿着方向的后一个,更新最大值,总分数加上新出现的数字.当出现2048,Win.或者没有空格了,Lose. 基本就是一个按照思路的模拟题,没有什么难度.不过我想写一个自动求解的程序,但是bfs搜索的话解空间太庞大,没有想到好的方法,有路过的牛人还请指点. //2048 by Tach #include<iostrea

Linux控制台版本2048

在Github上看到一个荷兰人写的linux控制台版的2048,用的C语言,感觉很有意思. 原网址在这里. 读了一下他的源码,感觉写的不错,就厚着脸皮加了一些中文注释,源码如下: /* ============================================================================ Name : 2048.c Author : Maurits van der Schee Description : Console version of th

从零開始开发Android版2048 (二)获取手势信息

今天是尝试開始Android版2048小游戏的第二天.在今天,我主要学习了怎样获取用户在屏幕滑动的手势,以及对布局进行了一些小小的完好. 获取用户操作的手势(比方向左滑.向右滑等)主要用到了GestureDetector.这个类能够帮助我们获取一些常见的用户对屏幕的操作.比如单击.双击.按压.拖动等.详细的使用说明.大家能够查API也能够去百度,或者看我之前有一篇使用GestureDetector实现的小样例(http://blog.csdn.net/xiapinnong/article/det

从零开始开发Android版2048 (五) 撤销的实现

本篇的内容是,在前一篇的基础上加入了撤销的功能.撤销其实就是将当前的用户界面恢复到这次滑动值前的样子.我实现撤销的主要原理是,将每次滑动后界面上的格子和对应的数字记录下来,当然还有分数,把这些数据写入一个栈中,然后点击撤销操作的时候,将栈顶pop掉,读取下一个栈中的对象,并根据对象中存储的数据重新绘制界面. 下面是我用于存储每次界面情况的类,在这个类中保存了界面中主要的三个数据,空白格.数字格和当前的分数. package com.example.t2048; import java.util.

C++实现简单的扫雷游戏(控制台版)

C++新手的代码,请各位多包涵. 用C++写的一个简单的控制台版扫雷游戏.玩家通过输入方块的坐标来翻开方块. 只是一个雏形,能够让玩家执行翻开方块的操作并且判断输赢,还未添加标记方块.游戏菜单.记录游戏时间.重新开一局等等的功能. 玩家输入坐标的方式来翻开方块只适用于小型的“雷区”,若“雷区”大了,用坐标会变得很不方便. 代码片段扫雷V1.1 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

屌丝也能开发安卓版2048(App Inventor)

想编写安卓游戏,java太难,来试试App Inventor,虽然有人认为他是中学生的玩具,但是也能编写2048这样的火爆游戏,不需要太复杂的算法. 整个游戏有几个模块: 一.游戏初始化 数列转化为图形,使用了canvas和精灵,相对应list,这里注意精灵位置是固定的,只是更改图片,多少分,就对于n.jpg,0分是底色图片.左右移动,使用了flung判断,绝对值判断,水平速度和垂直速度哪个大,用来判断是左右移动还是上下移动. 二.计分模块 一般计分在合并处增加,最高分用了tiny db,游戏结

从零开始开发Android版2048 (三)逻辑判断

最近工作比较忙,所以更新的慢了一点,今天的主要内容是关于Android版2048的逻辑判断,经过本篇的讲解,基本上完成了这个游戏的主体部分. 首先还是看一下,我在实现2048时用到的一些存储的数据结构.我在实现时,为了省事存储游戏过程中的变量主要用到的是List. 比如说:List<Integer> spaceList = new ArrayList<Integer>();这个spaceList主要用于保存,所有空白格的位置,也就是空白格在GridLayout中的位置(从0到15)

从零開始开发Android版2048 (一)初始化界面

自学Android一个月多了,一直在工作之余零零散散地看一些东西.感觉经常使用的东西都有些了解了,可是一開始写代码总会出各种奇葩的问题.感觉还是代码写得太少.这样继续杂乱地学习下去进度也太慢了,并且学一点忘一点,效率太低.所以从今天開始.我打算实际做点小程序.在开发中不断地学习吧. 恰好近期Android上有个游戏2048比較火,所以就那这个练手吧. 由于对Android还没有太深入的了解,所以我写的东西都会比較基础,所以须要看一些高阶开发的朋友能够绕过了,也希望能够有高手们给我一些指导和建议,