---
# System prepended metadata

title: 風聲-Message 功能牌說明

---

# 風聲規則整理：

## 出牌階段 (1)
- 可以出的牌：【試探】、【鎖定】、【真偽莫辨】、【燒毀】、【博弈】

## 情報傳遞階段
- 可以出的牌：一張手牌作為情報牌、無法傳出則視為輸掉遊戲
- 傳遞方式：密電 / 直達 /文本

### 情報傳遞
- 宣告情報傳遞、確認方式後傳遞
- 所有玩家可使用：【調虎離山】、【截獲】、【鎖定】
- 所有玩家不可使用：【破譯】、【轉移】

### 情報到達
- 情報傳遞到另一位玩家時
- 所有玩家可使用：【破譯】、【轉移】
- 所有玩家不可使用：【調虎離山】、【截獲】、【鎖定】

### 情報接收
- 玩家決定是否接收情報
- 所有玩家可使用： Ｘ


-----
## 功能牌部分

### 【鎖定】
- 使用階段：出牌階段、情報傳遞階段
- 指定一名玩家、必須接收本回合傳遞給他的情報
- 如多人被鎖定、按照「傳遞順序」進行結算
- 如被鎖定的玩家在情報傳遞中死亡、則無視該玩家繼續傳遞

### 【博弈】（目前階段不做）
- 使用階段：出牌階段
- 指定一名玩家，將牌庫頂的一張牌作為情報放置在該玩家面前
- 若使用博弈導致玩家死亡、則視為「親手」殺掉對方
- 牌庫沒有牌時不可使用博弈


### 【調包】（目前階段不做）
- 使用階段：情報傳遞階段
- 將此牌與傳遞情報替換、以公開方式顯示
- 若無人接收情報、導致情報返回自身時也可使用


### 【截獲】
- 使用階段：他人傳遞情報時
- 將一張傳遞中的情報傳遞至自己面前
- 可以把情報先【截獲】後【轉移】給其他人
- 【截獲】不受【鎖定】影響
- 【截獲】受到【調虎離山】影響

### 【破譯】
- 使用階段：情報傳遞到自身面前時
- 宣言一個顏色(黑 / 藍 / 紅)、檢視該情報、如符合宣言的顏色可公開情報後抽一張
- 雙色情報只要一個符合就可公開
- 可以不公開情報、但相對無法抽排

### 【燒毀】
- 燒毀一張黑情報
- 任何時機都可以使用
- 一旦角色死亡(持有三張黑情報)就不可對其使用燒毀

### 【試探】
- 使用階段：出牌階段
- 只有被試探玩家可以看牌，根據牌面與對應身份執行動作
- 使用後此牌「除外」遊戲
- 潛伏 / 軍情 / 醬油 : 棄牌 / 抽牌 / 回答[我是一個好人]
- 每張牌的效果不同

### 【轉移】
- 使用階段：情報轉移到自身時
- 將情報傳遞給另一位玩家、該玩家「必須」接收情報
- 其他人可以使用【截獲】搶奪情報
- 情報被【轉移】後、需要先詢問其他玩家是否使用功能牌、如不使用則進行結算

### 【識破】
- 使用階段：任何時間
- 使目前使用中的卡牌無效
- 13 張功能牌全部都可以被【識破】
- 被【識破】的牌需放置到棄牌堆
- 情報傳遞與傳遞方式不能被【識破】

### 【真偽莫辨】
- 使用階段：自身出牌階段
- 從牌庫頂拿取等同現存玩家數量的牌、洗牌後從自己開始逆時針抽一張牌作為情報
- 若過程有人達成勝利條件、則立即終止行動後宣告勝利
- 被【識破】時整個卡牌均視為無效、而非某位玩家
- 如有玩家因此死亡、視為使用者「親手」殺死

### 【調虎離山】
- 使用階段：情報傳遞階段
- 除去「情報傳出者」與「被鎖定者」以外、指定一位玩家在本次傳遞中不能接收傳到自己面前的情報
- 受到【調虎離山】與【鎖定】時、【鎖定】的判斷高於【調虎離山】
- 【調虎離山】可在別人回合使用
- 「直達」情報也可使用【調虎離山】、讓該玩家無法接收直接退回
- 被【調虎離山】者可以根據其他效果(Ex.【轉移】)來獲得情報

### 【權衡】（目前階段不做）
- 使用階段：自己出牌階段
- 捨棄全部手牌、重新抽取數量相等的牌
- 如【權衡】時被其他玩家改變手牌數量、則以改變後的數量為主(目前不影響)

### 【增援】（目前階段不做）
- 使用階段：自己出牌階段
- 每持有一張黑情報、就抽黑情報數量+1的牌

### 【公開文檔】（目前階段不做）
- 使用階段：情報傳遞階段
- 只能作為情報使用
- 作為情報傳遞時、接收情報的玩家須根據牌面敘述與對應身份進行對應動作
- 動作：抽一張牌



# 功能拆分

