Creating The Tiles From Rust

The tiles in the game should have a random placement. We'll need to add the <rand dependency to Cargo.toml for the randomization.

[dependencies]
slint = "0.2.5"
rand = "0.8" # Added

What we'll do is take the list of tiles declared in the .slint language, duplicate it, and shuffle it. We'll do so by accessing the memory_tiles property through the Rust code. For each top-level property, a getter and a setter function is generated - in our case get_memory_tiles and set_memory_tiles. Since memory_tiles is an array in the .slint language, it is represented as a Rc<dyn slint::Model>. We can't modify the model generated by the .slint, but we can extract the tiles from it, and put it in a VecModel which implements the Model trait. VecModel allows us to make modifications and we can use it to replace the static generated model.

We modify the main function like so:

fn main() {
    use slint::Model;

    let main_window = MainWindow::new();

    // Fetch the tiles from the model
    let mut tiles: Vec<TileData> = main_window.get_memory_tiles().iter().collect();
    // Duplicate them to ensure that we have pairs
    tiles.extend(tiles.clone());

    // Randomly mix the tiles
    use rand::seq::SliceRandom;
    let mut rng = rand::thread_rng();
    tiles.shuffle(&mut rng);

    // Assign the shuffled Vec to the model property
    let tiles_model = std::rc::Rc::new(slint::VecModel::from(tiles));
    main_window.set_memory_tiles(tiles_model.into());

    main_window.run();
}

Note that we clone the tiles_model because we'll use it later to update the game logic.

Running this gives us a window on the screen that now shows a 4 by 4 grid of rectangles, which can show or obscure the icons when clicking. There's only one last aspect missing now, the rules for the game.