C++小遊戲

一仁賴語穗    一和呂念潔    一勇阮心宥    陳飛妃

報告

簡報

程式

賴語穗、陳飛妃

靈感

賴語穗、陳飛妃、呂念潔、阮心宥

工作分配

賴語穗、陳飛妃
賴語穗、陳飛妃、呂念潔、阮心宥
  • 本作品為以最初版本的 2048 規則為基礎所開發的小遊戲。
  • 遊戲在 4×4 的棋盤中進行,玩家透過鍵盤方向鍵控制方塊移動,使相同數字的方塊在滑動過程中碰撞並合併成更大的數字。
  • 目標是逐步合成出 2048。

作品介紹

遊戲規則

  • 每次移動後隨機在空格生成一個新方塊

3. 生成新方塊

  • 棋盤填滿
  • 且無任何相鄰方塊可以合併

4. 失敗條件

  • 相同數字碰撞會合併
  • 每次滑動中,每個方塊最多只能合併一次

2. 合併規則

1. 操作方式

  • 使用鍵盤 WASD
  • 每次移動時,整個棋盤的數字會往同一方向滑動

1. 操作方式

# CHAPTER 2

程式介紹

1

Discovery of requirements for a project.

2

Research into the project space, competitors and the market.

3

Creating a Plan that sets the requirements for the design and build phases.

5

Review and Iterate on the designs with testing of ideas, client feedback and prototypes.

4

Design a number of iterations that capture the plans and requirements.

6

Build the project to an MVP to test and evaluate. Iterate using these learnings.

#include<iostream>
#include<vector>//動態陣列
#include<cstdlib>//產生亂數
#include<ctime>//計算時間
#include<iomanip>//輸出格式
# PRESENTING CODE

標頭檔

using namespace std;

int a[4][4]={0},n=4;//初始棋盤生成

struct zero{//記錄空格的位置
    int r, c;
};
# PRESENTING CODE
void rd(){
    vector<zero>emp;
    bool f=false;//不能放數字

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(a[i][j]==0){//可以放新數字
                emp.push_back({i, j});//座標存進emp
                f=true;//可以放數字的話
            }
        }
    }
    if(f){//可以放新數字
        int r=rand()%emp.size();//限制在 0 ~ emp.size()-1
        zero t=emp[r];//第 r 個座標存進 t
        a[t.r][t.c]=(rand()%10==0)?4:2;//條件式 ? 成立時的值 : 不成立時的值;
    }
}
# PRESENTING CODE

各函式功能  rd()

void p(){
    system("cls");

    cout<<"--- C++ 2048 GAME ---"<<endl;
    string Border="+------+------+------+------+";//可愛的邊界

    for(int i=0; i<n ; i++){
        cout<<Border<<endl;//放出結界

        for(int j=0; j<n ; j++){
            cout<<"|";//每個格子中間的槓槓

            if(a[i][j]==0){
                cout<<setw(7);
            }

            else{
                cout<<setw(6)<<a[i][j];//固定格子的寬度
            }
        }
        cout<<"|"<<endl;//每個格子中間的槓槓
    }
    cout<<Border<<endl;//把格子輸出
    cout<<"控制方式--->[W]是上 [S]是下 [A]是左 [D]是右"<<endl;
}
# PRESENTING CODE

各函式功能  p()

