//! 入玉宣言勝ちのルール設定
//!
//! 入玉宣言勝ちとは、自玉が相手陣（敵陣 3 段目以内）に入った状態で
//! 一定の条件を満たすとき、勝ちを宣言できるルールです。
//!
//! # 点数計算
//!
//! 敵陣にある自分の駒を点数化します。
//!
//! - 大駒（飛車・角）: 5 点
//! - 小駒（それ以外）: 1 点
//! - 玉は計算に含めない
//!
//! # ルールの種類
//!
//! | ルール | 先手の宣言条件 | 後手の宣言条件 |
//! |--------|---------------|---------------|
//! | `Point24` | 24 点以上 + 敵陣に自駒 10 枚以上 | 同左 |
//! | `Point27` | 28 点以上 + 敵陣に自駒 10 枚以上 | 27 点以上 + 同左 |
//! | `TryRule` | 自玉が相手の玉の初期位置に到達 | 同左 |
//!
//! `Handicap` 付きのバリアントは駒落ち対局用で、駒数の上限が調整されます。
//! いずれのルールでも、宣言時に自玉が王手されていないことが条件です。

/// 入玉ルール文字列
pub const EKR_STRINGS: [&str; 6] =
    ["NoEnteringKing", "CSARule24", "CSARule24H", "CSARule27", "CSARule27H", "TryRule"];

/// 入玉ルール
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
pub enum EnteringKingRule {
    /// 入玉ルールなし
    None,
    /// 24点法（31点以上で宣言勝ち）
    Point24,
    /// 24点法（駒落ち対応）
    Point24Handicap,
    /// 27点法（CSAルール）
    Point27,
    /// 27点法（駒落ち対応）
    Point27Handicap,
    /// トライルール
    TryRule,
    /// 未設定
    #[default]
    Unset,
}

impl EnteringKingRule {
    /// YaneuraOu互換の文字列に変換
    #[must_use]
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::None => EKR_STRINGS[0],
            Self::Point24 => EKR_STRINGS[1],
            Self::Point24Handicap => EKR_STRINGS[2],
            Self::Point27 => EKR_STRINGS[3],
            Self::Point27Handicap => EKR_STRINGS[4],
            Self::TryRule => EKR_STRINGS[5],
            Self::Unset => "EKR_NULL",
        }
    }

    /// 文字列に対応する `EnteringKingRule` を取得する。
    #[must_use]
    pub fn from_name(rule: &str) -> Option<Self> {
        for (idx, &name) in EKR_STRINGS.iter().enumerate() {
            if rule == name {
                return Some(match idx {
                    0 => Self::None,
                    1 => Self::Point24,
                    2 => Self::Point24Handicap,
                    3 => Self::Point27,
                    4 => Self::Point27Handicap,
                    5 => Self::TryRule,
                    _ => return None,
                });
            }
        }
        None
    }
}
