C++實現控制檯版2048(內附彩蛋)
阿新 • • 發佈:2019-01-30
前言
之前做過一個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();
}
由以上兩種判斷為基礎,構建左移核心演算法。
完整程式碼
C++版本意在複習基本遊戲演算法,熟悉C++語法,並沒有在細節方面考慮,比如沒有新增遊戲結束的判定等。
不過,我的JavaScript版本功能完善,包括遊戲結束顯示,動畫效果,記錄當前步數,記錄當前分數,儲存最高分,撤銷回上一步。
希望可以交流討論。