iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0

Current Sprint: 2. 實作遊戲開始
repo: https://github.com/side-project-at-SPT/ithome-ironman-2024-san-juan
swagger docs: https://side-project-at-spt.github.io/ithome-ironman-2024-san-juan/

前情提要

  • 新增了遊戲的新欄位: seed, version, game_data, result
  • 建立遊戲時產生 seed

TODO

  1. 產生並儲存 random seed
  2. 洗勻價格卡
  3. 抽出玩家人數的染坊卡片,發給每位玩家,作為起始建築
  4. 洗勻剩餘卡牌成為牌庫(抽牌堆)
  5. 玩家依序從牌庫抽取四張卡片,作為手牌
  6. 決定起始玩家

價格卡

trade

ref: #183 聖胡安 SAN JUAN 桌遊教學影片|勃根地桌遊

  1. 將五種價格定義下來
# app/models/trading_house.rb

class TradingHouse
# ...
  
  BASE_PRICES = [
    [ 1, 1, 1, 2, 2 ],
    [ 1, 1, 2, 2, 2 ],
    [ 1, 1, 2, 2, 3 ],
    [ 1, 2, 2, 2, 3 ],
    [ 1, 2, 2, 3, 3 ]
  ].each_with_object({}).with_index { |(prices, hash), index|
    hash[index] = prices
  }.freeze

# ...
end
  1. 按照 seed shuffle 後存到 game_data
# app/models/trading_house.rb

class TradingHouse
# ...
  
  def initialize(seed: nil)
    raise ArgumentError, "seed must provided" unless seed

    # assume seed is hex
    srand(seed.to_i(16))
    @order = [ 0, 1, 2, 3, 4 ].shuffle
  end

# ...
end

srand() 不提供引數時,會回傳一個 seed number
而當 srand(n) 時,會以 n 為種子取用隨機數
如此給予相同的 n,即能確保隨機方法(例如 shuffle, rand)的結果可控

因此在產生價格卡順序時,使用固定的 game.seed 來 shuffle,讓遊戲狀態可以重現

  1. 抽出下一張價格卡
# app/models/trading_house.rb

class TradingHouse
# ...
  
  def draw_next_trading_house_tile
    el = @order.shift
    @order.push(el)
    self
  end

# ...
end
  1. 取得目前價格
# app/models/trading_house.rb

class TradingHouse
# ...

  def current_price = BASE_PRICES[@order.first]

  def indigo_price = current_price[0]
  def sugar_price = current_price[1]
  def tobacco_price = current_price[2]
  def coffee_price = current_price[3]
  def silver_price = current_price[4]

# ...
end
  1. 我們也需要透過 價格卡順序(serialize data),產生 TradingHouse 物件,方便操作
# app/models/trading_house.rb

class TradingHouse
# ...

  def initialize(params = nil)
    case params
    in Array
      @order = params
    else
      raise ArgumentError, "order or seed must be provided"
    end
  end

# ...
end
  1. 把「洗勻價格卡」這個動作加進建立遊戲流程

宣告一個類別方法負責處理 start new game

  1. generate a random seed 產生種子
  2. shuffle the 5 trading house tiles 洗勻價格卡
  3. deal indigo plant to players as initial building 抽出玩家人數的染坊卡片,發給每位玩家,作為起始建築
  4. shuffle remaining cards to form a deck 洗勻剩餘卡牌成為牌庫(抽牌堆)
  5. deal 4 cards to each player as their initial hand, hidden from other players 發給每位玩家四張卡片,作為手牌
  6. choose first player 決定起始玩家
# app/models/game.rb

class Game < ApplicationRecord
# ...
  
  class << self
    def start_new_game
      game = new(status: :playing)
      # 1. generate a random seed
      game.seed = SecureRandom.hex(16)

      # 2. shuffle the 5 trading house tiles
      game.game_data[:trading_house_order] = TradingHouse.new(seed: game.seed).order

      # 3. deal indigo plant to players as initial building
      # 4. shuffle remaining cards to form a deck
      # 5. deal 4 cards to each player as their initial hand, hidden from other players
      # 6. choose first player
      game.save

      game
    end
  end

# ...
end
  1. 再來修改 GamesController
# app/controllers/api/v1/games_controller.rb

class Api::V1::GamesController < ApplicationController
# ...
  
  def create
    @game = Game.start_new_game

    render json: { error: @game.errors.full_messages } unless @game.present?
  end

# ...
end
  1. 修改 views
# app/views/api/v1/games/_game.json.jbuilder

json.id game.id
json.status game.status
if game.status_unknown?
  json.message "game not set up yet"
else
  json.game_config do
    json.seed game.seed
  end
  json.game_data do
    json.current_price game.current_price
  end
end
  1. 測試(略)

收工

  1. 產生並儲存 random seed
  2. 洗勻價格卡~
  3. 抽出玩家人數的染坊卡片,發給每位玩家,作為起始建築
  4. 洗勻剩餘卡牌成為牌庫(抽牌堆)
  5. 玩家依序從牌庫抽取四張卡片,作為手牌
  6. 決定起始玩家

小結

也可以直接看 diff 38959be /images/emoticon/emoticon35.gif

明天要做什麼

Sprint 2: 實作遊戲開始

以上不代表明天會做,如有雷同純屬巧合


工商服務

SPT (Side Project Taiwan) 的宗旨是藉由Side Project開發來成就自我,透過持續學習和合作,共同推動技術和專業的發展。我們相信每一個參與者,無論是什麼專業,都能在這個社群中找到屬於自己的成長空間。

歡迎所有對Side Project開發有興趣的人加入我們,可以是有點子來找夥伴,也可以是來尋找有興趣的Side Project加入,邀請大家一同打造一個充滿活力且有意義的技術社群!

Discord頻道連結: https://sideproj.tw/dc


上一篇
Day 10 - Sprint 2: 實作遊戲開始
下一篇
Day 12 - S2: 設置牌庫
系列文
透過實作網頁遊戲練習網站工程師的基本素養,以 San Juan(聖胡安) 為例。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言