当前位置: 代码迷 >> 综合 >> 一个简单的c++小游戏——2048
  详细解决方案

一个简单的c++小游戏——2048

热度:52   发布时间:2023-11-25 20:48:55.0

2048小游戏

代码

话不多说,代码如下:

#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
using namespace std;
class Game_2048
{
    
public:Game_2048();~Game_2048();void introduction();bool judgeOver();                            //判断游戏是否结束void reSize();void printBoard();                          //打印函数void getRand();                              //随机在棋盘上生成2,4;void slide();                                //滑动
private:int m=4, n=4;char op;                                   //用户操作vector< vector<int> > 	board;								//棋盘vector<int>  row;bool judgeInsert(int x,int y);bool judgeSlide();                               //判断是否能滑动,(未写完)void copyBoard(vector< vector<int> > &newBoard,vector< vector<int> > &board);void inputOp();char getOp();							//返回操作符bool judgeLeftSlide(bool mark=true);void leftSlide();                            //左滑动bool judgeRightSlide(bool mark = true);void rightSlide();bool judgeUpSlide(bool mark = true);void upSlide();bool judgeDownSlide(bool mark = true);void downSlide();void reStart();void enlarge();                             //将值扩大二倍
};int main()
{
    Game_2048 NB;NB.introduction();NB.getRand();NB.printBoard();while (!NB.judgeOver()){
    NB.slide();NB.getRand();NB.printBoard();} cout << "游戏结束!!!\n";system("pause");return 0;}void Game_2048::introduction()
{
    cout << "这是一个2048游戏,规则如下:\n";cout << "上划:W;\n下滑:S;\n左划:A;\n右划:D;\n退出:Q;\n重新开始:R;\n请输入下次操作,\n";
}void Game_2048::slide()
{
    inputOp();switch (getOp()){
    case 'a':case 'A':if (judgeLeftSlide())doleftSlide();while (judgeLeftSlide(false));else{
    cout << "无法左滑动,请重试!!!\n";slide();}break;case 'd':case 'D':if (judgeRightSlide())dorightSlide();while (judgeRightSlide(false));		else{
    cout << "无法右滑动,请重试!!!\n";slide();}break;case 'w':case 'W':if(judgeUpSlide())doupSlide();while (judgeUpSlide(false));else{
    cout << "无法上滑动,请重试!!!\n";slide();}break;case 's':case 'S':if(judgeDownSlide())do	downSlide();while (judgeDownSlide(false));else{
    cout << "无法下滑动,请重试!!!\n";slide();}break;case 'p':case 'P':enlarge();break;case 'q':case 'Q':exit(0);break;case 'r':case 'R':reStart();break;default:cout << "输入错误,作为惩罚,随机生成一个数!\n";break;}
}void Game_2048::reStart()
{
    for (int i = 0; i < m; i++)for (int j = 0; j < n; j++) {
    board[i][j] = 0;}
}void Game_2048::enlarge()
{
    for (int i = 0; i < m; i++)for (int j = 0; j < n; j++){
    board[i][j] *= 2;}
}char Game_2048::getOp()
{
    return op;
}void Game_2048::upSlide()
{
    for (int j = 0; j < n; j++)for (int i = m - 1; i > 0; i--) {
                                  //n-1!!if (board[i][j] != 0 && board[i - 1][j] == 0)            //移动{
    board[i - 1][j] = board[i][j];board[i][j] = 0;}}for (int j = 0; j < n; j++)for (int i = m - 1; i > 0; i--) {
    if (board[i][j] != 0 && board[i-1][j] == board[i][j])  //覆盖{
    board[i-1][j] += board[i][j];board[i][j] = 0;}}
}bool Game_2048::judgeUpSlide(bool mark)
{
    if (mark){
    for (int i = 0; i < m; i++)for (int j = n - 1; j > 0; j--){
    if (board[i][j] == 0)return true;}}for (int j = 0; j < n; j++)for (int i = m - 1; i > 0; i--) {
                                  //n-1!!if (board[i][j] != 0 && board[i - 1][j] == 0)            //移动return true;if (board[i][j] != 0 && board[i - 1][j] == board[i][j])  //覆盖return true;}return false;
}bool Game_2048::judgeDownSlide(bool mark)
{
    if (mark) {
    for (int i = 0; i < m; i++)for (int j = n - 1; j > 0; j--){
    if (board[i][j] == 0)return true;}}for (int j = 0; j < n; j++)for (int i = 0; i < m - 1; i++) {
                                  //n-1!!if (board[i][j] != 0 && board[i + 1][j] == 0)            //移动return true;if (board[i][j] != 0 && board[i + 1][j] == board[i][j])  //覆盖return true;}return false;
}void Game_2048::downSlide()
{
    for (int j = 0; j < n; j++)for (int i = 0; i < m - 1; i++) {
                             if (board[i][j] != 0 && board[i + 1][j] == 0)            //移动{
    board[i + 1][j] = board[i][j];board[i][j] = 0;}}for (int j = 0; j < n; j++)for (int i = 0; i < m - 1; i++) {
    if (board[i][j] != 0 && board[i + 1][j] == board[i][j])  //覆盖{
    board[i + 1][j] += board[i][j];board[i][j] = 0;}}
}void Game_2048::rightSlide()
{
    for (int i = 0; i < m; i++)for (int j = 0; j < n - 1; j++) {
                                  //n-1!!if (board[i][j] != 0 && board[i][j + 1] == 0)            //移动{
    board[i][j + 1] = board[i][j];board[i][j] = 0;}}for (int i = 0; i < m; i++)for (int j = 0; j < n - 1; j++) {
    if (board[i][j] != 0 && board[i][j + 1] == board[i][j])  //覆盖{
    board[i][j + 1] += board[i][j];board[i][j] = 0;}}
}bool Game_2048::judgeRightSlide(bool mark )
{
    if (mark) {
    for (int i = 0; i < m; i++)for (int j = n - 1; j > 0; j--){
    if (board[i][j] == 0)return true;}}for (int i = 0; i < m; i++)for (int j = 0; j < n - 1; j++) {
                                  //n-1!!if (board[i][j] != 0 && board[i][j + 1] == board[i][j])  //覆盖return true;if (board[i][j] != 0 && board[i][j + 1] == 0)return true;}return false;
}void Game_2048::leftSlide()
{
    for (int i = 0; i < m; i++)for (int j = 1; j < n; j++) {
                                  //n-1!!if (board[i][j] != 0 && board[i][j - 1] == 0)            //移动{
    board[i][j - 1] = board[i][j];board[i][j] = 0;}}for (int i = 0; i < m; i++)for (int j = 1; j < n; j++) {
    if (board[i][j] != 0 && board[i][j - 1] == board[i][j])  //覆盖{
    board[i][j - 1] += board[i][j];board[i][j] = 0;}}
}bool Game_2048::judgeLeftSlide(bool mark)
{
    if (mark) {
    for (int i = 0; i < m; i++)for (int j = n - 1; j > 0; j--){
    if (board[i][j] == 0)return true;}}for (int i = 0; i < m; i++)for (int j = n - 1; j > 0; j--) {
                                  //n-1!!if (board[i][j] != 0 && board[i][j - 1] == 0)            //移动return true;if (board[i][j] != 0 && board[i][j - 1] == board[i][j])  //覆盖return true;}return false;
}bool Game_2048::judgeOver()
{
    if (op == 'q' || op == 'Q')return true;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++) {
    if (board[i][j] == 2048){
    printBoard();cout << "有数字达到了2048,恭喜!!!\n";return true;}	}for (int i = 0; i < m; i++)for (int j = 0; j < n; j++) {
    if (board[i][j] == 0)return false;}if (judgeSlide())return false;else{
    cout << "无法再滑动\n";return true;}}bool Game_2048::judgeSlide()
{
    vector< vector<int> > 	copyBoard;								//棋盘vector<int>  copyRow;for (int i = 0; i < n; i++) {
    copyRow.push_back(0);}for (int i = 0; i < m; i++) {
    copyBoard.push_back(copyRow);}copyBoard = board;upSlide();downSlide();leftSlide();rightSlide();for (int i = 0; i < m; i++)for (int j = 0; j < n; j++){
    if (board[i][j] == 0) {
    board = copyBoard;return true;}	}return false;
}void Game_2048::copyBoard(vector< vector<int> >& newBoard, vector< vector<int> >& 	board)
{
    for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)newBoard[i][j] = board[i][j];
}bool Game_2048::judgeInsert(int x,int y)
{
    if (board[x][y] == 0)return true;elsereturn false;
}
void Game_2048::getRand()
{
    srand(time(0));int x, y,val;do{
    x = rand() % m;y = rand() % n;} while (!judgeInsert(x,y));val = (rand() % 2 + 1)*2;board[x][y] = val;}void Game_2048::inputOp()
{
    cin >> op;
}
void Game_2048::reSize()
{
    cout << "请输入棋盘大小m*n\n";cin >> m >> n;Game_2048();
}Game_2048::~Game_2048()
{
    
}Game_2048::Game_2048()
{
    for (int i = 0; i < n; i++){
    row.push_back(0);}for (int i = 0; i < m; i++){
    board.push_back(row);}
}
void Game_2048::printBoard()
{
    cout << "\n--------------\n";for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
    cout << board[i][j];if (j < n-1){
    cout << "—";}if (j == n-1 && i < m-1){
    cout << endl;int count = 0;while (count++ < n-1){
    cout << "| ";}cout << "|" << endl;}}}cout << "\n--------------\n" ;
}

