minsweeper_rs/solver/
mod.rs

1pub 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 const fn new(actions: HashSet<Action>, reason: Option<Reason<T>>) -> Self {
41    //     Self { actions, reason }
42    // }
43
44    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}