Add capability to convert AI plays into PlayedTiles vector
This commit is contained in:
parent
0887cb29aa
commit
e23c1d139b
2 changed files with 56 additions and 16 deletions
16
src/game.rs
16
src/game.rs
|
@ -33,11 +33,11 @@ pub struct PlayerState {
|
|||
pub tray: Tray
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Tsify, Copy, Clone)]
|
||||
#[derive(Deserialize, Tsify, Copy, Clone, Debug)]
|
||||
#[tsify(from_wasm_abi)]
|
||||
pub struct PlayedTile {
|
||||
index: usize,
|
||||
character: Option<char>,
|
||||
pub index: usize,
|
||||
pub character: char,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Tsify)]
|
||||
|
@ -164,15 +164,7 @@ impl Game {
|
|||
|
||||
let coord = Coordinates::new_from_index(played_tile.index);
|
||||
if letter.is_blank {
|
||||
match played_tile.character {
|
||||
None => {
|
||||
panic!("You can't play a blank character without providing a letter value")
|
||||
}
|
||||
Some(x) => {
|
||||
// TODO - I should check that the character is a valid letter
|
||||
letter.text = x;
|
||||
}
|
||||
}
|
||||
letter.text = played_tile.character;
|
||||
}
|
||||
played_letters.push((letter, coord));
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use rand::Rng;
|
|||
use crate::board::{Board, CellType, Coordinates, Direction, Letter};
|
||||
use crate::constants::GRID_LENGTH;
|
||||
use crate::dictionary::DictionaryImpl;
|
||||
use crate::game::PlayedTile;
|
||||
use crate::player_interaction::Tray;
|
||||
|
||||
const ALPHABET: [char; 26] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
|
||||
|
@ -51,6 +52,47 @@ pub struct CompleteMove {
|
|||
score: u32,
|
||||
}
|
||||
|
||||
impl CompleteMove {
|
||||
|
||||
pub fn convert_to_play(&self, tray: &Tray) -> Vec<Option<PlayedTile>> {
|
||||
let mut played_tiles = Vec::with_capacity(tray.letters.len());
|
||||
let mut moves = self.moves.iter()
|
||||
.map(|m| Some(m.clone()))
|
||||
.collect::<Vec<Option<MoveComponent>>>();
|
||||
|
||||
tray.letters.iter().for_each(|letter| {
|
||||
match letter {
|
||||
None => {
|
||||
played_tiles.push(None);
|
||||
}
|
||||
Some(letter) => {
|
||||
let mut found_match = false;
|
||||
// see if we can find a match in moves
|
||||
for m in moves.iter_mut() {
|
||||
match m {
|
||||
Some(x) => {
|
||||
if letter.partial_match(&x.letter) {
|
||||
played_tiles.push(Some(PlayedTile {
|
||||
index: x.coordinates.map_to_index(),
|
||||
character: x.letter.text,
|
||||
}));
|
||||
*m = None;
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
assert!(found_match);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
played_tiles
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MoveScoring {
|
||||
main_scoring: u32,
|
||||
|
@ -827,7 +869,7 @@ mod tests {
|
|||
ephemeral: false,
|
||||
is_blank: false,
|
||||
});
|
||||
tray.letters[2] = Some(Letter{
|
||||
tray.letters[6] = Some(Letter{
|
||||
text: 'A',
|
||||
points: 1,
|
||||
ephemeral: false,
|
||||
|
@ -848,19 +890,25 @@ mod tests {
|
|||
assert!(end_of_boat.is_some());
|
||||
assert_eq!(end_of_boat.as_ref().unwrap().len(), 1);
|
||||
|
||||
//let rng = SmallRng::seed_from_u64(123);
|
||||
|
||||
let moves = ai.find_all_moves(&tray, &board);
|
||||
|
||||
println!("Moves are {:?}", moves);
|
||||
|
||||
|
||||
// 2 possible moves -
|
||||
// 3 possible moves -
|
||||
// 1. put 'S' at the end of 'BOAT' and form words 'SLAM' and 'BOATS'
|
||||
// 2. Put 'S' at end of 'BOAT'
|
||||
// 3. Put 'SL' to left of 'A' in 'BOAT' and then 'M' to right of it
|
||||
assert_eq!(moves.len(), 3);
|
||||
|
||||
let mut rng = SmallRng::seed_from_u64(123);
|
||||
let best_move = ai.find_best_move(&tray, &board, &mut rng).unwrap();
|
||||
|
||||
assert_eq!(best_move.score, 23);
|
||||
|
||||
let play = best_move.convert_to_play(&tray);
|
||||
println!("Play is {:?}", play);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue