c++实现2048游戏(控制台)

来源:互联网 发布:python getopt函数 编辑:程序博客网 时间:2024/06/08 12:09

2048游戏的逻辑比较简单:同一行或者同一列的两个数字,如果值相同并且没有其他数字遮挡,则可以合并为一个数,并且不能连续合并。

刚开始写我考虑的主要是2048的逻辑部分,显示就先low low的用控制台好了,有兴趣的可以做下图形界面。

鉴于此,采用view-module分层模式将数据和表示层分离开来,这样之后就算修改了表示层代码,也不需要对数据层的代码做多少改动。


module 层代码:

#ifndef CGAME_H#define CGAME_H#include <windows.h>#include <String>#define ROW 4   //格子总行数#define COLUMN 4    //格子总列数class cGame{public:cGame();~cGame();void play();void moveUp();void moveDown();void moveLeft();void moveRight();void newLattice();bool canMove();void show();void buf_show();private:int(*matrix)[COLUMN];//存储格子信息int max;//格子最大的数字的值bool gameWin;//游戏是否取胜bool gameOver;//游戏是否结束};#endif // CGAME_H

#include <iostream>#include <conio.h>#include <cstdlib>#include "cgame.h"#include "Point.h"using namespace std;//cGame::cGame(QObject *parent) : QObject(parent)//{//    memset(matrix,0,ROW*COLUMN);//}cGame::cGame(){matrix = new int[ROW][COLUMN];for (int row = 0;row < ROW;row++)for(int column=0;column<COLUMN;column++)matrix[row][column] = 0;gameWin = false;gameOver = false;max = 0;newLattice();}cGame::~cGame(){delete[] matrix;}void cGame::moveUp(){bool flag = false;//能否上移//先往上移动for (int column = 0;column<COLUMN;column++)for (int row = 1;row<ROW;row++){if (matrix[row][column] != 0){for (int i = 0;i<row;i++)if (matrix[i][column] == 0)    //是空格,移动到该处{matrix[i][column] = matrix[row][column];matrix[row][column] = 0;flag = true;break;}}}//再合并相同的数字for (int column = 0;column<COLUMN;column++)for (int row = 0;row<ROW - 1;row++){if (matrix[row][column] == 0)break;if (matrix[row][column] == matrix[row + 1][column]){//合并数字matrix[row][column] *= 2;matrix[row + 1][column] = 0;flag = true;//更新最大格子数值if (matrix[row][column] > max)max = matrix[row][column];//判断是否赢////////////////if (matrix[row][column] == 2048){gameWin = true;return;}//往上移动格子for (int i = row + 1;i<ROW - 1;i++)matrix[i][column] = matrix[i + 1][column];matrix[ROW - 1][column] = 0;}}//是可以移动状态,创建新的格子if(flag)newLattice();}void cGame::moveDown(){bool flag = false;//能否下移//先往下移动for (int column = 0;column<COLUMN;column++)for (int row = ROW - 2;row >= 0;row--){if (matrix[row][column] != 0){for (int i = ROW - 1;i>row;i--)if (matrix[i][column] == 0)    //是空格,移动到该处{matrix[i][column] = matrix[row][column];matrix[row][column] = 0;flag = true;break;}}}//再合并相同的数字for (int column = 0;column<COLUMN;column++)for (int row = ROW - 1;row>0;row--){if (matrix[row][column] == 0)break;if (matrix[row][column] == matrix[row - 1][column]){//合并数字matrix[row][column] *= 2;matrix[row - 1][column] = 0;flag = true;//更新最大格子数值if (matrix[row][column] > max)max = matrix[row][column];//判断是否赢////////////////if (matrix[row][column] == 2048){gameWin = true;return;}//往下移动格子for (int i = row - 1;i>0;i--)matrix[i][column] = matrix[i - 1][column];matrix[0][column] = 0;}}//是可以移动状态,创建新的格子if (flag)newLattice();}void cGame::moveLeft(){bool flag = false;//能否左移//先向左移动for (int row = 0;row<ROW;row++)for (int column = 1;column<COLUMN;column++){if (matrix[row][column] != 0){for (int j = 0;j<column;j++)if (matrix[row][j] == 0)   //是空格,移动到该处{matrix[row][j] = matrix[row][column];matrix[row][column] = 0;flag = true;break;}}}//再合并相同数字for (int row = 0;row<ROW;row++)for (int column = 0;column<COLUMN - 1;column++){if (matrix[row][column] == 0)break;if (matrix[row][column] == matrix[row][column + 1]){//合并数字matrix[row][column] *= 2;matrix[row][column + 1] = 0;flag = true;//更新最大格子数值if (matrix[row][column] > max)max = matrix[row][column];//判断是否赢////////////////if (matrix[row][column] == 2048){gameWin = true;return;}//向左移动格子for (int j = column + 1;j<COLUMN - 1;j++)matrix[row][j] = matrix[row][j + 1];matrix[row][COLUMN - 1] = 0;}}//是可以移动状态,创建新的格子if (flag)newLattice();}void cGame::moveRight(){bool flag = false;//能否右移//先向右移动for (int row = 0;row<ROW;row++)for (int column = COLUMN - 2;column >= 0;column--){if (matrix[row][column] != 0){for (int j = COLUMN - 1;j>column;j--)if (matrix[row][j] == 0)   //是空格,移动到该处{matrix[row][j] = matrix[row][column];matrix[row][column] = 0;flag = true;break;}}}//再合并相同数字for (int row = 0;row<ROW;row++)for (int column = COLUMN - 1;column>0;column--){if (matrix[row][column] == 0)break;if (matrix[row][column] == matrix[row][column - 1]){//合并数字matrix[row][column] *= 2;matrix[row][column - 1] = 0;flag = true;//更新最大格子数值if (matrix[row][column] > max)max = matrix[row][column];//判断是否赢////////////////if (matrix[row][column] == 2048){gameWin = true;return;}//向右移动格子for (int j = column - 1;j>0;j--)matrix[row][j] = matrix[row][j - 1];matrix[row][0] = 0;}}//是可以移动状态,创建新的格子if (flag)newLattice();}void cGame::play(){//游戏结束时,不做任何事情if (gameOver)return;//没有按键按下时,不做任何事情if (!_kbhit())return;switch (_getch()){case 'a':case 'A':moveLeft();break;case 'd':case 'D':moveRight();break;case 'w':case 'W':moveUp();break;case 's':case 'S':moveDown();break;default:break;}//buf_show();}void cGame::newLattice(){//存储空格信息Point posArray[ROW*COLUMN];int num = 0;for(int row=0;row<ROW;row++)for(int column=0;column<COLUMN;column++)if (matrix[row][column] == 0){posArray[num].setPos(row, column);num++;}//有空位置,随机选择一个空位置放2或者4if (num){int index = rand() % num;int x = posArray[index].x();int y = posArray[index].y();int number=(rand()%20==0)?4:2;//出现2和4的概率比为19:1matrix[x][y] = number;if (max == 0)max = number;}//检测是否能继续移动if (canMove()){gameOver = false;}else{gameOver = true;}}bool cGame::canMove(){//判断是否有空格,有则返回truefor (int row = 0;row < ROW;row++)for (int column = 0;column < COLUMN;column++)if (matrix[row][column] == 0)return true;//判断同一行中是否有相邻格子的值相等,有则返回truefor (int row = 0;row < ROW;row++)for (int column = 0;column < COLUMN-1;column++)if (matrix[row][column] == matrix[row][column+1])return true;//判断同一列中是否有相邻格子的值相等,有则返回truefor (int row = 0;row < ROW;row++)for (int column = 0;column < COLUMN;column++)if (matrix[row][column] == matrix[row+1][column])return true;return false;}void cGame::show(){system("cls");//提示信息if (gameWin)cout << "You win!" << endl;else if (gameOver)cout << "You lose!" << endl;elsecout << "Fighting!" << endl;//打印格子for (int row = 0;row < ROW;row++){for (int column = 0;column < COLUMN;column++){cout << matrix[row][column] << "\t";}cout << endl;}}void cGame::buf_show(){//创建屏幕缓冲区HANDLE hNewConsole = CreateConsoleScreenBuffer(GENERIC_WRITE | GENERIC_READ,0,NULL,CONSOLE_TEXTMODE_BUFFER,NULL);//隐藏光标CONSOLE_CURSOR_INFO cci = { 1,0 };SetConsoleCursorInfo(hNewConsole, &cci);//设置标题栏SetConsoleTitle("2048小游戏");//设置窗口缓冲区大小COORD cdBufferSize = { 320,480 };// 80, 25};SetConsoleScreenBufferSize(hNewConsole, cdBufferSize);//提示信息if (gameWin)cout << "You win!" << endl;else if (gameOver)cout << "You lose!" << endl;elsecout << "Fighting!" << endl;//打印格子for (int row = 0; row < ROW; row++){for (int column = 0; column < COLUMN; column++){COORD cdCursorPos = { column,row };//cout << matrix[row][column] << '\t';int *p = &matrix[row][column];SetConsoleCursorPosition(hNewConsole, cdCursorPos);WriteConsole(hNewConsole, p, sizeof(int), NULL, NULL);}cout << endl; cout << "row";}//显示绘制好的东西SetConsoleActiveScreenBuffer(hNewConsole);//游戏结束,返回正常模式if (gameOver)SetConsoleActiveScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE));}

Point 类是用来记录点坐标的,c++里面是有处理平面点坐标的方法的,不过我懒得找了就简单写了一个类,代码如下:
#pragma once#define NotPoint -1class Point{public:Point();~Point();void setPos(int x, int y);int x();int y();private:int xpos;int ypos;};

#include "Point.h"#include <iostream>using namespace std;Point::Point(){xpos = NotPoint;ypos = NotPoint;}Point::~Point(){}void Point::setPos(int x, int y){xpos = x;ypos = y;}int Point::x(){return xpos;}int Point::y(){return ypos;}

然后是main.cpp:
#include <iostream>#include "cGame.h"using namespace std;int main(){cGame cgame;while (1){cgame.play();cgame.show();Sleep(300);}return 0;}




1 0
原创粉丝点击