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

回合製多人啤酒遊戲

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

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

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

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

這是一款多人遊戲

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

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

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

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

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

此外,玩家在每輪開始時的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]刪除
最新教學 更多>
  • 如何在 CSS 盒子上創建斜角?
    如何在 CSS 盒子上創建斜角?
    在 CSS 框上建立斜角可以使用多種方法在 CSS 框上實現斜角。一種方法描述如下:使用邊框的方法此技術依賴於沿容器左側建立透明邊框和沿底部建立傾斜邊框。以下程式碼示範如何實現:<div class="cornered"></div> <div cl...
    程式設計 發佈於2024-11-17
  • 如何在 Pandas DataFrame 中的字串中新增前導零?
    如何在 Pandas DataFrame 中的字串中新增前導零?
    在 Pandas Dataframe 中的字串中加入前導零在 Pandas 中,處理字串有時需要修改其格式。一項常見任務是向資料幀中的字串新增前導零。這在處理需要轉換為字串格式的數值資料(例如 ID 或日期)時特別有用。 要實現此目的,您可以利用 Pandas Series 的 str 屬性。此屬性...
    程式設計 發佈於2024-11-17
  • Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    程式設計 發佈於2024-11-17
  • 您是否應該異步加載腳本以提高網站效能?
    您是否應該異步加載腳本以提高網站效能?
    非同步腳本載入以提高網站效能在現今的Web 開發領域,優化頁面載入速度對於使用者體驗和搜尋引擎優化至關重要。提高效能的有效技術之一是非同步載入腳本,使瀏覽器能夠與其他頁面元素並行下載腳本。 傳統方法是將腳本標籤直接放置在 HTML 文件中,但這種方法常常會造成瓶頸因為瀏覽器必須等待每個腳本完成載入才...
    程式設計 發佈於2024-11-17
  • 如何將 Python 日期時間物件轉換為自紀元以來的毫秒數?
    如何將 Python 日期時間物件轉換為自紀元以來的毫秒數?
    在Python 中將日期時間物件轉換為自紀元以來的毫秒數Python 的datetime 物件提供了一種穩健的方式來表示日期和時間。但是,某些情況可能需要將 datetime 物件轉換為自 UNIX 紀元以來的毫秒數,表示自 1970 年 1 月 1 日協調世界時 (UTC) 午夜以來經過的毫秒數。...
    程式設計 發佈於2024-11-17
  • 如何在 Python 中使用特定前綴重命名目錄中的多個文件
    如何在 Python 中使用特定前綴重命名目錄中的多個文件
    使用Python重命名目錄中的多個檔案當面臨重命名目錄中檔案的任務時,Python提供了一個方便的解決方案。然而,處理錯綜複雜的文件重命名可能具有挑戰性,特別是在處理特定模式匹配時。 為了解決這個問題,讓我們考慮一個場景,我們需要從檔案名稱中刪除前綴“CHEESE_”,例如“CHEESE_CHEES...
    程式設計 發佈於2024-11-17
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-11-17
  • Java中的同步靜態方法如何處理執行緒同步?
    Java中的同步靜態方法如何處理執行緒同步?
    Java 中的同步靜態方法:解鎖物件類別困境Java 文件指出,在同一物件上多次呼叫同步方法不會交錯。但是,當涉及靜態方法時會發生什麼?靜態方法不與具體物件關聯,那麼synchronized關鍵字是指物件還是類別呢? 分解答案根據Java語言規範(8.4.3.6),同步方法在執行之前取得監視器。對於...
    程式設計 發佈於2024-11-16
  • 如何使用 Python 取得目錄中按建立日期排序的檔案清單?
    如何使用 Python 取得目錄中按建立日期排序的檔案清單?
    使用Python 獲取按創建日期排序的目錄列表使用Python 獲取按創建日期排序的目錄列表導航目錄時,經常需要獲取排序後的內容列表根據特定標準,例如建立日期。在Python中,這個任務可以輕鬆完成。 建議方法:import glob import os search_dir = "/my...
    程式設計 發佈於2024-11-16
  • 如何在初始頁面載入後動態載入 Less.js 規則?
    如何在初始頁面載入後動態載入 Less.js 規則?
    動態載入Less.js規則將Less.js合併到網站中可以增強其樣式功能。然而,遇到的一個限制是需要在 Less.js 腳本之前載入所有 LESS 樣式表。當某些樣式需要在初始頁面載入後動態載入時,這可能會帶來挑戰。 目前限制目前,Less.js 規定載入外部的順序樣式表和腳本起著至關重要的作用。顛...
    程式設計 發佈於2024-11-16
  • 如何在 PHP 中清除瀏覽器快取?
    如何在 PHP 中清除瀏覽器快取?
    在PHP 中清除瀏覽器快取您可能會遇到需要清除瀏覽器快取以強制瀏覽器重新載入最新版本的情況您的網頁。當您開發 Web 應用程式並且希望確保使用者看到您所做的最新變更時,這尤其有用。 清除瀏覽器快取的PHP 代碼要使用PHP清除瀏覽器緩存,可以使用以下程式碼:header("Cache-Co...
    程式設計 發佈於2024-11-16
  • 如何在 MySQL PDO 查詢中正確使用 LIKE 和 BindParam?
    如何在 MySQL PDO 查詢中正確使用 LIKE 和 BindParam?
    在MySQL PDO 查詢中正確使用LIKE 和BindParam當嘗試在MySQL PDO 查詢中使用BindParam 執行LIKE 搜尋時,必須使用正確的語法以確保準確的結果。 優化語法要使用bindParam匹配以“a”開頭的用戶名,正確的語法是:$term = "a%"...
    程式設計 發佈於2024-11-16
  • 如何使用 Selenium 和 Python 更改 Chrome 中的用戶代理程式?
    如何使用 Selenium 和 Python 更改 Chrome 中的用戶代理程式?
    使用Selenium 更改Chrome 中的用戶代理在自動化需要特定瀏覽器配置的任務時,更改Chrome 中的用戶代理至關重要。這可以透過使用 Selenium 和 Python 來實現。 若要啟用使用者代理開關,請修改選項設定:from selenium import webdriver from...
    程式設計 發佈於2024-11-16
  • .then(function(a){ return a; }) 是 Promises 的 No-Op 嗎?
    .then(function(a){ return a; }) 是 Promises 的 No-Op 嗎?
    .then(function(a){ return a; }) 是 Promises 的 No-Op 嗎? 在 Promise 領域,就出現了 .then(function(a){ return a; }) 是否為空操作的問題。讓我們闡明這個奇怪的查詢:是的,它通常是一個無操作。 相關程式碼接收前一...
    程式設計 發佈於2024-11-16
  • 如何在 Matplotlib 中建立自訂色彩圖並新增色標?
    如何在 Matplotlib 中建立自訂色彩圖並新增色標?
    建立自訂顏色圖並合併色標要建立自己的顏色圖,一種方法是利用 matplotlib.colors 模組中的 LinearSegmentedColormap 函數。這種方法更簡單,並產生連續的色標。 import numpy as np import matplotlib.pyplot as plt i...
    程式設計 發佈於2024-11-16

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

Copyright© 2022 湘ICP备2022001581号-3