1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: MIT
3
4#[allow(dead_code)]
5fn main() {
6 use slint::Model;
7
8 let main_window = MainWindow::new().unwrap();
9
10 // Fetch the tiles from the model
11 let mut tiles: Vec<TileData> = main_window.get_memory_tiles().iter().collect();
12 // Duplicate them to ensure that we have pairs
13 tiles.extend(tiles.clone());
14
15 // Randomly mix the tiles
16 use rand::seq::SliceRandom;
17 let mut rng = rand::thread_rng();
18 tiles.shuffle(&mut rng);
19
20 // ANCHOR: game_logic
21 // Assign the shuffled Vec to the model property
22 let tiles_model = std::rc::Rc::new(slint::VecModel::from(tiles));
23 main_window.set_memory_tiles(tiles_model.clone().into());
24
25 let main_window_weak = main_window.as_weak();
26 main_window.on_check_if_pair_solved(move || {
27 let mut flipped_tiles =
28 tiles_model.iter().enumerate().filter(|(_, tile)| tile.image_visible && !tile.solved);
29
30 if let (Some((t1_idx, mut t1)), Some((t2_idx, mut t2))) =
31 (flipped_tiles.next(), flipped_tiles.next())
32 {
33 let is_pair_solved = t1 == t2;
34 if is_pair_solved {
35 t1.solved = true;
36 tiles_model.set_row_data(t1_idx, t1);
37 t2.solved = true;
38 tiles_model.set_row_data(t2_idx, t2);
39 } else {
40 let main_window = main_window_weak.unwrap();
41 main_window.set_disable_tiles(true);
42 let tiles_model = tiles_model.clone();
43 slint::Timer::single_shot(std::time::Duration::from_secs(1), move || {
44 main_window.set_disable_tiles(false);
45 t1.image_visible = false;
46 tiles_model.set_row_data(t1_idx, t1);
47 t2.image_visible = false;
48 tiles_model.set_row_data(t2_idx, t2);
49 });
50 }
51 }
52 });
53 // ANCHOR_END: game_logic
54 main_window.run().unwrap();
55}
56
57slint::slint! {
58 struct TileData {
59 image: image,
60 image_visible: bool,
61 solved: bool,
62 }
63
64 component MemoryTile inherits Rectangle {
65 callback clicked;
66 in property <bool> open_curtain;
67 in property <bool> solved;
68 in property <image> icon;
69
70 height: 64px;
71 width: 64px;
72 background: solved ? #34CE57 : #3960D5;
73 animate background { duration: 800ms; }
74
75 Image {
76 source: icon;
77 width: parent.width;
78 height: parent.height;
79 }
80
81 // Left curtain
82 Rectangle {
83 background: #193076;
84 width: open_curtain ? 0px : (parent.width / 2);
85 height: parent.height;
86 animate width { duration: 250ms; easing: ease-in; }
87 }
88
89 // Right curtain
90 Rectangle {
91 background: #193076;
92 x: open_curtain ? parent.width : (parent.width / 2);
93 width: open_curtain ? 0px : (parent.width / 2);
94 height: parent.height;
95 animate width { duration: 250ms; easing: ease-in; }
96 animate x { duration: 250ms; easing: ease-in; }
97 }
98
99 TouchArea {
100 clicked => {
101 // Delegate to the user of this element
102 root.clicked();
103 }
104 }
105 }
106 // ANCHOR: mainwindow_interface
107 export component MainWindow inherits Window {
108 width: 326px;
109 height: 326px;
110
111 callback check_if_pair_solved(); // Added
112 in property <bool> disable_tiles; // Added
113
114 in-out property <[TileData]> memory_tiles: [
115 { image: @image-url("icons/at.png") },
116 // ANCHOR_END: mainwindow_interface
117 { image: @image-url("icons/balance-scale.png") },
118 { image: @image-url("icons/bicycle.png") },
119 { image: @image-url("icons/bus.png") },
120 { image: @image-url("icons/cloud.png") },
121 { image: @image-url("icons/cogs.png") },
122 { image: @image-url("icons/motorcycle.png") },
123 { image: @image-url("icons/video.png") },
124 ];
125 // ANCHOR: tile_click_logic
126 for tile[i] in memory_tiles : MemoryTile {
127 x: mod(i, 4) * 74px;
128 y: floor(i / 4) * 74px;
129 width: 64px;
130 height: 64px;
131 icon: tile.image;
132 open_curtain: tile.image_visible || tile.solved;
133 // propagate the solved status from the model to the tile
134 solved: tile.solved;
135 clicked => {
136 // old: tile.image_visible = !tile.image_visible;
137 // new:
138 if (!root.disable_tiles) {
139 tile.image_visible = !tile.image_visible;
140 root.check_if_pair_solved();
141 }
142 }
143 }
144 // ANCHOR_END: tile_click_logic
145 }
146}
147