---
# System prepended metadata

title: Tetris第二週進度
tags: [程式設計 IV]

---

# Tetris第二週進度

## 課前
先將上禮拜製作的 Code 從 GitHub 上 Pull 下
可參考先前的講義內容

## 第二周功能
上個禮拜的進度到讓同學們能輸出不同俄羅斯方塊出來，以下是今天的內容
- define 長寬
    長20 寬10的板子
    ```c=
    #define CANVAS_WIDTH 10
    #define CANVAS_HEIGHT 20
    ```

- Block
    - 遊戲板
        這是每一個格子的結構，我們會將其用於二維陣列
        ```c=
        typedef struct {
            Color color;
            ShapeId shape;
            bool current;
        }Block;
        ```
    - 兩個Block函式
        - 為此位置設置block的屬性
        ```c
        void setBlock(Block* block, Color color, ShapeId shape, bool current)
        ```
        - 重設block的屬性
        ```c
        void resetBlock(Block* block)
        ```
    
- State
    遊戲的狀態(分數、座標位置、旋轉模式、掉落時間、QUEUE裡的方塊是?)
    ```c=
    typedef struct {
        int x;
        int y;
        int score;
        int rotate;
        int fallTime;
        ShapeId queue[4];
    }State;
    ```
    
- 將BLOCK輸出看看
    先不輸出空白，使大家能更看出這個空間感
    ![image](https://hackmd.io/_uploads/HJV7dkKM0.png)
    
## 課堂練習
想像遊戲即將開始那方塊要出現在哪
請完成如圖，利用雙for迴圈、State達到，放入一個 J

![image](https://hackmd.io/_uploads/SJILWeYzA.png)

## 參考
[\u3000](https://blog.csdn.net/lilongsy/article/details/78288697)

## 課堂CODE
```c=
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

#define CANVAS_WIDTH 10
#define CANVAS_HEIGHT 20

typedef enum {
    RED = 41,
    GREEN,
    YELLOW,
    BLUE,
    PURPLE,
    CYAN,
    WHITE,
    BLACK = 0,
}Color;

typedef enum {
    EMPTY = -1,
    I,
    J,
    L,
    O,
    S,
    T,
    Z
}ShapeId;

typedef struct {
    ShapeId shape;
    Color color;
    int size;
    char rotates[4][4][4];
}Shape;

typedef struct
{
    int x;
    int y;
    int score;
    int rotate;
    int fallTime;
    ShapeId queue[4];
}State;

typedef struct {
    Color color;
    ShapeId shape;
    bool current;
}Block;

Shape shapes[7] = {
    {
        .shape = I,
        .color = CYAN,
        .size = 4,
        .rotates =
        {
            {
                {0, 0, 0, 0},
                {1, 1, 1, 1},
                {0, 0, 0, 0},
                {0, 0, 0, 0}
            },
            {
                {0, 0, 1, 0},
                {0, 0, 1, 0},
                {0, 0, 1, 0},
                {0, 0, 1, 0}
            },
            {
                {0, 0, 0, 0},
                {0, 0, 0, 0},
                {1, 1, 1, 1},
                {0, 0, 0, 0}
            },
            {
                {0, 1, 0, 0},
                {0, 1, 0, 0},
                {0, 1, 0, 0},
                {0, 1, 0, 0}
            }
        }
    },
    {
        .shape = J,
        .color = BLUE,
        .size = 3,
        .rotates =
        {
            {
                {1, 0, 0},
                {1, 1, 1},
                {0, 0, 0}
            },
            {
                {0, 1, 1},
                {0, 1, 0},
                {0, 1, 0}
            },
            {
                {0, 0, 0},
                {1, 1, 1},
                {0, 0, 1}
            },
            {
                {0, 1, 0},
                {0, 1, 0},
                {1, 1, 0}
            }
        }
    },
    {
        .shape = L,
        .color = YELLOW,
        .size = 3,
        .rotates =
        {
            {
                {0, 0, 1},
                {1, 1, 1},
                {0, 0, 0}
            },
            {
                {0, 1, 0},
                {0, 1, 0},
                {0, 1, 1}
            },
            {
                {0, 0, 0},
                {1, 1, 1},
                {1, 0, 0}
            },
            {
                {1, 1, 0},
                {0, 1, 0},
                {0, 1, 0}
            }
        }
    },
    {
        .shape = O,
        .color = WHITE,
        .size = 2,
        .rotates =
        {
            {
                {1, 1},
                {1, 1}
            },
            {
                {1, 1},
                {1, 1}
            },
            {
                {1, 1},
                {1, 1}
            },
            {
                {1, 1},
                {1, 1}
            }
        }
    },
    {
        .shape = S,
        .color = GREEN,
        .size = 3,
        .rotates =
        {
            {
                {0, 1, 1},
                {1, 1, 0},
                {0, 0, 0}
            },
            {
                {0, 1, 0},
                {0, 1, 1},
                {0, 0, 1}
            },
            {
                {0, 0, 0},
                {0, 1, 1},
                {1, 1, 0}
            },
            {
                {1, 0, 0},
                {1, 1, 0},
                {0, 1, 0}
            }
        }
    },
    {
        .shape = T,
        .color = PURPLE,
        .size = 3,
        .rotates =
        {
            {
                {0, 1, 0},
                {1, 1, 1},
                {0, 0, 0}
            },

                {{0, 1, 0},
                {0, 1, 1},
                {0, 1, 0}
            },
            {
                {0, 0, 0},
                {1, 1, 1},
                {0, 1, 0}
            },
            {
                {0, 1, 0},
                {1, 1, 0},
                {0, 1, 0}
            }
        }
    },
    {
        .shape = Z,
        .color = RED,
        .size = 3,
        .rotates =
        {
            {
                {1, 1, 0},
                {0, 1, 1},
                {0, 0, 0}
            },
            {
                {0, 0, 1},
                {0, 1, 1},
                {0, 1, 0}
            },
            {
                {0, 0, 0},
                {1, 1, 0},
                {0, 1, 1}
            },
            {
                {0, 1, 0},
                {1, 1, 0},
                {1, 0, 0}
            }
        }
    },
};

void setBlock(Block* block, Color color, ShapeId shape, bool current)
{
    block->color = color;
    block->shape = shape;
    block->current = current;
}

void resetBlock(Block* block)
{
    block->color = BLACK;
    block->shape = EMPTY;
    block->current = false;
}

int main() {
    srand(time(NULL));
    State state = {
        .x = CANVAS_WIDTH / 2,
        .y = 0,
        .score = 0,
        .rotate = 0,
        .fallTime = 0
    };

    Block canvas[CANVAS_HEIGHT][CANVAS_WIDTH];
    for (int i = 0; i < CANVAS_HEIGHT; i++) {
        for (int j = 0; j < CANVAS_WIDTH; j++) {
            resetBlock(&canvas[i][j]);
        }
    }

    Shape shapeData = shapes[1];

    for (int i = 0; i < shapeData.size; i++) {
        for (int j = 0; j < shapeData.size; j++) {
            if (shapeData.rotates[0][i][j]) {
                setBlock(&canvas[state.y + i][state.x + j], shapeData.color, J, true);
            }
        }
    }
    
    //將光標移動到第一行第一列
    printf("\033[0;0H\n");
    for (int i = 0; i < CANVAS_HEIGHT; i++) {
        printf("|");
        for (int j = 0; j < CANVAS_WIDTH; j++) {
            printf("\033[%dm\u3000", canvas[i][j].color);
        }
        printf("\033[0m");
        printf("|\n");
    }
    //printf("\e[?25l"); // hide cursor

    return 0;
}
``` 