diff --git a/opening-book/book-builder/src/main.rs b/opening-book/book-builder/src/main.rs index b474c31..814df19 100644 --- a/opening-book/book-builder/src/main.rs +++ b/opening-book/book-builder/src/main.rs @@ -223,13 +223,13 @@ fn dump(book: &opening_book::BookBuilder) { } write!(f, "

").unwrap(); let mut moves: Vec<_> = book.moves(pos).into_iter() - .map(|mv| (mv, book.value_of_position(pos.advance(mv.location).0))) + .map(|mv| (mv, book.value_of_position(pos.advance(mv.location()).0))) .collect(); moves.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap().reverse()); for (mv, v) in moves { - let cells = mv.location.cells(); - write!(f, "", name(pos.advance(mv.location).0)).unwrap(); - match mv.value { + let cells = mv.location().cells(); + write!(f, "", name(pos.advance(mv.location()).0)).unwrap(); + match mv.value() { Some(v) => write!(f, "V={}", v).unwrap(), None => { write!(f, "E(V)={:.5}", v.value).unwrap(); @@ -245,7 +245,7 @@ fn dump(book: &opening_book::BookBuilder) { if pos.rows()[y] & 1< "cyan", Piece::J => "blue", Piece::L => "orange", diff --git a/opening-book/src/builder.rs b/opening-book/src/builder.rs index 8ceac81..577aedd 100644 --- a/opening-book/src/builder.rs +++ b/opening-book/src/builder.rs @@ -10,7 +10,7 @@ pub struct BookBuilder { #[derive(Clone, Debug, Serialize, Deserialize)] struct PositionData { - values: HashMap, + values: HashMap, moves: Vec, backrefs: Vec } @@ -27,8 +27,18 @@ impl Default for PositionData { #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct Move { - pub location: FallingPiece, - pub value: Option + location: CompactPiece, + value: OptionNanF32 +} + +impl Move { + pub fn location(&self) -> FallingPiece { + self.location.into() + } + + pub fn value(&self) -> Option { + self.value.into() + } } impl BookBuilder { @@ -60,7 +70,7 @@ impl BookBuilder { let queue = queue.iter().copied().take(NEXT_PIECES) .collect::>() .into_inner().ok()?; - values.get(&Sequence { next, queue }).map(|&(_, mv)| mv) + values.get(&Sequence { next, queue }).map(|&(_, mv)| mv.into()) } pub fn value_of_position(&self, pos: Position) -> MoveValue { @@ -107,11 +117,12 @@ impl BookBuilder { let mut best = MoveValue::default(); let mut best_move = None; for &mv in &this.moves { - if !next.contains(mv.location.kind.0) { + let current_mv = mv.location(); + if !next.contains(current_mv.kind.0) { continue; } - let (pos, long_moves) = pos.advance(mv.location); - let mut value = if let Some(value) = mv.value { + let (pos, long_moves) = pos.advance(mv.location.into()); + let mut value = if let Some(value) = mv.value.into() { MoveValue { long_moves: 0.0, value @@ -120,7 +131,7 @@ impl BookBuilder { self.value_of_raw(pos, next | queue[0], &queue[1..], qbag) } else { self.value_of_raw( - pos, next - mv.location.kind.0 | queue[0], &queue[1..], qbag + pos, next - current_mv.kind.0 | queue[0], &queue[1..], qbag ) }; value.long_moves += long_moves; @@ -128,11 +139,11 @@ impl BookBuilder { best = value; best_move = Some(mv.location); } else if value == best && best != MoveValue::default() { - let best_mv = best_move.unwrap(); - let ord = mv.location.x.cmp(&best_mv.x) - .then(mv.location.y.cmp(&best_mv.y)) - .then((mv.location.kind.0 as usize).cmp(&(best_mv.kind.0 as usize))) - .then((mv.location.kind.1 as usize).cmp(&(best_mv.kind.1 as usize))); + let best_mv: FallingPiece = best_move.unwrap().into(); + let ord = current_mv.x.cmp(&best_mv.x) + .then(current_mv.y.cmp(&best_mv.y)) + .then((current_mv.kind.0 as usize).cmp(&(best_mv.kind.0 as usize))) + .then((current_mv.kind.1 as usize).cmp(&(best_mv.kind.1 as usize))); if ord == std::cmp::Ordering::Greater { best_move = Some(mv.location); } @@ -168,16 +179,16 @@ impl BookBuilder { let moves = &mut self.data.entry(position).or_default().moves; let mut add_backref = false; let mut remove_backref = false; - match moves.iter_mut().find(|m| m.location.same_location(&mv)) { - Some(mv) => if mv.value < value { - remove_backref = mv.value.is_none() && value.is_some(); - mv.value = value; + match moves.iter_mut().find(|m| m.location().same_location(&mv)) { + Some(mv) => if mv.value() < value { + remove_backref = mv.value().is_none() && value.is_some(); + mv.value = value.into(); } None => { add_backref = value.is_none(); moves.push(Move { - location: mv, - value + location: mv.into(), + value: value.into() }); } } @@ -286,4 +297,26 @@ impl std::iter::Sum for MoveValue { } this } +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +struct OptionNanF32(f32); + +impl From> for OptionNanF32 { + fn from(v: Option) -> Self { + match v { + Some(v) => Self(v), + None => Self(std::f32::NAN) + } + } +} + +impl From for Option { + fn from(v: OptionNanF32) -> Self { + if v.0.is_nan() { + None + } else { + Some(v.0) + } + } } \ No newline at end of file