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