c++實現2048遊戲(控制檯)
阿新 • • 發佈:2019-01-01
#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或者4 if (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:1 matrix[x][y] = number; if (max == 0) max = number; } //檢測是否能繼續移動 if (canMove()) { gameOver = false; } else { gameOver = true; } } bool cGame::canMove() { //判斷是否有空格,有則返回true for (int row = 0;row < ROW;row++) for (int column = 0;column < COLUMN;column++) if (matrix[row][column] == 0) return true; //判斷同一行中是否有相鄰格子的值相等,有則返回true for (int row = 0;row < ROW;row++) for (int column = 0;column < COLUMN-1;column++) if (matrix[row][column] == matrix[row][column+1]) return true; //判斷同一列中是否有相鄰格子的值相等,有則返回true for (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; else cout << "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; else cout << "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++裡面是有處理平面點座標的方法的,不過我懶得找了就簡單寫了一個類,程式碼如下: