1. 程式人生 > >用c++實現遊戲2048---前三步

用c++實現遊戲2048---前三步

利用c++實現遊戲2048(命令列版)

寫在前面

在知乎上偶爾看到有人利用寫這種小程式練手,正好最近剛考完期末考試,所以就花了一個晚上寫了一下,也簡單的寫了一個2048.

以下是效果圖。
效果圖

之前沒有用c++寫過比較大型的內容,對c++的理解也不是很深。所以經過這一次編寫,對遊戲演算法的理解以及c++多檔案之間的呼叫有了更深刻的理解。

在寫之前,我先簡單的構思了以下整個遊戲會分成哪幾個部分,私以為可以簡單的分為六個部分:

  1. 初始化遊戲地圖
  2. 在遊戲地圖內格子隨機生成一個數字
  3. 在螢幕上顯示出地圖
  4. 玩家輸入操控指令
  5. 程式對玩家的指令進行相應移動與合併
  6. 判斷遊戲是否結束,若沒有結束就跳到2,否則跳出

我發現這六點當中,只有第5點最有難度,也就是如何去移動整個錶盤中的元素,如何判別是否可以合併,四個方向上的移動合併有什麼共同點和差別,如何合併等內容。其他5點就很簡單了,基本上沒有這麼複雜的邏輯。

下面我就以這6點分別進行講解。

主程式

將主程式放在單獨的一個檔案內

//source.cpp
#include <iostream>
#include <Windows.h>
#include "OperateMap.h"
#include "Parameter.h"
using namespace std;

