加入更多遊戲的實作,改用虛擬碼 (pseudo code) 撰寫,方便閱讀理解
系列文結束前應該會試著把遊戲內的機制實作出來,實作還是最重要的部份。
更新:
TODO:
翻面(i): return i==0 ? 1 : 0
玩家ID列表 = [p1uid, p2uid]
先手玩家序號 = 隨機整數(0,1) //決定先後手
先手玩家ID = 玩家ID列表[先手玩家序號]
後手玩家ID = 玩家ID列表[翻面(先手玩家序號 )]
玩家先後ID列表 = [先手玩家ID,後手玩家ID]
玩家行動序列 = 環形序列(玩家先後ID列表) //將列表轉換成環形序列
玩家物件列表 = [玩家(玩家先後ID列表[0]), 玩家(玩家先後ID列表[1])] //初始化玩家物件
玩家.牌庫 = 牌組(API.取得牌組(deck_id))
玩家.職業 = 職業(API.取得牌組職業(deck_id))
玩家.血量 = 25
玩家.護甲 = 0
玩家.手牌 = 牌堆()
玩家.水晶 = 0
玩家.水晶槽容量 = 0
玩家.生物表 = 生物表()
玩家.祕密 = 祕密表() //聖騎士, 獵人, 法師 才有
//TODO 玩家view物件,跟玩家資料綁定
三張牌 = 玩家物件列表[0].抽牌(3)
事件通知(0, 先手開場棄牌事件, 三張牌)
啟動事件迴圈(0, 先手選擇開場棄牌) //棄牌會放回牌庫重洗,雙方玩家完成棄牌後,正式開始回合
四張牌 = 玩家物件列表[1].抽牌(4)
事件通知(1, 後手開場棄牌事件, 四張牌)
啟動事件迴圈(1, 後手選擇開場棄牌) //棄牌會放回牌庫重洗,雙方玩家完成棄牌後,正式開始回合
事件通知(1, 配送幸運幣事件) //後手額外的效果
回合序號 = 0
目前玩家序號 = 回合序號 % 2
等待玩家序號 = 翻面(回合序號)
目前玩家ID = 玩家行動序列.起始()
等待玩家ID = 玩家先後ID列表[翻面(回合序號 % 2)]
玩家回合(目前玩家序號):
事件通知(目前玩家序號, 玩家行動事件)//啟動玩家的事件迴圈
更新狀態_回合開始前(目前玩家序號)
啟動事件迴圈(目前玩家序號, 玩家行動) //主控端接收玩家行動
事件通知(等待玩家序號, 玩家等待事件) //啟動玩家的事件迴圈
啟動事件迴圈(等待玩家序號, 玩家等待) //主控端不處理指令,保持佇列淨空
//接收到結束指令 or 強制結束時
目前玩家序號,等待玩家序號 = 等待玩家序號, 目前玩家序號
回合序號++
玩家 = 玩家物件列表[目前玩家序號]
if len(玩家.牌庫) > 0:
一張牌 = 玩家.抽牌(1) //沒牌會創造疲勞卡,逐次上升
事件通知(目前玩家序號, 抽牌事件, 一張牌)
else:
玩家.疲勞值 = 1 if 玩家.疲勞值 is None else 玩家.疲勞值+1
事件通知(目前玩家序號, 疲勞事件, 玩家.疲勞值)
//狀態更新(目前玩家序號, "玩家血量", 玩家.HP - 玩家.疲勞值)
if 玩家.水晶槽容量 < 10:
事件通知(目前玩家序號, 增加水晶槽容量, 1)
玩家.水晶槽容量++
//狀態更新(目前玩家序號, "水晶槽容量", 玩家.水晶槽容量)
//補滿水晶槽
狀態更新(目前玩家序號, "水晶", 玩家.水晶槽容量)
//遊戲內新增加的水晶會呈現比較亮的光澤,有空再實作
//手牌可使用
for 牌 in 玩家.手牌堆:
if 牌.cost <= 玩家.水晶:
牌.可使用 = true //同時 view 那邊會同步更新成綠框 react
else:
牌.可使用 = false
//生物可行動
for 生物 in 玩家.生物列表:
生物.可攻擊 = true
//TODO: 凍結狀態會阻止這個事件
//英雄能力可用
玩家.英雄能力.可使用 = true
//玩家回合結束事件的處理常式
玩家 = 玩家物件列表[目前玩家序號]
//關閉UI可用性
for 牌 in 玩家.手牌堆:
牌.可使用 = false
for 生物 in 晚家.生物列表:
生物.可攻擊 = false
玩家.英雄能力.可使用 = flase
//玩家操作事件後的處理常式
//TODO
回合開始的事件處理常式:
啟動玩家事件迴圈()
//直到玩家按下結束 or 超過90秒主控端強制結束
事件通知(0, 先手開場棄牌事件, 三張牌)
有的事件會包含參數,代表會造成遊戲狀態的改變
。
主控端初始化,玩家初始化。H0, P0. host.init(), player.init()玩家無法得知牌庫內容,僅包含基本場面訊息
主控端開始遊戲後,產生第一個變化,告知行動玩家更新內容 H0>H1, host.publish(act_id, delta1,H1)等待玩家能看到牌背
玩家接收更新內容,回覆更新後的 hash值 作為驗證 P0>P1, player.ack(hash(P1))
玩家送出「行動指令」 player.commit(action_cmd)
4-1. 主控端判定合法,廣播更新遊戲內容 H1>H2, host.publish(act_id, delta2,H2)
4-2. 主控端判定不合法,回絕行動玩家的指令 host.reject(act_id, action_cmd)
簡短版: