Files
kondiplo_front/app/models/turn.rb
kontei e90ea88758
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
refactor: BoardAccessible concernを導入し、ボード関連コントローラを整理、ターン表示ロジックをTurnモデルへ移動し、ボード提案表示をコントローラで処理するよう変更
2026-02-19 22:46:24 +09:00

138 lines
4.2 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class Turn < ApplicationRecord
belongs_to :game
SEASON_MAP = { "S" => "", "F" => "", "W" => "" }.freeze
PHASE_TYPE_MAP = { "M" => "移動", "R" => "撤退", "A" => "調整" }.freeze
# フェーズコードを日本語表示に変換(例: "S1901M" → "1901年 春 (移動)"
def display_phase
return nil unless phase.present? && phase.length >= 6
year = phase[1..4]
season = SEASON_MAP[phase[0]] || ""
type = PHASE_TYPE_MAP[phase[-1]] || ""
"#{year}#{season} (#{type})"
end
# 特定の国の実行可能な命令を取得
# 例: 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