码迷,mamicode.com
首页 > 编程语言 > 详细

C++实现控制台版2048

时间:2018-03-17 00:40:19      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:算法   lock   alt   解释   结束   mil   asc   画布   else   

前言

  之前做过一个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

 

C++实现控制台版2048

标签:算法   lock   alt   解释   结束   mil   asc   画布   else   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!