Files
kondiplo_front/app/models/turn.rb
kontei f25fd6f802
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
フロントエンドプレイアブル
2026-02-15 14:57:17 +09:00

125 lines
3.7 KiB
Ruby

class Turn < ApplicationRecord
belongs_to :game
# 特定の国の実行可能な命令を取得
# 例: turn.possible_orders_for("FRANCE")
def possible_orders_for(power_name)
possible_orders&.dig("possible_orders", power_name.to_s.upcase)
end
# 特定の国の決定済み命令を取得
# 例: turn.orders_for("FRANCE")
def orders_for(power_name)
# orders は直接ハッシュを保存する場合を想定(必要に応じてネストを調整)
orders&.dig(power_name.to_s.upcase)
end
# 命令が存在するすべての国名リストを取得
def powers
possible_orders&.dig("possible_orders")&.keys || []
end
# 特定の国の命令が提出済みかチェック
def orders_submitted_for?(power_name)
orders&.key?(power_name.to_s.upcase)
end
# 未提出の国のリストを取得
def pending_powers
game.participants.where.not(power: nil).map(&:power).reject do |power|
orders_submitted_for?(power)
end
end
# 自動命令を生成(参加者がいない国用)
def generate_auto_orders_for_unassigned_powers
unassigned = game.unassigned_powers
return if unassigned.empty?
client = GameApiClient.new
current_orders = orders || {}
unassigned.each do |power|
if game.auto_order_mode == "hold"
# HOLD命令を生成
current_orders[power] = generate_hold_orders(power)
else
# ランダム命令を生成
auto_orders_response = client.api_calculate_auto_orders(game_state, power)
if auto_orders_response
# APIレスポンスから命令を抽出
# レスポンスが {"orders": [...]} の形式の場合
if auto_orders_response.is_a?(Hash) && auto_orders_response["orders"]
current_orders[power] = auto_orders_response["orders"]
elsif auto_orders_response.is_a?(Array)
current_orders[power] = auto_orders_response
else
# フォールバック: HOLD命令を使用
current_orders[power] = generate_hold_orders(power)
end
end
end
end
update(orders: current_orders)
update(orders: current_orders)
end
# 引き分け投票
def vote_draw(power_name)
current_votes = draw_votes || []
power = power_name.to_s.upcase
unless current_votes.include?(power)
current_votes << power
update(draw_votes: current_votes)
end
end
# 引き分け投票取り消し
def revoke_draw_vote(power_name)
current_votes = draw_votes || []
power = power_name.to_s.upcase
if current_votes.include?(power)
current_votes.delete(power)
update(draw_votes: current_votes)
end
end
# 投票済みかチェック
def draw_voted?(power_name)
(draw_votes || []).include?(power_name.to_s.upcase)
end
# 全会一致で引き分けかチェック
def unanimous_draw?
# 生存している国
active_powers = powers
return false if active_powers.empty?
# プレイヤーが割り当てられている国のみを対象とする
# (未割り当ての国は投票できないため、除外する)
assigned_powers = game.participants.where.not(power: nil).pluck(:power).map(&:upcase)
# 投票権を持つ国 = 生存している かつ プレイヤーがいる
eligible_powers = active_powers.map(&:upcase) & assigned_powers
return false if eligible_powers.empty?
current_votes = draw_votes || []
eligible_powers.all? { |power| current_votes.include?(power) }
end
private
def generate_hold_orders(power)
possible = possible_orders_for(power)
return {} unless possible
hold_orders = {}
possible.each do |unit, moves|
hold_orders[unit] = [ "H" ] if moves.is_a?(Array)
end
hold_orders
end
end