# Catan_project_1112 此專案為 1112 學期的程式設計課程專案,主題為卡坦島(Catan)桌遊。 ## 組員名單 | 組員姓名 | 學號 | | :--------:| :----: | | 徐政皓 | 40947043S | | 陳柏瑜 | 41047054S | | 洪維駿 | 40923205L | --- ### 分工 - 徐政皓 - 程式架構設計 - 地圖設計 - SDL 介面設計 - 遊戲初始化 - 盜賊相關功能 - 陳柏瑜 - 交易相關功能 - 發展卡相關功能 - 洪維駿 - 建築相關功能 - 最長道路與最大軍隊判斷 - 一些發展卡功能 --- ## 安裝 由於此程式使用 SDL 作為顯示介面,因此在編譯之前您必須安裝 SDL2,若您的電腦使用的是 ubuntu,可以在終端機執行以下指令進行安裝: ```shell sudo apt-get install libsdl2-dev libsdl2-image-dev ``` --- ## 遊戲指南 此遊戲的運作模式使用 SDL 作為地圖顯示的介面,並使用終端機做為遊戲的操作介面,輸入各種資料以進行遊戲。 遊戲全程中,玩家將作為編號為 1 的玩家進行遊戲。而編號 2, 3, 4 的玩家為電腦玩家,其操作為電腦自動進行。 各玩家編號及其對應的顏色如下: | 玩家編號 | 顏色 | | :--------: | :----: | | 1 | <span style="color: red"> 紅色| | 2 | 白色 | | 3 | <span style="color: orange">橘色 | | 4 | <span style="color: blue">藍色 | --- ### 遊戲階段 #### 遊戲開始 遊戲開始後,程式會將卡坦島的地圖初始化,並隨機分配地形及數字給每個地圖點,並顯示地圖在 SDL 的視窗上。接著,程式會隨機選擇一位玩家作為起始玩家,並由起始玩家開始進行遊戲。 接下來,程式會依玩家的順序,讓玩家建造第一個村莊及道路,接著反著剛剛的順序,讓玩家再建造第二個村莊及道路,並拿取初始資源。當所有玩家都完成動作後,遊戲進入正式的遊戲階段。 --- #### 回合階段 遊戲正式開始後,程式會依玩家的順序,讓玩家進行回合。每個玩家的回合中,會執行以下動作(部分動作可選擇跳過): * **擲骰子(回合開始必須執行)** * 交易 * 建造 * 使用發展卡 * **結束回合** --- ##### 擲骰子 在擲骰子的階段,程式會隨機產生兩個 1 到 6 的數字,並將兩個數字相加,作為此回合的骰子點數。接著,依據骰子點數,分為兩種情況: 1. 骰子點數為 7 點: 1. 此時,所有玩家的資源卡數量若超過 7 張,則必須棄掉一半的資源卡。 2. 接著,程式會讓擲骰玩家選擇一個板塊,將苦力怕移動到該板塊。 3. 最後,程式會讓玩家選擇一個玩家,並將該玩家的一張資源卡隨機拿走。 2. 骰子點數為 2 ~ 12 點,並不為 7 點: * 此時,程式會將骰子點數與板塊上的數字進行比對,若有符合的板塊,且該板塊上沒有苦力怕,則會將該地圖點上的資源卡發給所有與該地圖點相連的玩家。 --- ##### 交易 在建築階段,玩家可以選擇與銀行或其他玩家交易,若交易成功,則會成功與所選擇對象交易,否則交易失敗。 1. 與玩家交易: - 當與其他玩家交易時,其他玩家有權利拒絕與您的交易,若其他玩家拒絕您的交易,則交易失敗 2. 與銀行交易: - 與銀行交易時,程式會另外判斷您是否擁有港口,若有則會切換成與港口交易,交易匯率會以您擁有之港口所訂定之匯率更動 - 港口交易分為兩種: 1. 對於任意資源皆以 2:1 交換 2. 對於特定資源以 3:1 交換 > 請注意,若您或交易對象其中一方所擁有資源不足,則交易直接失敗 --- ##### 建造 在建造階段,玩家可以選擇消耗資源建造道路、村莊以及城市三種建築,或購買隨機種類的發展卡。 四種行為的資源消耗如下: | 建築 | 磚頭 | 木頭 | 羊毛 | 小麥 | 礦石 | | :--------: | :----: | :----: | :----: | :----: | :----: | | 道路 | 1 | 1 | 0 | 0 | 0 | | 村莊 | 1 | 1 | 1 | 1 | 0 | | 城市 | 0 | 0 | 0 | 2 | 3 | | 發展卡 | 0 | 1 | 1 | 1 | 0 | --- ##### 使用發展卡 發展卡分別有下列 4 種: | 發展卡 | 效果 | | :--------: | :----: | | 騎士卡 | 移動盜賊、掠奪資源 | | 壟斷卡 | 掠奪所有人手上某種特定資源 | | 獲取資源卡 | 免費從銀行得到兩種資源 | | 分數卡 | 分數 + 1 | | 建造道路卡 | 免費建造兩條道路 | > 請注意,若為這回合買到的發展卡,則不能在該回合使用。 --- ### 額外功能 為增加遊戲的趣味性,我們在遊戲中加入了一些額外的功能,您可以透過執行時輸入"-h"來查看如何開啟它們。 --- #### 季節 遊戲中有四個季節,分別為春夏秋冬,每個季節都有不同的效果,會有相應事件機率發生。 | 季節 | 效果 | 事件 | 圖片 | | :--------: | :----: | :----: | :----: | | 春 | 小麥增加 | 地殼變動、龍捲風、海盜 | 小黃花 | | 夏 | 木頭增加 | 海盜、地殼變動 | 太陽 | | 秋 | 獲取資源卡變為3個 | 海盜、地殼變動 | 橘葉 | | 冬 | 盜賊周圍仍可以拿到資源 | 地殼變動 | 雪球 | * 海盜:關閉港口功能 * 龍捲風:摧毀房子/降級城市(一個點) * 地殼變動:礦石增加 執行時輸入"-s"即可開啟季節模式。 --- #### 自動對戰 由四個電腦玩家進行遊戲,無須使用者進行任何操作。 執行時輸入"-a"即可開啟自動對戰模式。 --- ### 遊戲結束 當有玩家的分數達到 **10** 分時,遊戲結束,並宣布該玩家獲勝。 --- ## 程式架構 ```c // main.c // seudo structure of the program, not the real code, including the function name and the parameters int main(){ // initialize the variables init_game(...); // initialize SDL init_SDL(...); // show the map render_map(...); // start the game while(game_is_not_end){ // check if any player has 10 VP check_winner(...); // start a round start_round(...); } // free the memory free_game(...); } ``` --- ### structure ```c // store the coordinate of a point typedef struct Point{ int x; int y; }point; // store the information of a player typedef struct Player{ int id; int VP; // victory point int resource[5]; // 0: brick, 1: lumber, 2: wool, 3: grain, 4: ore int number_of_knights; int length_of_road; int number_of_building[3]; // 0: settlement, 1: city, 2: road int number_of_dev_card; bool has_longest_road; bool has_most_knights; struct list_head *devcard_list; // list of devcard in player's hand }player; // store the information of a piece typedef struct Piece{ point p; // coordinate of the piece int eco_type; // 0: hill, 1: forest, 2: pasture, 3: field, 4: mountain, 5: desert int number; // the point number of the piece bool robberFlag; // true: robber is on the piece, false: robber is not on the piece }piece; // store the information of a land between pieces typedef struct LandBetween{ point p; // coordinate of the land between pieces int type; // type of port, or nothing special bool has_building; int owner; // owner of the building int building; // 0: settlement, 1: city }landbetween; // store the information of a road typedef struct Road{ point start; // coordinate of the start point (upper point) point end; // coordinate of the end point (lower point) int owner; // owner of the road int dir; // direction of the road, 0: left down, 1: right down, 2: down }road; // store the information of a development card typedef struct DevCard{ int type; // 0: knight, 1: monopoly, 2: road building, 3: year of plenty, 4: victory point bool used; struct list_head node; // node of the list }devcard; // store the information of the map typedef struct mapInfo{ player **players; piece **pieces; landbetween **lands; road **roads; struct list_head *devcards; }mapInfo; ``` --- ## 程式碼說明 ### 交易 `void trade_action( mapInfo *info, int32_t id );` > Trade action list. After selection, `trade_action` will call corresponding functions - Input - `info` : game information - `id` : player id who wants to trade - Output - No `void trade_with_bank( player *player_A, landbetween **maps );` > Trade with bank - Input - `player_A` : player who wants to trade - `maps` : game information - Output - No `void trade_with_player( player *candidate, player *player_A );` > Trade with player - Input - `player_A` : player who wants to trade - `candidate` : player that player_A wants to trade with - Output - No `int32_t trade_with_port( player *player_A, landbetween **maps, int32_t get_choice );` > Find the exchange rate `player_A` can trade with bank. - Input - `player_A` : player who wants to trade - `maps` : game information - `get_choice` : resource player_A wants to get - Return value - The exchange rate if `player_A` has certain port - If `player_A` has no port or related port, the return value is default to 4 ### 發展卡 `void dev_card_action( SDL_Renderer *renderer, mapInfo *info, int id );` > devcard action list. After selection, `dev_card_action` will call corresponding functions. - Input - `renderer` : map - `info` : game information - `id` : player id who wants to trade - Output - No `void monopoly_action( mapInfo *info, int id );` > Monopoly. Take away one certain resource from all the other player's hand. - Input - `id` : player id of player who wants to trade - `info` : game information - Output - No `int32_t year_of_plenty_action( mapInfo *info, int id );` > Year of plenty. Freely get 2 resource from the bank. - Input - `id` : player id of player who wants to trade - `info` : game information - Output - No `void dev_point_action( mapInfo *info, int id );` > Devcard point. Freely get one point. - Input - `id` : player id of player who wants to trade - `info` : game information - Output - No
{"metaMigratedAt":"2023-06-20T01:45:18.837Z","metaMigratedFrom":"Content","title":"Catan_project_1112","breaks":true,"contributors":"[{\"id\":\"7d92459b-1169-478f-9901-ec51abfd3346\",\"add\":7473,\"del\":0}]"}
    65 views