## 前端
### 功能呈現
【UI】 遊戲結算畫面 
【UI】 情報接收畫面
【UI】 功能牌交互畫面

### 物件呈現
【UI】 功能牌 - 鎖定
【UI】 功能牌 - 截獲
【UI】 功能牌 - 轉移
【UI】 功能牌 - 燒毀
【UI】 功能牌 - 破譯
【UI】 功能牌 - 識破
【UI】 功能牌 - 真偽莫辨
【UI】 功能牌 - 調虎離山

## 後端
### 流程相關
【Backend】「遊戲開始」功能
【Backend】「陣營分配」功能
【Backend】「手牌獲取」功能
【Backend】「回合跳過」功能
【Backend】「情報傳遞」功能
【Backend】「情報接收」功能
【Backend】「情報移除」功能
【Backend】「死亡判斷」功能
【Backend】「資訊公開」功能 （玩家死亡時使用）
【Backend】「獲勝判斷」功能
【Backend】「遊戲結束」功能

### 玩家相關
【Backend】 功能牌 - 鎖定
【Backend】 功能牌 - 截獲
【Backend】 功能牌 - 轉移
【Backend】 功能牌 - 燒毀
【Backend】 功能牌 - 破譯
【Backend】 功能牌 - 識破
【Backend】 功能牌 - 真偽莫辨
【Backend】 功能牌 - 調虎離山
【Backend】 情報牌 - 密電
【Backend】 情報牌 - 直達
【Backend】 情報牌 - 文本


## 其他






### HackMD 說明描述

#### 風聲版本

#### 風聲版本
# The-Message
風聲-黑名單

## Intro your game
「風聲」桌遊改編自同名電影，屬於陣營對抗類的桌遊。
在遊戲中玩家會被分配到「軍情」「潛伏」或是「醬油」的陣營
玩家必須利用手上的各種功能牌，讓自己或是隊友獲得屬於自己陣營的情報
同時也要防止其他陣營獲得他們情報，以及避免自己獲得黑情報而死亡

## Tech Stack
* 前端：React
* 後端：Golang
* ORM: 
* DB：MySQL
* DevOps：Github
* CI: Github Action
* CD: Zeabur

## Practice Stack
- Scrum
- Event Storming
- Example mapping
- OOA
- Walking skeleton
- MVC 架構
  

## Env Set
### Step to Run in Frontend
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
   parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: ['./tsconfig.json', './tsconfig.node.json'],
    tsconfigRootDir: __dirname,
   },
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list


### Step to Run in Backend

1. 進入 Backend 資料夾
```bash
cd Backend
```

2. docker 建置出 MySQL 環境
```bash
docker-compose up -d
```

3. 進行 DB 資料表清空與重新建置
```bash
go run ./cmd/migrate/fresh.go
```

4. 進行 DB Migration
```bash
go run ./cmd/migrate/migrate.go
```

5. 開啟 Go Web Server
```bash
go run cmd/app/main.go
```

6. 進行第一個 Request 呼叫

 - 有兩種方式可以進行 Request 呼叫，如以下所示：

   1. 將 `The-Message.postman_collection.json` 檔匯入至 Postman 中，並執行 Collection 當中的 API。

   2. 撰寫一個 HTTP Method 為 POST 的 Request，路徑為 `localhost:8080/api/v1/games`，並帶入以下玩家 JSON 資料。
  ```json
  {
      "players": [{
        "id": "6497f6f226b40d440b9a90cc",
        "name": "A"
    }, {
        "id": "6498112b26b40d440b9a90ce",
        "name": "B"
    }, {
        "id": "6499df157fed0c21a4fd0425",
        "name": "C"
    }]
  }
  ```
  
  ## Class Diagram

```mermaid
---
title: The Message
---

classDiagram
    Game "1" o-- "1..*" Player
    Game "1" o-- "1" Deck
    Deck "1" o-- "1" TeamCard
    Deck "1" o-- "1" MissionCard
    Player "1" o-- "1..*" MissionCard
    Player "1" o-- "1" TeamCard
    Game ..> Judiciary
    class Game{
      - status : boolean
      - round : int
      + gameInit() : void
      + turnStart() : void
    }
    class Player{
      - cardOnDesk : MissionCard[]
      - isVictory : boolean
      - isDead : boolean
      + drawMissionCard() : MissionCard[]
      + showMessageCard(card : MissionCard|null) : MissionCard|null
      + showIntelligneceCard() : MissionCard
      + getMissionCard(card : MissionCard) : boolean
    }
    class Deck{
      + shuffle() : Deck
    }
    class TeamCard{
      - team : char
    }
    class MissionCard{
      - Intelligence : char
      - color : char
      - message : char
    }
    class Judiciary{
      - rule : char[]
      + getCardWeight(firstCard : MissionCard, secondCard : MissionCard) : MissionCard[]
      + getCanShowCard(heads : MissionCard[]) : MissionCard[]
    }
```


Golang 第一次建立都會連線不到MysQL
標記 issue 會把它關閉