ps:楼主现在还是个C++小白,这个小游戏写了差不多有450行,感觉有点多,后续会尝试删减一点。

设计思路

编译器

目前博主只会c++的控制台程序,编译器是vs2019;

2048类的声明

游戏很简单,主要操作只有上下左右滑动,数字也仅是储存在一个4 × 4的一个二维向量中。游戏类中公共部分主要有滑动,打印,判断游戏是否运行结束,获取操作符的函数,而私有部分主要是上下左右的滑动函数以及判断函数,另外声明了一个默认4 × 4的向量(可以通过resize函数修改)。

打印函数的实现

void Game_2048::printBoard()
{
    cout << "\n--------------\n";for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
    cout << board[i][j];if (j < n-1){
    cout << "—";}if (j == n-1 && i < m-1){
    cout << endl;int count = 0;while (count++ < n-1){
    cout << "| ";}cout << "|" << endl;}}}cout << "\n--------------\n" ;
}

这部分挺简单,实际上就是对一个二位向量的一个遍历(两个for循环),稍微有点复杂的部分是“|”“-”的输出,多想想就欧克了。

公共部分滑动函数slide的实现

代码就不粘了,其实就是一个简单的switch结构,根据用户的输入调用不同的函数。滑动case 有个do while结构,原因是私有部分的四 个滑动函数对棋盘上的数只能滑 动一下(局限性),例如4-0-0-0,向右 滑动只能滑成0-4-0-0,故使用do-while多次调用右划函数。

