---
# System prepended metadata

title: 小恐龍進化了

---

# 小恐龍進化了
## 增加特殊技能
*  激光![](https://i.imgur.com/aEhYPmL.jpg)


### 技能介紹
激光:當按下左側 shift 鍵時，特殊技能進入冷卻狀態，隨後，當按下空白鍵時，如果特殊技能已準備好且前方有障礙物，激光就會發射，特殊技能也會進入冷卻狀態。
#### 修改程式碼部分

檢查是否有障礙物
```javascript=
bool spawn_barrier(Dino* MyDino)
{
    // 產生一個 0-99 的亂數
    int random_number = rand() % 100;
    // 如果亂數小於 Dino 結構的屬性 barrier_chance
    if (random_number < MyDino->barrier_chance) {
        // 如果道路最後兩格或最後三格已經有障礙物，就返回 true
        if (MyDino->road[ROAD_LENGTH - 2] == 'X' || MyDino->road[ROAD_LENGTH - 3] == 'X') {
            return true;
        }
        // 如果道路最後兩格或最後三格沒有障礙物，就返回 false
        return false;
    }
    // 如果亂數大於等於 Dino 結構的屬性 barrier_chance，就返回 false
    return false;
}
```

滿足發動特殊技能的條件時，就發射激光
```javascript=
bool spawn_barrier(Dino* MyDino, bool has_special_skill)
{
    int random_number = rand() % 100; // 隨機產生0~99的整數
    if (random_number < MyDino->barrier_chance) { // 如果隨機數小於恐龍障礙物生成機率
        if (has_special_skill && MyDino->road[ROAD_LENGTH - 2] != 'X') { // 如果發動了特殊技能，且前方一格不是障礙物
            MyDino->road[ROAD_LENGTH - 2] = '|'; // 發射激光，放置一格激光符號
            return false; // 不放置障礙物
        }
        else { // 如果沒有發動特殊技能，或者前方一格已經有障礙物了
            MyDino->road[ROAD_LENGTH - 1] = 'X'; // 放置一格障礙物
            return true; // 放置了障礙物
        }
    }
    return false; // 如果沒有生成障礙物，返回false
}

```
玩家是否擁有特殊技能，在使用特殊技能時，同時不會放置障礙物
```javascript=
int main()
{
    /* 初始化 */
    srand(time(NULL)); // 用當前時間作為種子，初始化亂數產生器
    Dino* MyDino = init(); // 初始化恐龍，得到一個指向該物件的指針
    bool has_special_skill = true; // 設置玩家擁有特殊技能

    display(MyDino); // 渲染呈現畫面

    /* 遊戲本體 */
    while (true) // 無限循環，直到遊戲結束
    {
        /* 邏輯運算 */
        if (space_pressed() && MyDino->jump_time_left == 0 && has_special_skill) // 判斷是否擁有特殊技能，並且玩家按下空白鍵
        {
            MyDino->road[ROAD_LENGTH - 2] = '|'; // 發射激光
        }
        else if (space_pressed() && MyDino->jump_time_left == 0) // 如果玩家按下空白鍵，且現在不在跳躍中
        {
            MyDino->jump_time_left = 7; // 設置跳躍時間
        }
        move(MyDino); // 移動恐龍的位置
        if (spawn_barrier(MyDino, has_special_skill)) // 檢查是否要放置障礙物，並且是否可以使用特殊技能
        {
            MyDino->road[ROAD_LENGTH - 1] = 'X'; // 在路上放置障礙物
        }
        if (MyDino->jump_time_left > 0) // 如果現在在跳躍中
            MyDino->jump_time_left -= 1; // 減少跳躍時間
        if (is_bumped(MyDino)) // 檢查是否碰到了障礙物
        {
            display(MyDino); // 重新渲染畫面，顯示最後得分
            break; // 結束遊戲循環
        }

        /* 渲染呈現 */
        display(MyDino); // 渲染呈現畫面
        MyDino->score++; // 增加得分
        Sleep(MyDino->wait_time); // 程式暫停一段時間，使得畫面更新的速度有所限制
    }
    return 0; 
}
```

#### 完整程式碼

```javascript=
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<windows.h>
#include<time.h>

#define ROAD_LENGTH 50 //路面長度
#define DINO_PLACE 6   //小恐龍在路面上的第幾格

struct dino {
    char road[ROAD_LENGTH + 1];//字串結尾需要'\0'
    int jump_time_left;      //還剩多久掉回地面
    int score;               //分數
    int wait_time;           //每次迴圈之間等待的時間
    int barrier_chance;      //放置障礙物的機率
};
typedef struct dino Dino;

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

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

    if (MyDino->road[ROAD_LENGTH - 2] == '|') { // 激光向右移動
        MyDino->road[ROAD_LENGTH - 3] = '_';
        MyDino->road[ROAD_LENGTH - 2] = '_';
    }
    else { // 障礙物向右移動
        MyDino->road[ROAD_LENGTH - 1] = '_';
        MyDino->road[ROAD_LENGTH - 2] = 'X';
    }

    MyDino->road[ROAD_LENGTH - 1] = '_';
    MyDino->road[ROAD_LENGTH] = '\0';
}


Dino* init(void)
{
    Dino* MyDino = (Dino*)malloc(sizeof(Dino));

    if (MyDino != NULL)
    {
        MyDino->score = 0;
        MyDino->jump_time_left = 0;
        MyDino->wait_time = 150;
        MyDino->barrier_chance = 10;

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

        MyDino->road[ROAD_LENGTH] = '\0';
    }

    return MyDino;
}

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

    printf("\n\n\t");



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


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

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

    return;
}

bool spawn_barrier(Dino* MyDino)
{
    int random_number = rand() % 100;
    if (random_number < MyDino->barrier_chance) {
        if (MyDino->road[ROAD_LENGTH - 2] == 'X' || MyDino->road[ROAD_LENGTH - 3] == 'X') {
            // 如果前方有障碍物，就返回true
            return true;
        }
        return false;
    }
    return false;
}


bool spawn_barrier(Dino* MyDino, bool has_special_skill)
{
    int random_number = rand() % 100;
    if (random_number < MyDino->barrier_chance) {
        if (has_special_skill && MyDino->road[ROAD_LENGTH - 2] != 'X') { // 判斷是否發動特殊技能
            MyDino->road[ROAD_LENGTH - 2] = '|'; // 發射激光
            return false; // 不放置障礙物
        }
        else {
            MyDino->road[ROAD_LENGTH - 1] = 'X';
            return true;
        }
    }
    return false;
}


int main()
{
    /* 初始化 */
    srand(time(NULL));
    Dino* MyDino = init();
    bool has_special_skill = true; // 設置玩家擁有特殊技能

    display(MyDino);

    /* 遊戲本體 */
    while (true)
    {
        /* 邏輯運算 */
        if (space_pressed() && MyDino->jump_time_left == 0 && has_special_skill) // 判斷是否擁有特殊技能
        {
            MyDino->road[ROAD_LENGTH - 2] = '|'; // 發射激光
        }
        else if (space_pressed() && MyDino->jump_time_left == 0) // 普通跳躍
        {
            MyDino->jump_time_left = 7;
        }
        move(MyDino);
        if (spawn_barrier(MyDino, has_special_skill))
        {
            MyDino->road[ROAD_LENGTH - 1] = 'X';
        }
        if (MyDino->jump_time_left > 0)
            MyDino->jump_time_left -= 1;
        if (is_bumped(MyDino))
        {
            display(MyDino);
            break;
        }

        /* 渲染呈現 */
        display(MyDino);
        // 觸發激光
        if (MyDino->road[ROAD_LENGTH - 2] == '|' && MyDino->road[ROAD_LENGTH - 3] == '_') {
            MyDino->road[ROAD_LENGTH - 2] = ' ';
        }
        MyDino->score++;
        Sleep(MyDino->wait_time);
    }
    return 0;
}
