---
# System prepended metadata

title: 小恐龍專案

---

# D1211137/貝俊德
****
==完整程式碼==
```
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <Windows.h>
#include <time.h>
#include <conio.h>

#define ROAD_LENGTH 50
#define DINO_PLACE  6

struct dino {
    char road[ROAD_LENGTH + 1];
    int  jump_Time_Left;
    int  score;
    int  wait_Time;
    int  barrier_Chance;
    bool invincible;
};

typedef struct dino Dino;

Dino* init(int mode) {
    Dino* MyDinoPtr = (Dino*)malloc(sizeof(Dino));

    if (MyDinoPtr != NULL) {
        MyDinoPtr->jump_Time_Left = 0;
        MyDinoPtr->score = 0;
        MyDinoPtr->wait_Time = 0; // 默认等待时间为0，即快速模式
        MyDinoPtr->barrier_Chance = 0; // 默认障碍物生成概率为0

        if (mode == 1) { // 简单模式
            MyDinoPtr->wait_Time = 100;
            MyDinoPtr->barrier_Chance = 7;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 2) { // 中等模式
            MyDinoPtr->wait_Time = 50;
            MyDinoPtr->barrier_Chance = 8;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 3) { // 困难模式
            MyDinoPtr->wait_Time = 25;
            MyDinoPtr->barrier_Chance = 10;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 4)
        {
            MyDinoPtr->wait_Time = 10;
            MyDinoPtr->barrier_Chance = 12;
            MyDinoPtr->invincible = true;
        }
        else if (mode == 5)
        {
            MyDinoPtr->barrier_Chance = 7;
            MyDinoPtr->wait_Time = 150;
            MyDinoPtr->invincible = false;
        }

        for (int i = 0; i < ROAD_LENGTH; i++) {
            MyDinoPtr->road[i] = '_';
        }

        MyDinoPtr->road[ROAD_LENGTH - 1] = 'X';
        MyDinoPtr->road[ROAD_LENGTH] = '\0';
    }

    return MyDinoPtr;
}

bool is_bumped(Dino* MyDinoPtr) {
    // 如果处于无敌状态，则无视障碍物
    if (MyDinoPtr->invincible) {
        return false;
    }
    return MyDinoPtr->jump_Time_Left == 0 && MyDinoPtr->road[DINO_PLACE] == 'X';
}

void display(Dino* MyDinoPtr) {
    system("cls");

    printf("\n\n\t");
    for (int i = 0; i < ROAD_LENGTH; i++) {
        if (i == DINO_PLACE && MyDinoPtr->jump_Time_Left > 0)
            printf("o");
        else
            printf(" ");
    }
    printf("\n\t");

    for (int i = 0; i < ROAD_LENGTH; i++) {
        if (i == DINO_PLACE && MyDinoPtr->jump_Time_Left == 0)
            printf("o");
        else
            printf("%c", MyDinoPtr->road[i]);
    }

    printf("\n\n\n");
    printf("\t\tyour score is: %d", MyDinoPtr->score);
    return;
}

void move(Dino* MyDinoPtr) {
    for (int i = 0; i < ROAD_LENGTH - 1; i++) {
        MyDinoPtr->road[i] = MyDinoPtr->road[i + 1];
    }
    MyDinoPtr->road[ROAD_LENGTH - 1] = '_';
}

bool space_pressed(void) {
    return _kbhit() != 0 && _getch() == 32;
}

bool spawn_barrier(Dino* MyDinoPtr) {
    int random_Number = rand() % 100;
    if (random_Number < MyDinoPtr->barrier_Chance) {
        return true;
    }
    return false;
}

void show_title_screen() {
    printf("\n\n");
    printf("\t\t\tDDDD   IIIIII  N     N   OOO   SSSSS   AAAAA   U     U  RRRRR\n");
    printf("\t\t\tD   D     I    NN    N  O   O  S       A     A  U     U  R    R\n");
    printf("\t\t\tD   D     I    N N   N  O   O  SSSSS   AAAAAAA  U     U  RRRRR\n");
    printf("\t\t\tD   D     I    N  N  N  O   O      S   A     A  U     U  R  R\n");
    printf("\t\t\tDDDD   IIIIII  N    NN   OOO   SSSSS   A     A   UUUUU   R   R\n");
    printf("\n");
    printf("\n\n");
    printf("\t\t\t                  Welcome to Dinosaur Game\n");
    printf("\t\t\t                  Press 'Enter' to start...\n");
    printf("\n\n");
}

void start_game() {
    system("cls");
    printf("                ██████████████  \n");
    printf("                ████░░████████████\n");
    printf("                ██████████████████\n");
    printf("                ██████████████████\n");
    printf("                ██████████████████\n");
    printf("                ████████          \n");
    printf("                ██████████████░░  \n");
    printf("                ██████            \n");
    printf("  ██            ██████████        \n");
    printf("  ██▒▒        ▒▒▒▒██████████▒▒▒▒  \n");
    printf("  ████▓▓      ██████████████  ▒▒  \n");
    printf("  ██████▒▒▒▒████████████████      \n");
    printf("  ██████████████████████████      \n");
    printf("    ██████████████████████        \n");
    printf("        ██████████████████        \n");
    printf("        ▒▒██████████████          \n");
    printf("          ▒▒██████▒▒██▓▓          \n");
    printf("            ████      ▓▓          \n");
    printf("            ██▒▒      ▓▓          \n");
    printf("            ██        ██          \n");
    printf("選擇遊戲難度:\n1. 簡單級別\n2. 中等級別\n3. 困難級別\n4. 氣急敗壞級別\n5. 正常模式\n");
}

int main() {
    srand(time(NULL));

    while (true) {
        show_title_screen(); // 显示片头画面

        // 等待用户按下 Enter 键开始游戏
        while (_getch() != 13); // 13 代表 Enter 键

        start_game();

        int mode;
        scanf("%d", &mode);

        while (mode < 1 || mode > 5) {
            printf("沒有這個模式,請重新輸入\n");
            scanf("%d", &mode);
        }

        Dino* MyDinoPtr = init(mode);
        display(MyDinoPtr);

        while (true) {
            // 在模式5下，每次循环判断空格键是否按下，若按下则将等待时间减少10
            if (mode == 5 && space_pressed()) {
                MyDinoPtr->wait_Time -= 5;
                if (MyDinoPtr->wait_Time < 0) {
                    MyDinoPtr->wait_Time = 0;
                }
                if (MyDinoPtr->jump_Time_Left == 0) {
                    MyDinoPtr->jump_Time_Left = 7;
                }
            }

            if (space_pressed() && MyDinoPtr->jump_Time_Left == 0)
                MyDinoPtr->jump_Time_Left = 7;

            move(MyDinoPtr);

            if (MyDinoPtr->jump_Time_Left > 0)
                MyDinoPtr->jump_Time_Left -= 1;

            if (spawn_barrier(MyDinoPtr)) {
                MyDinoPtr->road[ROAD_LENGTH - 1] = 'X';
            }

            if (is_bumped(MyDinoPtr)) {
                display(MyDinoPtr);
                break;
            }

            display(MyDinoPtr);
            MyDinoPtr->score++;

            Sleep(MyDinoPtr->wait_Time);
        }

        free(MyDinoPtr);

        printf("\nPress 'Enter' to restart or any other key to exit...\n");

        // 如果用户按下的不是 Enter 键，则退出游戏循环
        if (_getch() != 13) {
            break;
        }
    }

    return 0;
}



```
### 修改的功能
1. 在遊戲開始前添加了片頭，等待玩家點擊'Enter'鍵位才開始。如下圖
![Dino遊戲界面](https://hackmd.io/_uploads/BJSML_Sx0.png)

==修改的程式碼==
```
void show_title_screen() {
    printf("\n\n");
    printf("\t\t\tDDDD   IIIIII  N     N   OOO   SSSSS   AAAAA   U     U  RRRRR\n");
    printf("\t\t\tD   D     I    NN    N  O   O  S       A     A  U     U  R    R\n");
    printf("\t\t\tD   D     I    N N   N  O   O  SSSSS   AAAAAAA  U     U  RRRRR\n");
    printf("\t\t\tD   D     I    N  N  N  O   O      S   A     A  U     U  R  R\n");
    printf("\t\t\tDDDD   IIIIII  N    NN   OOO   SSSSS   A     A   UUUUU   R   R\n");
    printf("\n");
    printf("\n\n");
    printf("\t\t\t                  Welcome to Dinosaur Game\n");
    printf("\t\t\t                  Press 'Enter' to start...\n");
    printf("\n\n");
}

// 等待用户按下 Enter 键开始游戏
while (_getch() != 13); // 13 代表 Enter 键
```


2. 在點擊了'Enter'鍵後，會有四種等級的難度模式，簡單、中等、困難、以及氣急敗壞等級供玩家選擇。
![Dino遊戲](https://hackmd.io/_uploads/SkYnDD9xA.png)

==修改的程式碼==
```
void start_game() {
    system("cls");
    printf("                ██████████████  \n");
    printf("                ████░░████████████\n");
    printf("                ██████████████████\n");
    printf("                ██████████████████\n");
    printf("                ██████████████████\n");
    printf("                ████████          \n");
    printf("                ██████████████░░  \n");
    printf("                ██████            \n");
    printf("  ██            ██████████        \n");
    printf("  ██▒▒        ▒▒▒▒██████████▒▒▒▒  \n");
    printf("  ████▓▓      ██████████████  ▒▒  \n");
    printf("  ██████▒▒▒▒████████████████      \n");
    printf("  ██████████████████████████      \n");
    printf("    ██████████████████████        \n");
    printf("        ██████████████████        \n");
    printf("        ▒▒██████████████          \n");
    printf("          ▒▒██████▒▒██▓▓          \n");
    printf("            ████      ▓▓          \n");
    printf("            ██▒▒      ▓▓          \n");
    printf("            ██        ██          \n");
    printf("選擇遊戲難度:\n1. 簡單級別\n2. 中等級別\n3. 困難級別\n4. 氣急敗壞級別\n5. 正常模式\n");
}

while (mode < 1 || mode > 5) {
            printf("沒有這個模式,請重新輸入\n");
            scanf("%d", &mode);
        }
```


3. 各種模式的說明

| 簡單級別  | 中等級別 | 困難級別 |  氣急敗壞級別   |  正常級別   |
| -------- | -------- | -------- | --- | --- |
| 移速較慢，障礙物出現的機率較低    | 提高了百分之50%的移速，障礙物出現的機率高了一點      | 提高了百分之75%的移速，障礙物出現的機率比中等級別高了一點     | 為了照顧玩家的體驗，防止玩家氣急敗壞或是玩傻了。所以設置了這個模式，在這個模式裡玩家是無敵的     |    就跟網上的小恐龍一樣，小恐龍的移速會由慢至快一直遞增     |

==修改的程式碼==
```
        if (mode == 1) { // 简单模式
            MyDinoPtr->wait_Time = 100;
            MyDinoPtr->barrier_Chance = 7;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 2) { // 中等模式
            MyDinoPtr->wait_Time = 50;
            MyDinoPtr->barrier_Chance = 8;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 3) { // 困难模式
            MyDinoPtr->wait_Time = 25;
            MyDinoPtr->barrier_Chance = 10;
            MyDinoPtr->invincible = false;
        }
        else if (mode == 4)
        {
            MyDinoPtr->wait_Time = 10;
            MyDinoPtr->barrier_Chance = 12;
            MyDinoPtr->invincible = true;
        }
        else if (mode == 5)
        {
            MyDinoPtr->barrier_Chance = 7;
            MyDinoPtr->wait_Time = 150;
            MyDinoPtr->invincible = false;
        }
        
        // 在模式5下，每次循环判断空格键是否按下，若按下则将等待时间减少10
            if (mode == 5 && space_pressed()) {
                MyDinoPtr->wait_Time -= 5;
                if (MyDinoPtr->wait_Time < 0) {
                    MyDinoPtr->wait_Time = 0;
                }
                if (MyDinoPtr->jump_Time_Left == 0) {
                    MyDinoPtr->jump_Time_Left = 7;
                }
            }
```


4. 在遊戲結束時加入了退出或重新開始
![Dino片尾](https://hackmd.io/_uploads/BkJJ9v9xC.png)
當玩家點擊除Enter以外的鍵位，就會直接退出，若是點擊Enter則會回到選擇模式的界面。

==修改的程式碼==
```
        printf("\nPress 'Enter' to restart or any other key to exit...\n");

        // 如果用户按下的不是 Enter 键，则退出游戏循环
        if (_getch() != 13) {
            break;
        }
```

