1. 程式人生 > >C++ 實現 2048 (控制檯版)

C++ 實現 2048 (控制檯版)

// 山寨黑框框 2048

#include 
#include 
#include 
using namespace std;
#define rand(x) ( rand() % (x) ) 
#define UP    1
#define DOWN  2
#define LEFT  3
#define RIGHT 4
struct POS
{
    int x;
    int y;
};
class Game
{
public:
    Game();
    ~Game();
    int  get_random_2or4();
    bool get_null_pos(POS &pos);
    bool set_2or4_pos(int m,POS &pos);
    bool merge(int direction,bool realMerge);        
    bool isGameOver();
    bool set_userinput(char c);
    bool has2048();
    void printArray();
private:    
    int a[4][4];
};
Game::Game()
{
    // 設定隨機數種子
    srand((unsigned(time(0))));
    // 初始化陣列
    for(int i = 0; i < 4;i++)
        for(int j = 0;j < 4;j++)
            a[i][j] = 0;
    for(int i = 0; i < 2;i++)
    {
        // 隨機生成2或4
        int m = get_random_2or4();
        // 設定數字位置
        POS pos;
        get_null_pos(pos);
        set_2or4_pos(m,pos);
    }
    printArray();
}
Game::~Game()
{
    
}
int Game::get_random_2or4()
{
    int m = rand(4); // 返回0,1,2,3
    
    // 返回2 和4 的比例為3 : 1
    return m < 3 ? 2 : 4; 
}
bool Game::get_null_pos(POS &pos)
{
    POS available_pos[16];
    int n = 0;
    for(int i = 0;i < 4;i++)
        for(int j = 0;j < 4;j++)
            if(a[i][j] == 0)
            {
                available_pos[n].x = i;
                available_pos[n].y = j;
                n++;
            }
    // 沒有空餘位置
    if(n == 0)
        return false;
    else
    {
        int rand_i = rand(n);
        pos = available_pos[rand_i];
        return true;
    }
}
bool Game::set_2or4_pos(int m,POS &pos)
{
    a[pos.x][pos.y] = m;
    return true;
}
bool Game::merge(int direction,bool realMerge = false)
{
    int nRet = false;
    // 拷貝陣列a到陣列b
    int b[4][4];
    for(int i = 0;i < 4;i++)
        for(int j = 0;j < 4;j++)
            b[i][j] = a[i][j];
    if(direction == UP)
    {
        // 向上合併
        for(int i = 0;i < 4;i++)
        {
            int has_merge = false; // 對一行只合並一次
            for(int j = 1;j < 4;j++)
            {
                // 若位置為空,跳過
                if(b[j][i] == 0)
                    continue;
                // 該位置非空
                int former_index = j;
                int current_index = j - 1;
                int val = b[j][i];
                // 向上替換掉空位置直到頂部或者遇到方塊
                while(current_index >= 0 && b[current_index][i] == 0)
                {
                    b[current_index][i] = val;
                    b[former_index][i]  = 0;
                    former_index = current_index;
                    current_index -- ;
                }
                // 如果遇到的是相同方塊
                if(current_index >= 0 && b[current_index][i] == val)
                {
                    if(!has_merge)    // 若該行未合併過,則合併
                    {
                        has_merge = true;
                        b[current_index][i] *= 2;
                        b[former_index][i]   = 0;
                    }
                }
            }
            if(has_merge == true)
                nRet = true;
        }
        
    }
    if(direction == DOWN)
    {
        // 向上合併
        for(int i = 0;i < 4;i++)
        {
            int has_merge = false; // 對一行只合並一次
            for(int j = 2;j >= 0;j--)
            {
                // 若位置為空,跳過
                if(b[j][i] == 0)
                    continue;
                // 該位置非空
                int former_index = j;
                int current_index = j + 1 ;
                int val = b[j][i];
                // 向上替換掉空位置直到頂部或者遇到方塊
                while(current_index < 4 && b[current_index][i] == 0)
                {
                    b[current_index][i] = val;
                    b[former_index][i]  = 0;
                    former_index = current_index;
                    current_index ++ ;
                }
                // 如果遇到的是相同方塊
                if(current_index < 4 && b[current_index][i] == val)
                {
                    if(!has_merge)    // 若該行未合併過,則合併
                    {
                        has_merge = true;
                        b[current_index][i] *= 2;
                        b[former_index][i]   = 0;
                    }
                }
            }
            if(has_merge == true)
                nRet = true;
        }
    }
    if(direction == LEFT)
    {
        // 向左合併
        for(int i = 0; i < 4; i++)
        {
            int has_merge = false; // 對一行只合並一次
            for(int j = 1;j < 4 ; j ++)
            {
                if(b[i][j] == 0)
                    continue;
                int former_index = j;
                int current_index = j - 1;
                int val = b[i][j];
                //// 向上替換掉空位置直到頂部或者遇到方塊
                while(current_index >= 0 && b[i][current_index] == 0)
                {
                    b[i][current_index] = val;
                    b[i][former_index]  = 0;
                    former_index = current_index;
                    current_index -- ;
                }
                // 如果遇到的是相同方塊
                if(current_index >= 0 && b[i][current_index] == val)
                {
                    if(!has_merge)    // 若該行未合併過,則合併
                    {
                        has_merge = true;
                        b[i][current_index] *= 2;
                        b[i][former_index]   = 0;
                    }
                }
            }
            if(has_merge == true)
                nRet = true;
            }
        }
    if(direction == RIGHT)
    {
        // 向右合併
        for(int i = 0; i < 4; i++)
        {
            int has_merge = false; // 對一行只合並一次
            for(int j = 2;j >= 0 ; j --)
            {
                if(b[i][j] == 0)
                    continue;
                int former_index = j;
                int current_index = j + 1;
                int val = b[i][j];
                //// 向上替換掉空位置直到頂部或者遇到方塊
                while(current_index < 4 && b[i][current_index] == 0)
                {
                    b[i][current_index] = val;
                    b[i][former_index]  = 0;
                    former_index = current_index;
                    current_index ++ ;
                }
                // 如果遇到的是相同方塊
                if(current_index < 4 && b[i][current_index] == val)
                {
                    if(!has_merge)    // 若該行未合併過,則合併
                    {
                        has_merge = true;
                        b[i][current_index] *= 2;
                        b[i][former_index]   = 0;
                    }
                }
            }
            if(has_merge == true)
                nRet = true;
            }
        }
    if(realMerge == true)
    {
        for(int i = 0;i < 4;i++)
            for(int j = 0;j < 4;j++)
                a[i][j] = b[i][j];
    }
    return nRet;
}
bool Game::isGameOver()
{
    POS pos;
    if(get_null_pos(pos) == false)
    {
        int nRet = false;
        nRet |= merge(UP,false);
        nRet |= merge(DOWN,false);
        nRet |= merge(LEFT,false);
        nRet |= merge(RIGHT,false);
        if(nRet == false)
            return true;
    }
    return false;
}
bool Game::set_userinput(char c)
{
    int direction = 0;
    switch (c)
    {
        case 'i':
            direction = UP;break;
        case 'k':
            direction = DOWN;break;
        case 'j':
            direction = LEFT;break;
        case 'l':
            direction = RIGHT;break;
        default:
            return false;
    }
    // 合併
    merge(direction,true);
    
    int m = get_random_2or4();
    POS pos;
    if(get_null_pos(pos))
        set_2or4_pos(m,pos);
    printArray();
    return true;
}
void Game::printArray()
{
    static long turns = 1;
            // -------------------------
         //    |     |     |     |     |
         //    -------------------------
         //    |     |     |     |     |
         //    -------------------------
         //    |     |     |     |     |
         //    -------------------------
         //    |     |     |     |     |
         //    -------------------------
    cout << "這是第"<< left << setw(5) << turns++ << "輪"<< endl;
    for(int i = 0;i < 25;i++)
        cout << '-';
    cout << endl;
    for(int i = 0; i < 4;i++)
    {
        
        for(int j = 0;j < 4;j++)
        {
            cout << '|';
            cout << ' ';
            if(a[i][j] != 0)
                cout << left << setw(4) << a[i][j];
            else
                cout << left << setw(4) << ' ';
        }
        cout << '|';
        cout << endl;
        for(int k = 0;k < 25;k++)
            cout << '-';
        cout << endl;
    }
    cout << endl;
}
bool Game::has2048()
{
    for(int i = 0; i < 4 ;i++)
        for(int j = 0; j < 4;j++)
            if(a[i][j] == 2048)
                return true;
    return false;
}

