」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 回合製多人啤酒遊戲

回合製多人啤酒遊戲

發佈於2024-11-16
瀏覽:229

由於我需要在不久的將來組織一個系統思維研討會,所以我需要一個啤酒遊戲來開始它。

啤酒遊戲本身由四個角色組成:零售商、批發商、經銷商和工廠。透過物流的時滯性質來理解系統視角,可以更好地理解系統邊界。

由於這是一個幾個小時的研討會,我希望這款啤酒遊戲能夠實現以下功能。

這是一款多人遊戲

啤酒遊戲本身會有很多參與者在供應鏈中扮演不同的角色,但我希望能夠讓多個供應鏈同時競爭,看看誰得分更高。這樣,我們就可以同時了解他們的系統策略。

遊戲主機應該能夠看到每個人的狀態

由於有多隊同時參賽,身為主持人我需要能夠看到每支隊伍目前的進展和得分情況。

遊戲流程必須簡單且易於控制節奏

正如我一開始所說的,這是一個簡短的研討會,所以我需要讓每個人快速上手,並且我需要能夠控制每一輪的細節。

此外,玩家在每輪開始時的UI中都會出現一個計時器,透過倒數計時來推進遊戲節奏。

可以自訂人物.

經典的啤酒遊戲由四個角色組成,但角色越多,遊戲時間就越長。所以我想調整一下遊戲節奏,最好是三個角色。

經過一番查找,發現無論是開源專案或是已經上線的專案都無法完美滿足這些需求。所以,我最好自己做一個。

啤酒遊戲項目

https://github.com/wirelessr/beer_game

Turn Based Multiplayer Beer Game
主機使用者介面

Turn Based Multiplayer Beer Game
播放器使用者介面

整個專案是業務驅動開發和測試,覆蓋率超過90%,請放心使用。

準備工作

在專案資料夾中建立一個機密文件。您應該看到我將其複製到 Dockerfile 中。

.streamlit/secrets.toml

[mongo]
uri = ""

[admin]
key = ""

[player]
key = ""

由於該項目使用MongoDB,因此您必須在連結中填寫您的帳戶密碼。另外,admin.key和player.key對應UI上的關鍵欄位。

畢竟我是將應用程式上傳到公有雲,所以我仍然需要一個基本的身份驗證機制。如果您僅在本地運行並且覺得身份驗證很麻煩,您可以刪除相應的原始程式碼。

安裝與使用

該專案附加了Dockerfile,因此可以直接使用docker運行。

docker build -t beer_game .
docker run --rm --name beer -p 8501:8501 beer_game

對於開發,除了requiremnts.txt之外,還應該安裝運行單元測試的requirements-test.txt。然後你可以透過Makefile來執行所有的單元測試。

pip install -r requiremnts.txt
pip install -r requirements-test.txt
make test

遊戲流程

整個遊戲分為主持人模式和參與者模式,分別對應UI右上角的選項。

主持人創作遊戲時先分配一個game_id,所有參與者都要用這個id填入player_game。

同一供應鏈上的所有玩家需要使用相同的player_id,因此這個id也稱為供應鏈ID,具有相同player_id的參與者透過player_role進行角色劃分。

當參加者加入時,您可以在主持人畫面上看到與會者的狀態。
Turn Based Multiplayer Beer Game

讓我們從主持人的角度看完整的迭代會是什麼樣子。

Turn Based Multiplayer Beer Game

所有需要操作的元件都在這張圖中,每回合按刷新按鈕開始,按下週結束。

至於本輪向所有供應鏈發送多少訂單,將由下單觸發。

值得一提的是,下單本身是冪等的,所以改變數字再按一次就可以了,會使用最後一個數字。每個參與者介面的下單也將是冪等的。

主人下單後,店舖玩家即可接單。

Turn Based Multiplayer Beer Game

同樣,供應鏈中的每個角色都以「刷新」開始,以「下訂單」結束,商店玩家採取行動,然後零售商玩家採取行動,依此類推。

最後回到主持人,再次按下「刷新」即可查看本輪所有狀態,按「下週」即可結束本輪比賽。

遊戲詳情

刷新期間實際完成了幾件事。

  1. 它根據四個星期前的訂單從下游補充庫存。
  2. 它接收來自上游的訂單。
  3. 根據可銷售的庫存決定銷售量。