bool left(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=0 ; j<n ; j++){
                if(a[i][j]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k>0 && a[i][k-1]==0){//如果左邊沒東西的話,全部過去
                        a[i][k-1]=a[i][k];
                        a[i][k]=0;
                        k--;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=0 ; j<n ; j++){
                    if(a[i][j]!=0 && a[i][j]==a[i][j+1]){
                        a[i][j]*=2;
                        a[i][j+1]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=0 ; j<n ; j++){
                    if(a[i][j]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k>0 && a[i][k-1]==0){
                        a[i][k-1]=a[i][k];
                        a[i][k]=0;
                        k--;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
# PRESENTING CODE

各函式功能  left()

bool right(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=n-2 ; j>=0 ; j--){
                if(a[i][j]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k<n -1 && a[i][k+1]==0){//如果右邊沒東西的話,全部過去
                        a[i][k+1]=a[i][k];
                        a[i][k]=0;
                        k++;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=n-2 ; j>= 0 ; j--){
                    if(a[i][j]!=0 && a[i][j]==a[i][j+1]){
                        a[i][j]*=2;
                        a[i][j+1]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=n - 2 ; j>=0 ; j--){
                    if(a[i][j]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k<n - 1 && a[i][k+1]==0){
                        a[i][k+1]=a[i][k];
                        a[i][k]=0;
                        k++;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
# PRESENTING CODE

各函式功能  right()

bool down(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=n-2 ; j>=0 ; j--){
                if(a[j][i]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k<n -1 && a[k+1][i]==0){//如果下面沒東西的話,全部過去
                        a[k+1][i]=a[k][i];
                        a[k][i]=0;
                        k++;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=n-2 ; j>= 0 ; j--){
                    if(a[j][i]!=0 && a[j][i]==a[j+1][i]){
                        a[j+1][i]*=2;
                        a[j][i]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=n - 2 ; j>=0 ; j--){
                    if(a[j][i]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k<n - 1 && a[k+1][i]==0){
                        a[k+1][i]=a[i][k];
                        a[k][i]=0;
                        k++;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
# PRESENTING CODE

各函式功能  down()

bool up(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=0 ; j<n ; j++){
                if(a[j][i]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k>0 && a[k-1][i]==0){//如果上面沒東西的話,全部過去
                        a[k-1][i]=a[k][i];
                        a[k][i]=0;
                        k--;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=0 ; j< n ; j++){
                    if(a[j][i]!=0 && a[j][i]==a[j-1][i]){
                        a[j-1][i]*=2;
                        a[j][i]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=0 ; j<n ; j++){
                    if(a[j][i]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k>0 && a[k-1][i]==0){
                        a[k-1][i]=a[k][i];
                        a[k][i]=0;
                        k--;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
   
# PRESENTING CODE

各函式功能  up()

 bool gameover(){
        bool g = false;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(a[i][j] == 0){
                    g = true;
                }else if(a[i][j] == a[i+1][j] && i < 3){
                    g = true;
                }else if(a[i][j] == a[i- 1][j] && i > 0){
                    g = true;
                }else if(a[i][j] == a[i][j+1] && j < 3){
                    g = true;
                }else if(a[i][j] == a[i][j-1] && i > 0){
                    g = true;
                }
            }
        }
        return g;
    }
# PRESENTING CODE

各函式功能  gameover()

int main() {
    srand(time(0));
    rd();
    rd();
    //2048一開始畫面上會有兩個數字,所以rd()呼叫兩次
    p();

    char t;



    while(cin >> t){
        if(!gameover()){
            cout<<"--- GAME OVER ---";
            break;
        }

        if(t == 'W'){
            up();
            rd();
            p();
        }else if(t== 'S'){
            down();
            rd();
            p();
        }else if(t == 'A'){
            left();
            rd();
            p();
        }else if(t == 'D'){
            right();
            rd();
            p();
        }
    }
    return 0;
}
# PRESENTING CODE

主程式

#include<iostream>
#include<vector>//動態陣列
#include<cstdlib>//產生亂數
#include<ctime>//計算時間
#include<iomanip>//輸出格式
using namespace std;

int a[4][4]={0},n=4;//初始棋盤生成

struct zero{//記錄空格的位置
    int r, c;
};

void rd(){
    vector<zero>emp;
    bool f=false;//如果不能放數字

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(a[i][j]==0){//如果=0表示可以放新數字
                emp.push_back({i, j});//把這個可以放新數字的座標存進emp
                f=true;//如果這個地方可以放數字的話,f=true
            }
        }
    }


    if(f){//如果有空格
        int r=rand()%emp.size();//結果限制在 0 ~ emp.size()-1
        zero t=emp[r];//從 emp 裡取出第 r 個空格座標,存進 t
        a[t.r][t.c]=(rand()%10==0)?4:2;//條件式 ? 成立時的值 : 不成立時的值;
    }
}

void p(){
    system("cls");

    cout<<"--- C++ 2048 GAME ---"<<endl;
    string Border="+------+------+------+------+";//可愛的邊界

    for(int i=0; i<n ; i++){
        cout<<Border<<endl;//放出結界

        for(int j=0; j<n ; j++){
            cout<<"|";//每個格子中間的槓槓

            if(a[i][j]==0){
                cout<<setw(6)<<" ";
            }

            else{
                cout<<setw(6)<<a[i][j];//固定格子的寬度
            }
        }
        cout<<"|"<<endl;//每個格子中間的槓槓
    }
    cout<<Border<<endl;//把格子輸出
    cout<<"控制方式--->[W]是上 [S]是下 [A]是左 [D]是右"<<endl;
}

    bool left(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=0 ; j<n ; j++){
                if(a[i][j]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k>0 && a[i][k-1]==0){//如果左邊沒東西的話,全部過去
                        a[i][k-1]=a[i][k];
                        a[i][k]=0;
                        k--;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=0 ; j<n ; j++){
                    if(a[i][j]!=0 && a[i][j]==a[i][j+1]){
                        a[i][j]*=2;
                        a[i][j+1]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=0 ; j<n ; j++){
                    if(a[i][j]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k>0 && a[i][k-1]==0){
                        a[i][k-1]=a[i][k];
                        a[i][k]=0;
                        k--;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
    bool right(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=n-2 ; j>=0 ; j--){
                if(a[i][j]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k<n -1 && a[i][k+1]==0){//如果右邊沒東西的話,全部過去
                        a[i][k+1]=a[i][k];
                        a[i][k]=0;
                        k++;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=n-2 ; j>= 0 ; j--){
                    if(a[i][j]!=0 && a[i][j]==a[i][j+1]){
                        a[i][j]*=2;
                        a[i][j+1]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=n - 2 ; j>=0 ; j--){
                    if(a[i][j]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k<n - 1 && a[i][k+1]==0){
                        a[i][k+1]=a[i][k];
                        a[i][k]=0;
                        k++;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }

    bool down(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=n-2 ; j>=0 ; j--){
                if(a[j][i]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k<n -1 && a[k+1][i]==0){//如果下面沒東西的話,全部過去
                        a[k+1][i]=a[k][i];
                        a[k][i]=0;
                        k++;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=n-2 ; j>= 0 ; j--){
                    if(a[j][i]!=0 && a[j][i]==a[j+1][i]){
                        a[j+1][i]*=2;
                        a[j][i]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=n - 2 ; j>=0 ; j--){
                    if(a[j][i]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k<n - 1 && a[k+1][i]==0){
                        a[k+1][i]=a[i][k];
                        a[k][i]=0;
                        k++;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }

    bool up(){
        bool moved=false;
        for(int i=0 ; i<n ; i++){
            for(int j=0 ; j<n ; j++){
                if(a[j][i]==0){
                        continue;
                }
                    int k=j;//如果用j的話會毀掉原本的計數器

                    while(k>0 && a[k-1][i]==0){//如果上面沒東西的話,全部過去
                        a[k-1][i]=a[k][i];
                        a[k][i]=0;
                        k--;
                        moved=true;
                    }
                }

                for(int i=0 ; i<n ; i++){//遇到相同的數字就併過去
                        for(int j=0 ; j< n ; j++){
                    if(a[j][i]!=0 && a[j][i]==a[j-1][i]){
                        a[j-1][i]*=2;
                        a[j][i]=0;
                        moved=true;
                    }
                        }
                }

                for(int j=0 ; j<n ; j++){
                    if(a[j][i]==0){
                        continue;
                    }
                    int k=j;//如果用j的話會毀掉原本的計數器
                    while(k>0 && a[k-1][i]==0){
                        a[k-1][i]=a[k][i];
                        a[k][i]=0;
                        k--;
                        moved=true;
                    }
                }
            }
            return moved;//回報主程式
    }
    bool gameover(){
        bool g = false;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(a[i][j] == 0){
                    g = true;
                }else if(a[i][j] == a[i+1][j] && i < 3){
                    g = true;
                }else if(a[i][j] == a[i- 1][j] && i > 0){
                    g = true;
                }else if(a[i][j] == a[i][j+1] && j < 3){
                    g = true;
                }else if(a[i][j] == a[i][j-1] && i > 0){
                    g = true;
                }
            }
        }
        return g;
    }

int main() {
    srand(time(0));
    rd();
    rd();
    //2048一開始畫面上會有兩個數字,所以rd()呼叫兩次
    p();

    char t;



    while(cin >> t){
        if(!gameover()){
            cout<<"--- GAME OVER ---";
            break;
        }

        if(t == 'W'){
            up();
            rd();
            p();
        }else if(t== 'S'){
            down();
            rd();
            p();
        }else if(t == 'A'){
            left();
            rd();
            p();
        }else if(t == 'D'){
            right();
            rd();
            p();
        }
    }
    return 0;
}
# PRESENTING CODE

完整程式

Made with Slides.com