judgeOver函数的实现

思路就是简单的遍历,出现了2048,游戏结束,还有0,游戏未结束。但还有一种情况就是棋盘满了,但是还能够进行滑动,这种情况下就新建一个copy的棋盘(ps:当然不能在原棋盘上尝试滑动),对这个copy的棋盘进行上下左右的滑动,如果出现了空位,则游戏未结束。

私有滑动函数的实现

void Game_2048::rightSlide()
{
    for (int i = 0; i < m; i++)for (int j = 0; j < n - 1; j++) {
                                  //n-1!!if (board[i][j] != 0 && board[i][j + 1] == 0)            //移动{
    board[i][j + 1] = board[i][j];board[i][j] = 0;}}for (int i = 0; i < m; i++)for (int j = 0; j < n - 1; j++) {
    if (board[i][j] != 0 && board[i][j + 1] == board[i][j])  //覆盖{
    board[i][j + 1] += board[i][j];board[i][j] = 0;}}
}

还是很简单,就是两个遍历,一个移动,一个合并。

总结

博主是一个编程小白,这个2048游戏是博主某一天晚上突发奇想,想编一个小游戏,来试试自己的能力。设计思路一个晚上(ps:失眠的晚上)已经想的差不多了,第二天一早的三节课已经初步编编出来了,改bug差不都一个晚上(主要是那个do-while循环)。毕竟小白,效率很低。450行的代码没什么亮点,也没有算法。
但学习是一个渐进的过程,与诸君共勉!!!