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行的代码没什么亮点,也没有算法。
但学习是一个渐进的过程,与诸君共勉!!!