use crate::score::{FuValue, HanValue, HonbaCounter};
pub(crate) type Points = u64;
const DEALER_RON_MULTIPLIER: u64 = 6;
const DEALER_TSUMO_MULTIPLIER: u64 = 2;
const NON_DEALER_RON_MULTIPLIER: u64 = 4;
const NON_DEALER_TSUMO_TO_NON_DEALER_MULTIPLIER: u64 = 1;
const NON_DEALER_TSUMO_TO_DEALER_MULTIPLIER: u64 = 2;
#[derive(Debug)]
pub struct Payment {
base_points: Points,
tsumibou: Points,
}
impl Payment {
pub fn new(base_points: Points) -> Self {
Self {
base_points,
tsumibou: 300,
}
}
pub fn from_han_and_fu(han: HanValue, fu: FuValue) -> Self {
let fu = if fu == 25 {
fu
} else {
fu.div_ceil(10) * 10
};
Self::new(fu * 2u64.pow(han + 2))
}
pub fn base_points(&self) -> Points {
self.base_points
}
fn round_payment(&self, unrounded_payment: Points) -> Points {
unrounded_payment.div_ceil(100) * 100
}
pub fn dealer_ron(&self, honba: HonbaCounter) -> Points {
self.round_payment((self.base_points * DEALER_RON_MULTIPLIER) + (self.tsumibou * honba))
}
pub fn dealer_tsumo(&self, honba: HonbaCounter) -> Points {
self.round_payment(
(self.base_points * DEALER_TSUMO_MULTIPLIER) + ((self.tsumibou / 3) * honba),
)
}
pub fn non_dealer_ron(&self, honba: HonbaCounter) -> Points {
self.round_payment((self.base_points * NON_DEALER_RON_MULTIPLIER) + (self.tsumibou * honba))
}
pub fn non_dealer_tsumo_to_dealer(&self, honba: HonbaCounter) -> Points {
self.round_payment(
(self.base_points * NON_DEALER_TSUMO_TO_DEALER_MULTIPLIER)
+ ((self.tsumibou / 3) * honba),
)
}
pub fn non_dealer_tsumo_to_non_dealer(&self, honba: HonbaCounter) -> Points {
self.round_payment(
(self.base_points * NON_DEALER_TSUMO_TO_NON_DEALER_MULTIPLIER)
+ ((self.tsumibou / 3) * honba),
)
}
}