Add capability to convert AI plays into PlayedTiles vector

This commit is contained in:
Joel Therrien 2023-09-07 19:44:07 -07:00
parent 0887cb29aa
commit e23c1d139b
2 changed files with 56 additions and 16 deletions

View file

@ -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));

View file

@ -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]