int main() {
    //遊戲地圖
    int
MAP[MAP_SIZE][MAP_SIZE]; //初始化地圖 Initlize(MAP); bool isFull = false; int score = 0; while (!isFull) { //重新整理視窗 system("cls"); //生成數字 Generate(MAP); //顯示地圖 ShowMap(MAP, score); //輸入指令 char command; cin >> command; //移動地圖
MoveMap(MAP, command, score); //是否結束? isFull = IsOver(MAP); } system("pause"); return 0; }

可以看出我引用了兩個自定義的檔案,即OperateMap.hParameter.h

OperateMap.h定義了主函式中所用到的Initlize(), Generate(), ShowMap(), MoveMap(), IsOver()等函式。

Parameter.h則定義了一些重要的引數,諸如地圖大小MAP_SIZE

程式的邏輯比較容易看懂,就是很簡單的判斷isFull是否為ture,也就是地圖滿了沒,如果滿了,那就是遊戲結束。

初始化地圖

初始化地圖所用到的函式為Initlize(),具體實現過程如下

void Initlize(int(&MAP)[MAP_SIZE][MAP_SIZE]) {
    /*初始化地圖MAP*/
    cerr << "-----Initlize Finish!" << endl;
    for (int i = 0; i < MAP_SIZE; i++) {
        for (int j = 0; j < MAP_SIZE; j++) {
            MAP[i][j] = 0;
        }
    }
}

也就是通過引用傳遞MAP將其內所有元素設定為0.

隨機生成數字

在上面已經將地圖初始化了,但是全部格點都是0,在呈現給玩家看之前就需要先隨機生成一個點,這一步就是解決這一個問題的。

在剛開始的時候,我是從整個地圖中隨機生成一個座標,然後賦值2或者4。但是這樣子會讓程式效率十分低下,因為在後期格子只有少數幾個為0的情況下,隨機很難直接隨機到那幾個點,所以會導致不斷的生成座標點,效率極其低下。

為此做的對應的修改就是,首先將地圖遍歷一遍,記錄當前為0的格點,然後從這些格點當中抽出一個賦值為2或4即可。

對應的程式碼如下

void Generate(int(&MAP)[MAP_SIZE][MAP_SIZE]) {
    /*在地圖中生成隨機數*/
    //判斷生成2還是4
    int randNum[2] = { 2, 4 };
    int chose24;
    if (Rand021() <= 0.5) chose24 = 2;
    else chose24 = 4;

    int noZeroMAP[MAP_SIZE*MAP_SIZE][2], noZeroNum = 0;

    //將不是0的格子儲存下來, 從中選出一個生成
    for (int i = 0; i < MAP_SIZE; i++) {
        for(int j = 0; j < MAP_SIZE; j++) {
            if (MAP[i][j] != 0) {
                noZeroMAP[noZeroNum][0] = i;
                noZeroMAP[noZeroNum][1] = j;
                noZeroNum++;
            }
        }
    }
    int generatePos = RandA2B(0, noZeroNum-1);
    MAP[noZeroMAP[noZeroNum][0]][noZeroMAP[noZeroNum][1]] = chose24;
}

這裡用到的Rand021()是隨機生成0到1之間的隨機浮點數,和RandA2B()是隨機生成A到B之間的隨機整數,具體定義如下

//Rand.cpp
#include <cstdlib>
#include <ctime>

double Rand021() {
    srand((int)time(0));
    return rand() / double(RAND_MAX);
}

int RandA2B(int A, int B) {
    srand((int)time(0));
    return rand() % (B - A + 1) + A;
}

顯示地圖

顯示地圖相當於沒什麼技術含量了,就是簡單粗暴的直接輸出就好。不過為了地圖更好看,將0替換成-進行輸出。

void ShowMap(int(&MAP)[MAP_SIZE][MAP_SIZE], int score) {
    /*輸出地圖*/
    cout << "Now Your Game Map is: " << endl;
    cout << "---------------------------------" << endl;
    for (int i = 0; i < MAP_SIZE; i++) {
        for (int j = 0; j < MAP_SIZE; j++) {
            if (MAP[i][j] == 0) cout << "   " << "-";
            else cout << "  " << MAP[i][j];
        }
        cout << endl;
    }
    cout << "---------------------------------" << endl;
    cout << "Now Your Score is: " << score << endl;
    cout << "Plase Move Map(up:w down:s left:a right:d): ";
}

告一段落

下一部分就是移動地圖的內容了,內容比較多,所以我放在下一篇文章中進行講解。

如果有幫助的話還麻煩點個關注點個贊噢~

相關推薦

c++實現遊戲2048---

利用c++實現遊戲2048(命令列版) 寫在前面 在知乎上偶爾看到有人利用寫這種小程式練手,正好最近剛考完期末考試,所以就花了一個晚上寫了一下,也簡單的寫了一個2048. 以下是效果圖。 之前沒有用c++寫過比較大型的內容,對c++的理解也不是很

有限元剛度矩陣的一維變頻寬儲存C++實現

在有限元剛度矩陣的一維變頻寬儲存用C++實現(二)中,我們已經把總體剛度矩陣[K]中下三角部分的帶內元素順利存入pGK陣列中,現在我們來討論如何從pGK陣列中取出[K]內的任意元素。 從儲存了總剛矩陣[K]中的帶內元素的一維陣列pGK中取出總剛矩陣[K]的元素,主要是建立總

c#實現拼圖遊戲

上學期程式是設計實驗之二,用c#實現一個拼圖遊戲 (一)需求:(這個需求書寫較為簡單) 圖片:有圖 切割:拼圖不是一個圖,我們需要把一個整圖它切割成N*N的小圖 打亂:把這N*N的小圖打亂順序,才能叫拼圖qwq 判斷:判斷拼圖是否成功 互動:選擇滑鼠點選拖動

C#實現貪吃蛇遊戲

先說了,如果不會GDI+,類的定義這些基礎東西的,請先搜尋相關貼子學習。 這次教大家用C#做一個簡單的貪吃蛇遊戲。 先介紹用到的技術: GDI+ 定義類 列舉 因為C#是一門面向物件的語言,我們不用把所有程式碼都寫在一個窗體上,應該有一個分層思想(介面還介

C++實現連連看程式碼原理及解析()——消除演算法

C++連連看消除程式碼的實現,過程比較複雜。 【加入我們的學習群(C/C++群:892643663;Java群:957907127),大牛線上為您提供服務,還有免費編譯大禮包和視訊教程贈送哦】 以下是程式碼: #include<iostream> #include&l

C++實現二叉樹的種遍歷方式

- 非遞迴實現程式碼: #include<stdio.h> #include<stdlib.h> #include"data_structure.h" //建立一棵二叉樹 BTree create_tree() { BTree

VS下C++實現的簡單3D射擊遊戲(附遊戲檔案與源工程程式碼)

記不得什麼時候開始感興趣寫遊戲程式碼了。開始的時候就只是寫一些簡單的小遊戲,打檯球,開小車,走迷宮,用一些2Dgraphics庫,完成每個小作品後都很開心。後來一想,在現在的計算機裝置條件下,2D太簡陋了,於是開始著手做一個3D賽車遊戲。說是賽車,實際上也就只有一輛小車。模

C++實現約瑟夫環的問題

content 人在 -h tel padding next family bsp sun 約瑟夫問題是個有名的問題:N個人圍成一圈。從第一個開始報數,第M個將被殺掉,最後剩下一個,其余人都將被殺掉。比如N=6,M=5。被殺掉的人的序號為5,4,6。2。3。最後剩下1

c++實現高精度加法

strlen 數位 cout col 代碼 code pre 操作數 eof c++實習高精度加法 最近遇到一個c++實現高精度加法的問題,高精度問題往往十復雜但發現其中的規律後發現並沒有那麽復雜,這裏我實現了一個整數的高精度加法,主要需要註意以下幾點: 1:將所需

c實現的各種排序的方法

else print switch %d [] code article 選擇 ++ #include <stdio.h> void swap(int *a, int *b); void bubble_sort(int a[], int n); void

OpenCV實現Photoshop算法(): 曲線調整

快的 nes copy eve pla 很快 view 特點 色值 http://blog.csdn.net/c80486/article/details/52499919 系列文章: 用OpenCV實現Photoshop算法(一): 圖像旋轉 用OpenCV實現Photo

C/C++】:C實現輸出日期的陰歷日子

print http this while lunar void 大小 oid pan 前言 輸出陰歷一直是個老大難的問題。由於陰歷日子沒有規律。所以這裏須要做的就是通過打表的算法做到輸出陰歷日子,可是非常多人都不太了解原理,我這裏就給大家送上了一個福

C# 實現一個簡單的 Rest Service 供外部調

message [] operation rem adk www span method title 用 C# 實現一個簡單的 Restful Service 供外部調用,大體總結為4點: The service contract (the methods it o

C++實現利用(序和中序生成二叉樹)以及(二叉樹的鏡像)

lse pub 非遞歸 ace 方法 [] reorder spa push #include<iostream> #include<string.h> #include<stack> using namespace std; type

學習筆記-c實現三角函數的計算

math \n 數值 print spa 轉化 弧度 can ID 剛剛編好,記錄一下: #include <stdio.h> #include <math.h> int main(void) { while(1) {

RabbitMQ初探--C#實現通訊服務

download gin summary color 發送消息 sta 過程調用 change rod MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程序對應用程序的通信方法。應用程序通過讀寫出入隊列的消息(針對應用程序的數據)來通信,而無需專用連接來鏈

UniRx 實現 Timeline 式的異操作

lin code property set pos llb 等待 all 適合   沒接觸 UniRx 之前,我在 Unity 中通常用 Coroutine 或 Callback 來實現異步操作。根據我的任務,一般都是去實現遊戲組件的演出,比如:敵方角色圖形顯示後,我方角

c#實現文件的讀取和系列操作

static filename ros ima git int lin {0} ase Gitee代碼鏈接:https://gitee.com/hyr5201314/workcount 1.解題思路 首先要先讀取文件,然後調用函數實現返回文件的字符數,行數,單詞總數。用

c實現一個跳動的小球

#include<stdio.h> #include<stdlib.h> int main() {  int x=1,y=1,dirx=1,diry=1;  for(;;)  {   int line,col;   fo

c++實現環形陣列的最大子陣列之和(結對)

結對作業 1.分解問題,將環形陣列,剪開變成一個一維陣列。 2.用一維陣列的最大子陣列和解決。 對於一個環形陣列,對每一個一維陣列的表示共有n-1種 原始碼如下: 1 #include<iostream> 2 using namespace std; 3 int max_