1use crate::calculator;
2use crate::calculator::result::{Points, ScoreResult};
3use crate::constants::hand::WinningHand;
4use crate::core::CalcError::{HandValidationError, NoYakuError};
5use crate::finder::finder;
6use crate::finder::result::FoundResult;
7use crate::parser::{Input, ValidationError};
8use std::collections::HashMap;
9
10#[derive(Debug)]
11pub enum CalcError {
12 HandValidationError(ValidationError),
13 NoYakuError(String),
14}
15
16#[derive(Debug)]
17#[allow(dead_code)]
18pub struct Output {
19 winning_hand: WinningHand,
20 found_result: FoundResult,
21 score_result: ScoreResult,
22}
23
24type Outputs = Vec<Output>;
25
26impl Input {
27 pub fn calc_hand(self) -> Result<Output, CalcError> {
33 let hands = self.parse_hand();
34 if hands.is_err() {
35 return Err(HandValidationError(hands.unwrap_err()));
36 }
37
38 let mut outputs: Outputs = vec![];
39 for hand in hands.unwrap() {
40 let found = finder::Finder::find_hand(&hand);
41 if !found.is_valid_hora() {
42 continue;
43 }
44 let score = calculator::score::calc_score(
45 &found,
46 &hand.field,
47 &hand.winning_hand,
48 &hand.status,
49 );
50 outputs.push(Output {
51 winning_hand: hand.winning_hand,
52 found_result: found,
53 score_result: score,
54 });
55 }
56
57 if outputs.len() == 0 {
58 return Err(NoYakuError("No yaku found".to_string()));
59 }
60
61 Ok(get_highest(outputs))
62 }
63}
64
65fn get_highest(results: Outputs) -> Output {
66 let mut result_sum: HashMap<u32, Output> = HashMap::new();
67
68 for result in results {
69 let sum = match result.score_result.points {
70 Points::ChildTumo(x, y) => x * 2 + y,
71 Points::DealerTumo(x) | Points::Ron(x) => x,
72 };
73
74 result_sum.insert(sum, result);
75 }
76
77 let highest = result_sum.into_iter().max_by(|x, y| x.0.cmp(&y.0)).unwrap();
78
79 highest.1
80}