由於 Place Order 是冪等的,因此 Refresh 本身也是冪等的。

未來的工作

現在基本上滿足了我所有的需求,但還有一些改進的地方。

例如,雖然主持人可以看到所有參與者的狀態,但如果有一個圖表來顯示庫存和成本資訊隨時間的變化,這將有助於遊戲結束後回顧比賽.

還有一個更基本的問題:目前的UI根本沒有測試覆蓋率,主要是因為目前的遊戲流程相當簡單。只需在 UI 上點擊幾下即可涵蓋所有 UI 流程,因此我不太依賴自動測試。不過如果有UI修改的話,還是會有點繁瑣,所以最好還是有一個UI單元測試。

總的來說,這些需求是優化,但缺少它們並不影響功能。

如果您有其他想法,您也可以提交 Pull Request,歡迎貢獻。

版本聲明 本文轉載於:https://dev.to/lazypro/turn-based-multiplayer-beer-game-3n5k?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • C++20 Consteval函數中模板參數能否依賴於函數參數?
    C++20 Consteval函數中模板參數能否依賴於函數參數?
    [ consteval函數和模板參數依賴於函數參數在C 17中,模板參數不能依賴一個函數參數,因為編譯器仍然需要對非contexexpr futcoriations contim at contexpr function進行評估。 compile time。 C 20引入恆定函數,必須在編譯時進...
    程式設計 發佈於2025-07-15
  • Python中何時用"try"而非"if"檢測變量值?
    Python中何時用"try"而非"if"檢測變量值?
    使用“ try“ vs.” if”來測試python 在python中的變量值,在某些情況下,您可能需要在處理之前檢查變量是否具有值。在使用“如果”或“ try”構建體之間決定。 “ if” constructs result = function() 如果結果: 對於結果: ...
    程式設計 發佈於2025-07-15
  • eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    eval()vs. ast.literal_eval():對於用戶輸入,哪個Python函數更安全?
    稱量()和ast.literal_eval()中的Python Security 在使用用戶輸入時,必須優先確保安全性。強大的Python功能Eval()通常是作為潛在解決方案而出現的,但擔心其潛在風險。 This article delves into the differences betwee...
    程式設計 發佈於2025-07-15
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-07-15
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示Achieving Text-Only Extraction with Python's MLStripperTo streamline the stripping process, the Python standard librar...
    程式設計 發佈於2025-07-15
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-07-15
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-07-15
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在銀光應用程序中,嘗試使用LINQ建立錯誤的數據庫連接的嘗試,無法找到以查詢模式的實現。 ”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例中,tblpersoon可能...
    程式設計 發佈於2025-07-15
  • 如何使用PHP從XML文件中有效地檢索屬性值?
    如何使用PHP從XML文件中有效地檢索屬性值?
    從php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    程式設計 發佈於2025-07-15
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-07-15
  • 在PHP中如何高效檢測空數組?
    在PHP中如何高效檢測空數組?
    在PHP 中檢查一個空數組可以通過各種方法在PHP中確定一個空數組。如果需要驗證任何數組元素的存在,則PHP的鬆散鍵入允許對數組本身進行直接評估:一種更嚴格的方法涉及使用count()函數: if(count(count($ playerList)=== 0){ //列表為空。 } 對...
    程式設計 發佈於2025-07-15
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    在使用GO MOD時,在GO MOD 中克服模塊路徑差異時,可能會遇到衝突,其中可能會遇到一個衝突,其中3派對軟件包將另一個帶有導入套件的path package the Imptioned package the Imptioned package the Imported tocted pac...
    程式設計 發佈於2025-07-15
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, attributeError:SomeClass實...
    程式設計 發佈於2025-07-15
  • Go語言垃圾回收如何處理切片內存?
    Go語言垃圾回收如何處理切片內存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片時,了解垃圾收集行為至關重要,以避免潛在的內存洩...
    程式設計 發佈於2025-07-15
  • 如何在無序集合中為元組實現通用哈希功能?
    如何在無序集合中為元組實現通用哈希功能?
    在未訂購的集合中的元素要糾正此問題,一種方法是手動為特定元組類型定義哈希函數,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    程式設計 發佈於2025-07-15

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3