1use std::io::{self, Stdin};
2
3use pachislo::{
4 CONFIG_EXAMPLE as CONFIG, Game, START_HOLE_PROBABILITY_EXAMPLE,
5 command::{Command, FinishGame, LaunchBallFlowProducer, StartGame},
6 game::{GameState, Transition},
7 interface::{UserInput, UserOutput},
8 lottery::LotteryResult,
9 slot::SlotProducer,
10};
11
12fn main() {
13 let input = CuiInput::new(START_HOLE_PROBABILITY_EXAMPLE);
14
15 let output = CuiOutput::new();
16
17 let mut game = Game::new(CONFIG, input, output).unwrap();
18
19 game.run();
20}
21
22pub struct CuiInput {
23 launch_ball_flow_producer: LaunchBallFlowProducer,
24 stdin: Stdin,
25}
26
27impl<O: UserOutput> UserInput<O> for CuiInput {
28 fn wait_for_input(&mut self) -> Command<Self, O> {
29 loop {
30 let mut s = String::new();
31 self.stdin.read_line(&mut s).ok();
32 match s.trim() {
33 "s" => return Command::Control(Box::new(StartGame)),
34 "l" | "" => {
35 return Command::Control(Box::new(self.launch_ball_flow_producer.produce()));
36 }
37 "q" => return Command::Control(Box::new(FinishGame)),
38 "q!" => return Command::FinishGame,
39 _ => (),
40 }
41 }
42 }
43}
44
45impl CuiInput {
46 pub fn new(start_hole_probability: f64) -> Self {
47 assert!((0.0..=1.0).contains(&start_hole_probability));
48 Self {
49 launch_ball_flow_producer: LaunchBallFlowProducer::new(start_hole_probability),
50 stdin: io::stdin(),
51 }
52 }
53}
54
55pub struct CuiOutput {
56 slot_producer: SlotProducer<u8>,
57}
58
59impl UserOutput for CuiOutput {
60 fn default(&mut self, state: Transition) {
61 let Transition {
62 before,
63 after: state,
64 } = state;
65
66 match (state, before) {
67 (GameState::Uninitialized, _) => {
68 println!("Welcome to Pachislo!");
69 println!();
70 return;
71 }
72 (GameState::Normal { .. }, Some(GameState::Rush { n, .. })) => {
73 println!("RUSH finished!, Number of RUSH times: {n}")
74 }
75 _ => {}
76 }
77
78 println!("Current state: {state:?}");
79 println!();
80 }
81
82 fn finish_game(&mut self, state: &GameState) {
83 println!("Game finished!");
84 println!("Final state: {state:?}");
85 }
86
87 fn lottery_normal(&mut self, result: LotteryResult) {
88 let slot = self.slot_producer.produce(&result);
89 Self::print_slot(slot);
90 println!("Lottery result: {result:?}");
91 }
92
93 fn lottery_rush(&mut self, result: LotteryResult) {
94 let slot = self.slot_producer.produce(&result);
95 Self::print_slot(slot);
96 println!("Lottery result in rush mode: {result:?}");
97 }
98
99 fn lottery_rush_continue(&mut self, result: LotteryResult) {
100 let slot = self.slot_producer.produce(&result);
101 Self::print_slot(slot);
102 println!("Lottery result in rush continue: {result:?}");
103 }
104}
105
106impl CuiOutput {
107 pub fn new() -> Self {
108 Self {
109 slot_producer: SlotProducer::new(3, (1..=9).collect()),
110 }
111 }
112
113 pub fn print_slot(slot: (Vec<u8>, Option<Vec<u8>>)) {
114 println!("Slot: {:?}", slot.0);
115
116 if let Some(but) = slot.1 {
117 println!("But: {but:?}");
118 }
119 }
120}
121
122impl Default for CuiOutput {
123 fn default() -> Self {
124 Self::new()
125 }
126}