你是本質迷嗎?還是認同棒球隊本來就是附屬的?
在前兩篇的文章中,我們透過簡單的 Swift
語法特性,來實作了一些基本規則。
接下來,我們將目光移回到球場上的主角(?),進一步探討球員在場上的動作,以及如何設計球員的多重狀態。
如果你還沒看過前兩篇,可以先看看:
上週文章發佈後,還是遭受了一點點爬蟲機器人的留言洗版,希望這週不會再遇到,也期待方格子官方能快點處理好。
本篇文章著重於規則及邏輯的部分,若想要做棒球遊戲的設計,需要再考慮更多因素,不適合直接套用。
狀態拆分
我們都知道,同一個球員在場上會有不同的身份,像是投手、打者、跑者、守備球員等,可以執行不同的動作。
如果我們簡單的把球員的行為動作定義如下:
這樣看似沒問題,但是當程式在執行的時候,我們會發現球員在場上可以執行任何動作,這樣的設計會讓球員的行為變得非常混亂。
像是投手可以打擊、捕手可以跑壘,這樣的設計明顯違反了棒球規則。因此,我們需要將球員的行為動作拆分成不同的狀態,並且讓球員在場上只能執行符合其狀態的動作。為了讓球員能在場上切換不同身份,我們預先為每種狀態建立獨立結構,避免角色混淆,也能確保只有符合條件的球員能執行該狀態的動作。
投手:投球動作
首先我們先來設計投手狀態的行為,先不談球投出去之後的結果(打擊、捕逸、暴投、投手犯規),只談投手出手的動作就好:
我們先用 PitchType
來表示投手的球種,再用 StrikeZonePosition
來表示投手投球的目標位置。
接著把球種跟位置放到 pitch
function 中,然後簡單把投球結果 print
出來,大概會是像
打者/跑者:擊球與跑壘
接下來輪到擊球和跑壘,打者可以擊出不同的球種,並且朝向不同的方向,我們可以先這樣定義:
打者的部分,我們先定義了擊球的形態和方向,並放入 hit
function 中,再把結果 print
出來;而跑者的部分,我們透過 Base
定義了各個壘包,並實作了各種進/退壘的動作,再把結果 print
出來。
這樣子使用方式就會像:
守備:接球與傳球
守備的部分,我們在第一篇已經先用 FieldPosition
定義了守備位置,就不再重複定義。
我們簡單實作一個 DefenderState
來表示守備球員的狀態,並放入 catchBall
和 throwTo
兩個簡單的 function ,再把結果 print
出來。
多重狀態的切換
在實際比賽中,球員可能同時具備多重狀態:
- 擔任打者準備打擊
- 上壘後變成跑者
- 防守時成為野手或捕手等角色
我們將這些狀態獨立成四種 State,並在 Player 中透過 PlayerState
來表示球員的當前狀態,利用 enum
的特性,讓球員在場上可以自由切換不同的狀態。
透過這樣的設計,在實際使用的時候,我們可以這樣:
本篇文章我們透過不同的狀態,設計了球員在場上的不同動作行為,並且透過不同狀態間的切換,來避免程式在執行時呼叫錯誤的狀態。
因此便不會出現像是,在投手丘上做出打擊動作,或是捕手蹲著在跑壘的狀況。
還有哪些球場上的狀態或動作你想要了解嗎?留言告訴我!
如果覺得這篇文章對你有幫助,也歡迎分享給更多人知道,或者還有想了解的 Swift
技巧,也歡迎留言告訴我!我們下次再見囉!!!
本篇文章程式碼部分由 AI
輔助產生。