use riichi_elements::prelude::*;
use crate::{
rules::Ruleset,
};
use super::{
ActionResult,
AgariResult,
};
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RoundId {
pub kyoku: u8,
pub honba: u8,
}
impl RoundId {
pub const fn prevailing_wind(self) -> Wind {
Wind::new(self.kyoku / 4)
}
pub const fn button(self) -> Player { Player::new(self.kyoku % 4) }
pub fn player_with_self_wind(self, wind: Wind) -> Player {
self.button().add(wind)
}
pub fn self_wind_for_player(self, player: Player) -> Wind {
Wind::from(player.sub(self.button()))
}
pub const fn next_kyoku(self) -> Self {
Self {
kyoku: self.kyoku + 1,
honba: 0,
}
}
pub const fn next_honba(self, renchan: bool) -> Self {
Self {
kyoku: if renchan { self.kyoku } else { self.kyoku + 1 },
honba: self.honba + 1,
}
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RoundBegin {
pub ruleset: Ruleset,
pub round_id: RoundId,
#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]
pub wall: Wall,
pub pot: GamePoints,
pub points: [GamePoints; 4],
}
impl Default for RoundBegin {
fn default() -> Self {
Self {
ruleset: Default::default(),
round_id: Default::default(),
wall: wall::make_dummy_wall(),
pot: 0,
points: [0; 4],
}
}
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct RoundEnd {
pub round_result: ActionResult,
pub pot: GamePoints,
pub points: [GamePoints; 4],
pub points_delta: [GamePoints; 4],
pub renchan: bool,
pub next_round_id: Option<RoundId>,
pub agari_result: [Option<AgariResult>; 4],
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn round_id_computes_correct_self_wind() {
let round_id = RoundId { kyoku: 6, honba: 0 };
assert_eq!(round_id.self_wind_for_player(P2), Wind::new(0));
assert_eq!(round_id.self_wind_for_player(P3), Wind::new(1));
assert_eq!(round_id.self_wind_for_player(P0), Wind::new(2));
assert_eq!(round_id.self_wind_for_player(P1), Wind::new(3));
}
}