相關推薦

C++ 實現 2048 控制檯

// 山寨黑框框 2048 #include #include #include using namespace std; #define rand(x) ( rand() % (x) ) #define UP 1 #define DOWN 2 #define LEFT 3 #define

jCryptoJS 、C#互通加密MD5

使用 nbsp script odi sta 1.8 nic 格式 ret /////////////////////////////////////////////////////////前端代碼//////////////////////////////////////

Redis 分布式鎖的正確實現方式 Java

想要 uda 就是 tex implement 代碼實現 key eval() attach 前言 分布式鎖一般有三種實現方式:1. 數據庫樂觀鎖;2. 基於Redis的分布式鎖;3. 基於ZooKeeper的分布式鎖。本篇博客將介紹第二種方式,基於Redis實現分布式鎖。

C++ 2017提高組C++初賽試題答案

CCF NOIP2016 初賽提高組C++語言試題第 1 頁,共10 頁第二十三屆全國青少年資訊學奧林匹克聯賽初賽提高組C++語言試題競賽時間:2017 年10 月14 日14:30~16:30選手注意: 試題紙共有10 頁,答題紙共有2 頁,滿分100 分。請在答題紙上作答,寫在試題紙上的一律無效。 不

Redis 分散式鎖的正確實現方式 Java

前言 分散式鎖一般有三種實現方式:1. 資料庫樂觀鎖;2. 基於Redis的分散式鎖;3. 基於ZooKeeper的分散式鎖。本篇部落格將介紹第二種方式,基於Redis實現分散式鎖。雖然網上已經有各種介紹Redis分散式鎖實現的部落格,然而他們的實現卻有著各種各樣的問題,為

