Early legality check to not clone asa often

This commit is contained in:
Daniel Olsen 2022-02-17 00:30:59 +01:00
parent f82b210e28
commit 94982994f5
4 changed files with 83 additions and 5 deletions

View File

@ -26,7 +26,7 @@ byte-strings = "0.2.2"
#alloc_counter = "0.0.4"
[profile.release]
debug = 1
debug = 0
lto = "fat"
codegen-units = 1
panic = "abort"

View File

@ -665,6 +665,79 @@ impl State {
self.player = (self.player + 1) % self.boards.len() as u8;
Ok(())
}
pub fn is_legal(&self, game_move: GameMove) -> Result<(), &'static str> {
let board = &self.boards[self.player as usize];
match game_move {
GameMove(_, Tile::Start, _) => return Err("You can't take the start tile specifically"),
GameMove(0, _, 0) => {
if !&self.market.contains(&game_move.1) {
return Err("Market does not contain selected tile")
}
else {
Ok(())
}
},
GameMove(0, _, 1..=5) => {
if self.market.len() == 0 {
return Err("Market is empty");
}
else if self.market.contains(&game_move.1) {
let target = &board.patterns[game_move.2 - 1];
if target.first().is_some() && target[0] != game_move.1 {
return Err("That pattern line already contains a different color")
}
let empty = game_move.2 - target.len();
if empty == 0 {
return Err("That pattern is full")
}
Ok(())
}
else {
return Err("Market does not contain selected tile")
}
},
GameMove(1..=9, _, _) => {
let board = &self.boards[self.player as usize];
if game_move.0 > self.factories.len() {
return Err("That factory is out of bounds");
}
let factory = self.factories[game_move.0 - 1].deref();
if factory.contains(&game_move.1) {
let mut hand = factory.clone();
hand.retain(|x| *x == game_move.1);
match game_move.2 {
0 => Ok(()),
1..=9 => {
let target = &board.patterns[game_move.2 - 1];
if target.first().is_some() && target[0] != game_move.1 {
return Err("That pattern line already contains a different color")
}
let empty = game_move.2 - target.len();
if hand.len() <= empty {
return Ok(())
}
else if empty != 0 {
return Ok(())
}
else {
return Err("That pattern line is full")
}
},
_ => return Err("Not a valid destination")
}
}
else {
return Err("That tile is not in that factory")
}
},
GameMove(_,_,_) => return Err("Not a valid move")
}
}
/*pub fn hash(&self) -> [u8; 256]{
[
[self.player],

View File

@ -485,9 +485,10 @@ impl Game2 {
use std::time::{Instant, Duration};
pub fn size_of_bitfields() -> Result<(), &'static str> {
//println!("size of bitfield game: {}", std::mem::size_of::<Game2>());
println!("size of bitfield game: {}", std::mem::size_of::<Game2>());
println!("size of state: {}", std::mem::size_of::<super::azul::State>());
let game2 = Game2::create();
/* let game2 = Game2::create();
//println!("debug: {:#?}", game2);
//println!("{:?}", game2.into_bytes());
@ -510,7 +511,7 @@ pub fn size_of_bitfields() -> Result<(), &'static str> {
let game_1_time = now.elapsed().as_nanos();
println!("{} | {}", game_1_time, game_2_time);
*/
Ok(())

View File

@ -100,11 +100,12 @@ fn count_options(_game: Game, depth: u8, treshold: u8) -> u128 {
let mut multiplier = 1;
// Upper bound calculation by skipping first depth and assuming most complicated possible game as multiplier
let game = match depth {
0 => {
let mut new_game = _game.clone();
for i in GameMoveIter::new(2).next() {
match new_game.do_move( i) {
match new_game.do_move(i) {
Ok(_) => break,
Err(_) => continue
}
@ -121,6 +122,9 @@ fn count_options(_game: Game, depth: u8, treshold: u8) -> u128 {
for game_move in i {
//println!("{:?}", game_move);
if game.is_legal(game_move).is_err() {
continue;
};
let mut new_game = game.clone();
let r = new_game.do_move(game_move);
match r {