2048控制臺版
文章目錄
- 2048控制臺版
- 實現效果:
- 在這里插入圖片描述
- 庫函數使用:
- 初始化變量
- 功能函數實現:
- 狀態判斷函數int Judge();
- 數字生成函數 bool CtreateNumber()
- 打印游戲界面 void Print()
- 操作函數void Process()
- 鍵盤輸入函數int Input()
- 主函數
- 彩蛋:
實現效果:
庫函數使用:
#include<iostream>
#include<Windows.h>//鍵盤輸入讀取
#include<iomanip>//控制格式
#include<ctime>//生成隨機數種子
初始化變量
int const ROW = 4;
int const COL = 4;
int game[ROW][COL] = { 0};int const GAME_CONTINUE = 1;
int const GAME_WIN = 2;
int const GAME_LOSE = 3;int const UP = 1;
int const DOWN = 2;
int const LEFT = 3;
int const RIGHT = 4;
功能函數實現:
int Judge();//判斷游戲狀態
bool CreateNumber();//生成下一個數
void Print();//打印初始化界面
void Process(int move);//實現移動效果
int Input();//讀取鍵盤輸入
bool is_Empty(int const a);//可不需要,判斷某行謀列是否為0
狀態判斷函數int Judge();
設計思路:除去最后一行,逐行逐列的檢查正下方和右方有無可以消去的元素
int Judge() {int count = 0;for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {if (game[i][j] == 2024){return GAME_WIN;}if (!is_Empty(game[i][j])) {count++;if (i == ROW - 1) {if (j != COL - 1&&(game[i][j]==game[i][j+1])) {count--;}}else {if (j != COL - 1) {if (game[i][j] == game[i][j + 1] || game[i][j] == game[i + 1][j]) {count--;}}else continue;}}}}if (count < ROW * COL)return GAME_CONTINUE;else return GAME_LOSE;
}
數字生成函數 bool CtreateNumber()
實際思路:rand生成隨機數,通過非零情況控制生成2和4的概率
bool CreateNumber() {/*int x =0;int y = 0;*/int x = -1;int y = -1;int times = 0,max_times=ROW*COL;//max_times防止滿表的時候無限循環do {x = rand() % 4;y = rand() % 4;times++;} while (!is_Empty(game[x][y]) && times <= max_times);//有一個為0就跳出去//控制得到2和4的概率int value = rand() % 3;if (times > max_times) {return false;}else {if (value == 0)game[x][y] = 4;elsegame[x][y] = 2;return true;}
}
打印游戲界面 void Print()
void Print() {system("cls");/*cout << setfill('=') << setw(5 * COL)<<'='<<endl ;*/cout << setfill('-') << setw(5 * COL) << '-' << endl;for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {if (is_Empty(game[i][j])) {cout <<'|' << setfill(' ')<<setw(4) << ' ';}else {cout << '|' << setfill(' ')<<setw(4) << game[i][j];}}cout << '|' << endl;cout <<setfill('-') << setw(5 * COL) << '-'<<endl ;}
}
操作函數void Process()
教訓:第一次寫的時候寫了個count,用來記錄上面一行(在UP中)的每一列是否都滿足為空或者可以相消,這種操作是錯的,因為只要可以相消或者只要有空位,就都應該可以往上走
ps:LEFT和Right的函數實現代碼與UP和DOWN類似,把對應的col和row對調一下即可
void Process(int move) {if (move == UP) {for (int row = 1; row < ROW; ++row) {for (int crow = row; crow >= 1; --crow) {for (int col = 0; col < COL; col++) {if (is_Empty(game[crow - 1][col])) {game[crow - 1][col] = game[crow][col];game[crow][col] = 0;}if (game[crow - 1][col] == game[crow][col]) {game[crow - 1][col] *= 2;game[crow][col] = 0;}}}}}if (move == DOWN) {//注意ROW-2指的是倒數第二排int count = 0;for (int row = ROW-2; row>=0; --row) {//crow<ROW-1for (int crow = row; crow < ROW-1; ++crow) {for (int col = 0; col < COL; col++) {if (is_Empty(game[crow + 1][col])) {game[crow + 1][col] = game[crow][col];game[crow][col] = 0;}else if(game[crow+1][col]==game[crow][col]){game[crow + 1][col] *= 2;game[crow][col] = 0;}}}}
}
}
鍵盤輸入函數int Input()
說明:sleep函數是為了減少誤觸,降低敏感性
int Input() {int directionUP = 0;int directionDOWN =0;int directionLeft = 0;int directionRight = 0;int direction = 0;while (true) {directionUP = GetAsyncKeyState(VK_UP);directionDOWN = GetAsyncKeyState(VK_DOWN);directionLeft = GetAsyncKeyState(VK_LEFT);directionRight = GetAsyncKeyState(VK_RIGHT);if (directionUP) {/*cout << "UP" << endl;*/direction= UP;break;}if (directionDOWN) {/*cout << "DOWN" << endl;*/direction= DOWN;break;}if (directionLeft) {/*cout << "LEFT" << endl;*/direction= LEFT;break;}if (directionRight) {/*cout << "RIGHT" << endl;*/direction= RIGHT;break;}Sleep(100);}return direction;
}
主函數
int main() {srand((unsigned int)time(0));CreateNumber();Print();while (true) {int gameState = Judge();int direction = Input();if ((direction)&&(gameState == GAME_CONTINUE)) {/*CreateNumber();Print();Process(direction);*/Process(direction);CreateNumber();Print();Sleep(100);//防止太敏感}else if (gameState == GAME_WIN) {Print();cout << "You Win" << endl;break;}else if (gameState == GAME_LOSE) {Print();cout << "Sorry,You Lose" << endl;break;}}return 0;
}
彩蛋:
如果時間足夠,會再出有前端版本的實現代碼!