minsweeper_rs/solver/
mod.rs1pub mod mia;
2pub mod start;
3
4use std::collections::HashSet;
5use std::fmt::{Debug, Display};
6use crate::{GameState, GameStatus, Minsweeper};
7use crate::board::Point;
8
9pub trait Solver {
10
11 fn solve(&self, game_state: &GameState) -> Option<Move>;
12
13 fn solve_game(&self, minsweeper: &mut dyn Minsweeper) -> GameResult {
14 let mut state = minsweeper.gamestate();
15
16 while state.status == GameStatus::Playing {
17 let Some(Move { actions, ..}) = self.solve(state) else { break };
18
19 for action in actions {
20 state = minsweeper.action(action).into()
21 }
22 }
23
24 match state.status {
25 GameStatus::Won => GameResult::Won,
26 GameStatus::Lost => GameResult::Lost,
27 GameStatus::Playing => GameResult::Resigned,
28 _ => unreachable!()
29 }
30 }
31}
32
33#[derive(Debug)]
34pub struct Move {
35 pub actions: HashSet<Action>,
36 pub reason: Option<Reason>
37}
38
39impl Move {
40 pub fn single(action: Action, reason: Option<Reason>) -> Self {
45 Self {
46 actions: HashSet::from([action]),
47 reason
48 }
49 }
50
51 pub const fn multi(actions: HashSet<Action>, reason: Option<Reason>) -> Self {
52 Self { actions, reason }
53 }
54}
55
56#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
57pub struct Action {
58 point: Point,
59 operation: Operation,
60}
61
62impl Action {
63 pub const fn new(point: Point, operation: Operation) -> Self {
64 Self { point, operation }
65 }
66}
67
68#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
69pub enum Operation {
70 Reveal,
71 Chord,
72 Flag
73}
74
75pub trait Actionable {
76 fn action(&mut self, action: Action) -> Result<&GameState, &GameState>;
77}
78
79impl<T: Minsweeper + ?Sized> Actionable for T {
80 fn action(&mut self, action: Action) -> Result<&GameState, &GameState> {
81 match action.operation {
82 Operation::Reveal => self.reveal(action.point),
83 Operation::Chord => self.clear_around(action.point),
84 Operation::Flag => self.toggle_flag(action.point)
85 }
86 }
87}
88
89#[derive(Debug)]
90pub struct Reason {
91 pub logic: Box<dyn Logic>,
92 pub related: HashSet<Point>
93}
94
95impl Reason {
96 pub fn new<T: Logic + 'static>(logic: T, related: HashSet<Point>) -> Self {
97 Self { logic: Box::new(logic), related }
98 }
99}
100
101pub trait Logic: Debug + Display {
102
103}
104
105#[derive(Copy, Clone, Debug, Eq, PartialEq)]
106pub enum GameResult {
107 Won, Lost, Resigned
108}