用代码生成牌面
这一步将游戏牌随机摆放。
代码使用 rand 依赖来实现随机化。使用 cargo 命令将其添加到 Cargo.toml 文件中。
cargo add rand@0.9将 main 函数修改为以下内容:
fn main() { use slint::Model;
let main_window = MainWindow::new().unwrap();
// 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::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.clone().into());
main_window.run().unwrap();}代码获取牌列表,将其复制并打乱,通过 Rust 代码访问 memory_tiles 属性。
对于每个顶层属性,
Slint 会生成一个 getter 和一个 setter 函数。在本例中为 get_memory_tiles 和 set_memory_tiles。
由于 memory_tiles 是一个 Slint 数组,表示为 Rc<dyn slint::Model>。
你无法更改 Slint 生成的模型,但可以从中提取牌并将它们
放入实现了 Model trait 的 VecModel 中。
VecModel 允许你进行修改,你可以用它来替换静态生成的模型。
将 src/main.cpp 中的 main 函数和 include 修改为以下内容:
#include <random> // Added
int main(){ auto main_window = MainWindow::create(); auto old_tiles = main_window->get_memory_tiles(); std::vector<TileData> new_tiles; new_tiles.reserve(old_tiles->row_count() * 2); for (int i = 0; i < old_tiles->row_count(); ++i) { new_tiles.push_back(*old_tiles->row_data(i)); new_tiles.push_back(*old_tiles->row_data(i)); } std::default_random_engine rng {}; std::shuffle(new_tiles.begin(), new_tiles.end(), rng); auto tiles_model = std::make_shared<slint::VectorModel<TileData>>(new_tiles); main_window->set_memory_tiles(tiles_model);
main_window->run();}代码获取牌列表,将其复制并打乱,通过 C++ 代码访问 memory_tiles 属性。
对于每个顶层属性,Slint 会生成一个 getter 和一个 setter 函数。在本例中为 get_memory_tiles 和 set_memory_tiles。
由于 memory_tiles 是一个 Slint 数组,它表示为 std::shared_ptr<slint::Model>。
你无法更改 Slint 生成的模型,但可以从中提取牌并将它们
放入继承自 Model 的 slint::VectorModel 中。
VectorModel 允许你进行修改,你可以用它来替换静态生成的模型。
将 main.js 修改为以下内容:
import * as slint from 'slint-ui';const ui = slint.loadFile(new URL('./ui/app-window.slint', import.meta.url));const mainWindow = new ui.MainWindow();
const initial_tiles = [...mainWindow.memory_tiles];const tiles = initial_tiles.concat( initial_tiles.map((tile) => Object.assign({}, tile)),);
for (let i = tiles.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * i); [tiles[i], tiles[j]] = [tiles[j], tiles[i]];}
const model = new slint.ArrayModel(tiles);mainWindow.memory_tiles = model;
await mainWindow.run();代码获取牌列表,将其复制并打乱,通过 JavaScript 代码访问 memory_tiles 属性。
由于 memory_tiles 是一个数组,它表示为 JavaScript 的 Array。
你无法更改 Slint 生成的模型,但可以从中提取牌并将它们
放入实现了 Model 接口的 slint.ArrayModel 中。
ArrayModel 允许你进行修改,你可以用它来替换静态生成的模型。
将 main.py 修改为以下内容:
import slintimport sysimport osimport randomimport itertoolsimport copyimport datetime
class MainWindow(slint.loader.ui.app_window.MainWindow): def __init__(self): super().__init__() initial_tiles = self.memory_tiles tiles = slint.ListModel( itertools.chain( map(copy.copy, initial_tiles), map(copy.copy, initial_tiles) ) ) random.shuffle(tiles) self.memory_tiles = tiles
main_window = MainWindow()main_window.show()main_window.run()代码获取牌列表,将其复制并打乱,通过 Python 代码访问 memory_tiles 属性。
由于 memory_tiles 是一个数组,它表示为 Slint 的 ListModel。
你无法更改 Slint 生成的模型,但可以从中提取牌并将它们
放入 slint.ListModel 中,它是 Model 接口的子类。
ListModel 允许你进行修改,你可以用它来替换静态生成的模型。
运行这段代码会打开一个窗口,现在显示一个 4×4 的矩形网格,当玩家点击它们时 会显示或隐藏图标。
现在还缺少最后一方面内容,即游戏规则。
© 2026 SixtyFPS GmbH