use crate::algorithms::{cal_probability_onboard, solve_direct, solve_enumerate, solve_minus};
use crate::utils::{cal_bbbv_on_island, cal_cell_nums, cal_isl, cal_op, refresh_matrixs};
#[derive(Clone, Debug)]
pub struct GameBoard {
pub game_board: Vec<Vec<i32>>,
game_board_marked: Vec<Vec<i32>>,
poss: Vec<Vec<f64>>,
mine_num: usize,
is_marked: bool, has_poss: bool, basic_not_mine: Vec<(usize, usize)>,
basic_is_mine: Vec<(usize, usize)>,
enum_not_mine: Vec<(usize, usize)>,
enum_is_mine: Vec<(usize, usize)>,
}
impl GameBoard {
pub fn new(mine_num: usize) -> GameBoard {
GameBoard {
game_board: vec![],
game_board_marked: vec![],
poss: vec![],
mine_num: mine_num,
is_marked: false,
has_poss: false,
basic_is_mine: vec![],
basic_not_mine: vec![],
enum_is_mine: vec![],
enum_not_mine: vec![],
}
}
pub fn set_game_board(&mut self, board: &Vec<Vec<i32>>) {
let mut game_board_marked = board.clone();
for i in 0..game_board_marked.len() {
for j in 0..game_board_marked[0].len() {
if game_board_marked[i][j] > 10 {
game_board_marked[i][j] = 10;
}
}
}
self.game_board = board.clone();
self.game_board_marked = game_board_marked;
}
fn mark(&mut self) {
if self.is_marked {
return;
}
let (mut a_s, mut x_s, mut b_s, _, _) = refresh_matrixs(&self.game_board_marked);
let mut ans = solve_direct(&mut a_s, &mut x_s, &mut b_s, &mut self.game_board_marked)
.unwrap()
.0;
self.basic_not_mine.append(&mut ans);
let mut ans = solve_minus(&mut a_s, &mut x_s, &mut b_s, &mut self.game_board_marked)
.unwrap()
.0;
self.basic_not_mine.append(&mut ans);
for i in &self.basic_not_mine {
self.game_board_marked[i.0][i.1] = 12;
}
for i in 0..self.game_board_marked.len() {
for j in 0..self.game_board_marked[0].len() {
if self.game_board_marked[i][j] == 11 {
self.basic_is_mine.push((i, j));
}
}
}
self.enum_not_mine = solve_enumerate(&a_s, &x_s, &b_s).0;
for i in 0..self.game_board_marked.len() {
for j in 0..self.game_board_marked[0].len() {
if self.game_board_marked[i][j] == 11 && !self.basic_is_mine.contains(&(i, j)) {
self.enum_is_mine.push((i, j));
}
}
}
self.is_marked = true;
}
pub fn get_poss(&mut self) -> &Vec<Vec<f64>> {
if !self.has_poss {
self.mark();
self.poss = cal_probability_onboard(&self.game_board_marked, self.mine_num as f64)
.unwrap()
.0;
self.has_poss = true;
}
&self.poss
}
pub fn get_basic_not_mine(&mut self) -> &Vec<(usize, usize)> {
if !self.is_marked {
self.mark();
self.is_marked = true;
}
&self.basic_not_mine
}
pub fn get_basic_is_mine(&mut self) -> &Vec<(usize, usize)> {
if !self.is_marked {
self.mark();
self.is_marked = true;
}
&self.basic_is_mine
}
pub fn get_enum_not_mine(&mut self) -> &Vec<(usize, usize)> {
if !self.is_marked {
self.mark();
self.is_marked = true;
}
&self.enum_not_mine
}
pub fn get_enum_is_mine(&mut self) -> &Vec<(usize, usize)> {
if !self.is_marked {
self.mark();
self.is_marked = true;
}
&self.enum_is_mine
}
}
#[derive(Clone)]
pub struct Board {
pub board: Vec<Vec<i32>>,
bbbv: Option<usize>,
openings: Option<usize>,
islands: Option<usize>,
cell0: usize,
cell1: usize,
cell2: usize,
cell3: usize,
cell4: usize,
cell5: usize,
cell6: usize,
cell7: usize,
cell8: usize,
has_cal_cells: bool,
}
impl Board {
pub fn new(board: Vec<Vec<i32>>) -> Board {
Board {
board,
bbbv: None,
openings: None,
islands: None,
cell0: 0,
cell1: 0,
cell2: 0,
cell3: 0,
cell4: 0,
cell5: 0,
cell6: 0,
cell7: 0,
cell8: 0,
has_cal_cells: false,
}
}
pub fn get_bbbv(&mut self) -> usize {
if let Some(value) = self.bbbv {
return value;
}
self.bbbv = Some(cal_bbbv_on_island(&self.board) + self.get_op());
return self.bbbv.unwrap();
}
pub fn get_op(&mut self) -> usize {
*self.openings.get_or_insert_with(|| cal_op(&self.board))
}
pub fn get_isl(&mut self) -> usize {
*self.islands.get_or_insert_with(|| cal_isl(&self.board))
}
fn cal_cell_nums(&mut self) {
let ans = cal_cell_nums(&self.board);
self.cell0 = ans[0];
self.cell1 = ans[1];
self.cell2 = ans[2];
self.cell3 = ans[3];
self.cell4 = ans[4];
self.cell5 = ans[5];
self.cell6 = ans[6];
self.cell7 = ans[7];
self.cell8 = ans[8];
self.has_cal_cells = true;
}
pub fn get_cell0(&mut self) -> usize {
if self.has_cal_cells {
return self.cell0;
}
self.cal_cell_nums();
return self.cell0;
}
pub fn get_cell1(&mut self) -> usize {
if self.has_cal_cells {
return self.cell1;
}
self.cal_cell_nums();
return self.cell1;
}
pub fn get_cell2(&mut self) -> usize {
if self.has_cal_cells {
return self.cell2;
}
self.cal_cell_nums();
return self.cell2;
}
pub fn get_cell3(&mut self) -> usize {
if self.has_cal_cells {
return self.cell3;
}
self.cal_cell_nums();
return self.cell3;
}
pub fn get_cell4(&mut self) -> usize {
if self.has_cal_cells {
return self.cell4;
}
self.cal_cell_nums();
return self.cell4;
}
pub fn get_cell5(&mut self) -> usize {
if self.has_cal_cells {
return self.cell5;
}
self.cal_cell_nums();
return self.cell5;
}
pub fn get_cell6(&mut self) -> usize {
if self.has_cal_cells {
return self.cell6;
}
self.cal_cell_nums();
return self.cell6;
}
pub fn get_cell7(&mut self) -> usize {
if self.has_cal_cells {
return self.cell7;
}
self.cal_cell_nums();
return self.cell7;
}
pub fn get_cell8(&mut self) -> usize {
if self.has_cal_cells {
return self.cell8;
}
self.cal_cell_nums();
return self.cell8;
}
}