pyqt5 登入介面的實現模板加強

說明 本例,在登入介面第一版的基礎上,增加了主介面的登出功能和退出功能。 登出功能 # 動作一:登出 def on_printAction1_triggered(self): self.close() dialog

C++實現佇列迴圈佇列

一、佇列的操作: 、1、入隊(從尾入隊) 將值存入rear所代表的位置 rear = (rear + 1)% 陣列的長度   2、 出隊(頭部出隊) front = (front + 1)% 陣列的長度   3、 佇列是否為空 front 和 rear的值相等,則該

opencv兩視訊疊加控制檯

//#include "stdafx.h" #include <iostream> #include <cv.h> //#include <cxcore.h> #include <cxcore.h> #in

C#貪吃蛇WPF

最近寫了個貪吃蛇,雖然有很多BUG,但是還是拿出來讓大家看下! 額,我用的還是VS2010. 首先,新建專案——WPF應用程式 將 canvas設定為定義為lol 接下來是引用部分 新增 using System.Windows.Threading;

Redis分散式鎖的正確實現方式Java

前言 分散式鎖一般有三種實現方式:1. 資料庫樂觀鎖;2. 基於Redis的分散式鎖;3. 基於ZooKeeper的分散式鎖。本篇部落格將介紹第二種方式,基於Redis實現分散式鎖。雖然網上已經有各種介紹Redis分散式鎖實現的部落格,然而他們的實現卻有著各種各樣的問題

資料結構、演算法與應用C++語言描述第二 第一章部分練習參考答案

1、 void swap(int& x,int& y) {//交換x,y int temp=x; x=y; y=temp; } 2、 template<class T,unsigned N> size_t count(const T (

用連結串列實現Java

/** /** * 用單鏈表實現棧 * * 表示連結串列的一個節點 * @author ly * */ public class Node { Object element; Node next; public Node(Object element){ this(elemen

C程式設計語言第二-讀書筆記

The C Programming Language 1. 設計一個程式,作用為無限字元輸出: int c; printf(“Please in put the char …\n”); //getc

C語言程式設計第二第6章程式設計題

1:找出與平均值相差最小的元素 #include"stdio.h" #include"math.h" #define N 10 void main() { int i; double a[N],v=0,min; printf("Please input

c程式設計語言第二學習】20160326

\b 退格 printf("請輸入您的身高:______英寸\b\b\b\b\b\b\b\b\b", ); %e 用法 #include<stdio.h> int main(void) { float a; printf("please input

Redis 分散式鎖的正確實現方式 Java [轉]

分散式鎖一般有三種實現方式:1. 資料庫樂觀鎖;2. 基於Redis的分散式鎖;3. 基於ZooKeeper的分散式鎖。本篇部落格將介紹第二種方式,基於Redis實現分散式鎖。雖然網上已經有各種介紹Redis分散式鎖實現的部落格,然而他們的實現卻有著各種各樣的問題,為了避

【演算法】二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現記錄Java

        本文總結了刷LeetCode過程中,有關樹的遍歷的相關程式碼實現,包括了二叉樹、N叉樹先序、中序、後序、BFS、DFS遍歷的遞迴和迭代實現。這也是解決樹的遍歷問題的固定套路。 一、二叉樹的先序、中序、後序遍歷  1、遞迴模板  (1)

C++實現2048小遊戲控制檯

無聊,在公司寫了個2048小遊戲的程式,聊以自娛。(事實是我手機壞了,沒得玩)。 很簡單,直接上程式碼了。 #include <iostream> #include <windows.h> #include <ctime> using

C語言執行結果控制檯視窗表格的實現最基礎

先放張效果圖: 這就是一個簡單的表格(複雜的我辦不到!!),而這個表格的實現也是非常簡單的,就是簡單的 printf 輸出: #include <stdio.h> int main() { printf("=================================

c++實現2048遊戲控制檯

#ifndef CGAME_H #define CGAME_H #include <windows.h> #include <String> #define ROW 4 //格子總行數 #define COLUMN 4 //格子總列數 class cGame { pub