Fixed recursion issue, enabled right click to flag

This commit is contained in:
Guilleag01
2023-08-07 13:59:48 +02:00
parent 9172002c34
commit b378932dd1
7 changed files with 87 additions and 60 deletions

View File

@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// use serde_wasm_bindgen::to_value; // use serde_wasm_bindgen::to_value;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
// use web_sys::EventTarget; use web_sys::AddEventListenerOptions;
// use wasm_bindgen_futures::spawn_local; // use wasm_bindgen_futures::spawn_local;
use yew::{prelude::*, html::Scope}; use yew::{prelude::*, html::Scope};
@@ -19,7 +19,8 @@ extern "C" {
} }
pub enum Msg { pub enum Msg {
Discover{cell: Cell} Discover{ cell: Cell },
Flag{ cell: Cell }
} }
pub struct App { pub struct App {
@@ -33,10 +34,12 @@ impl Component for App {
type Properties = (); type Properties = ();
fn create(ctx: &Context<Self>) -> Self { fn create(ctx: &Context<Self>) -> Self {
let mut game = Game::new(10, 10, 10); let height = 100;
game.start_board(); let width = 41;
let num_mines =(height * width / 10) as usize;
// info!("\n{}", game.get_board().to_string()); let mut game = Game::new(height, width, num_mines);
game.start_board();
Self { Self {
link: ctx.link().clone(), link: ctx.link().clone(),
@@ -46,10 +49,12 @@ impl Component for App {
fn view(&self, ctx: &Context<Self>) -> Html { fn view(&self, ctx: &Context<Self>) -> Html {
let b = self.game.get_board().clone(); let b = self.game.get_board().clone();
html!{ html!{
<main class="container"> <main class="container">
<BoardComponent onsignal={self.link.callback(|cell| Msg::Discover{cell})} board={b}/> // Disable context menu
// <button class="restart-button">Restart</button>
<script>{"document.addEventListener('contextmenu', event => event.preventDefault());"}</script>
<BoardComponent onsignal={self.link.callback(|cell| Msg::Discover{cell})} flagsignal={self.link.callback(|cell| Msg::Flag{cell})} board={b}/>
</main> </main>
} }
} }
@@ -57,11 +62,10 @@ impl Component for App {
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool { fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg { match msg {
Msg::Discover {cell} => { Msg::Discover {cell} => {
// info!("Pos (from App): {}", format!("{:?}", cell.get_pos()));
self.game.show(cell.get_pos()); self.game.show(cell.get_pos());
},
// info!("celhid (from App): {}", format!("{:?}", self.game.get_cell(cell.get_pos()).is_hidden())); Msg::Flag {cell} => {
// info!("\n{}", self.game.get_board().to_string()) self.game.set_flag(cell.get_pos(), !self.game.get_cell(cell.get_pos()).is_flagged());
} }
} }
true true

View File

@@ -10,17 +10,20 @@ use wasm_bindgen::JsValue;
pub struct BoardComponent { pub struct BoardComponent {
link: Scope<Self>, link: Scope<Self>,
board: Board, board: Board,
onsignal: Callback<Cell> onsignal: Callback<Cell>,
flagsignal: Callback<Cell>
} }
pub enum Msg { pub enum Msg {
Discover{ cell: Cell }, Discover{ cell: Cell },
Flag{ cell: Cell }
} }
#[derive(Clone, PartialEq, Properties)] #[derive(Clone, PartialEq, Properties)]
pub struct Props { pub struct Props {
pub board: Board, pub board: Board,
pub onsignal: Callback<Cell>, pub onsignal: Callback<Cell>,
pub flagsignal: Callback<Cell>
} }
impl Component for BoardComponent { impl Component for BoardComponent {
@@ -32,7 +35,8 @@ impl Component for BoardComponent {
Self { Self {
link: ctx.link().clone(), link: ctx.link().clone(),
board: ctx.props().board.clone(), board: ctx.props().board.clone(),
onsignal: ctx.props().onsignal.clone() onsignal: ctx.props().onsignal.clone(),
flagsignal: ctx.props().flagsignal.clone()
} }
} }
@@ -47,7 +51,7 @@ impl Component for BoardComponent {
<> <>
{row.into_iter().map(|c| { {row.into_iter().map(|c| {
html! { html! {
<Button onsignal={self.link.callback(move |_| Msg::Discover{cell: c})} cell={c}/> <Button onsignal={self.link.callback(move |_| Msg::Discover{cell: c})} flagsignal={self.link.callback(move |_| Msg::Flag{cell: c})} cell={c}/>
} }
}).collect::<Html>()} }).collect::<Html>()}
<br/> <br/>
@@ -61,9 +65,11 @@ impl Component for BoardComponent {
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool { fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg { match msg {
Msg::Discover {cell} => { Msg::Discover {cell} => {
// info!("Pos (from board): {}", format!("{:?}", cell.get_pos()));
self.onsignal.emit(cell); self.onsignal.emit(cell);
} }
Msg::Flag {cell} => {
self.flagsignal.emit(cell);
}
} }
false false
} }

View File

@@ -8,6 +8,7 @@ pub struct Button {
link: Scope<Self>, link: Scope<Self>,
cell: Cell, cell: Cell,
onsignal: Callback<Cell>, onsignal: Callback<Cell>,
flagsignal: Callback<Cell>
} }
pub enum Msg { pub enum Msg {
@@ -19,6 +20,7 @@ pub enum Msg {
pub struct Props { pub struct Props {
pub cell: Cell, pub cell: Cell,
pub onsignal: Callback<Cell>, pub onsignal: Callback<Cell>,
pub flagsignal: Callback<Cell>
} }
impl Component for Button { impl Component for Button {
@@ -29,7 +31,8 @@ impl Component for Button {
Self { Self {
link: ctx.link().clone(), link: ctx.link().clone(),
cell: ctx.props().cell.clone(), cell: ctx.props().cell.clone(),
onsignal: ctx.props().onsignal.clone() onsignal: ctx.props().onsignal.clone(),
flagsignal: ctx.props().flagsignal.clone()
} }
} }
@@ -43,11 +46,25 @@ impl Component for Button {
<button <button
class={if self.cell.is_hidden() {"button-hidden"} else {"button-shown"}} class={if self.cell.is_hidden() {"button-hidden"} else {"button-shown"}}
onclick={self.link.callback(|_| Msg::Clicked)} onclick={self.link.callback(|_| Msg::Clicked)}
// oncontextmenu={self.link.callback(|_| Msg::Clicked)} oncontextmenu={self.link.callback(|e: MouseEvent| {Msg::RightClicked})}
oncontextmenu={self.link.callback(|e: MouseEvent| {drop(e); Msg::RightClicked})}
// style={(if !self.cell.is_hidden() {format!("background-color: #2f2f2f; transition: background-color 0.5s; transition-delay: {}s;", self.cell.get_delay())} else {"".to_string()}).as_str()}
style={style}> style={style}>
{ &self.cell.to_string() } if self.cell.is_flagged() {
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pennant-filled" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M10 2a1 1 0 0 1 .993 .883l.007 .117v.35l8.406 3.736c.752 .335 .79 1.365 .113 1.77l-.113 .058l-8.406 3.735v7.351h1a1 1 0 0 1 .117 1.993l-.117 .007h-4a1 1 0 0 1 -.117 -1.993l.117 -.007h1v-17a1 1 0 0 1 1 -1z" stroke-width="0" fill="#ffffff"></path>
</svg>
} else {
if self.cell.is_mine() && !self.cell.is_hidden(){
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-bomb-filled" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M14.499 3.996a2.2 2.2 0 0 1 1.556 .645l3.302 3.301a2.2 2.2 0 0 1 0 3.113l-.567 .567l.043 .192a8.5 8.5 0 0 1 -3.732 8.83l-.23 .144a8.5 8.5 0 1 1 -2.687 -15.623l.192 .042l.567 -.566a2.2 2.2 0 0 1 1.362 -.636zm-4.499 5.004a4 4 0 0 0 -4 4a1 1 0 0 0 2 0a2 2 0 0 1 2 -2a1 1 0 0 0 0 -2z" stroke-width="0" fill="#ffffff"></path>
<path d="M21 2a1 1 0 0 1 .117 1.993l-.117 .007h-1c0 .83 -.302 1.629 -.846 2.25l-.154 .163l-1.293 1.293a1 1 0 0 1 -1.497 -1.32l.083 -.094l1.293 -1.292c.232 -.232 .375 -.537 .407 -.86l.007 -.14a2 2 0 0 1 1.85 -1.995l.15 -.005h1z" stroke-width="0" fill="#ffffff"></path>
</svg>
} else {
{&self.cell.to_string()}
}
}
// { }
</button> </button>
} }
@@ -56,11 +73,10 @@ impl Component for Button {
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool { fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg { match msg {
Msg::Clicked => { Msg::Clicked => {
// info!("hid (from cell): {}", format!("{:?}", self.cell.is_hidden()));
self.onsignal.emit(self.cell); self.onsignal.emit(self.cell);
} }
Msg::RightClicked => { Msg::RightClicked => {
self.onsignal.emit(self.cell); self.flagsignal.emit(self.cell);
}, },
} }
false false

View File

@@ -83,6 +83,10 @@ impl Board {
pub fn set_delay(&mut self, pos: (usize, usize), delay: f32) { pub fn set_delay(&mut self, pos: (usize, usize), delay: f32) {
self.board[pos.0][pos.1].set_delay(delay) self.board[pos.0][pos.1].set_delay(delay)
} }
pub fn set_flag(&mut self, pos: (usize, usize), flag: bool) {
self.board[pos.0][pos.1].set_flag(flag)
}
} }
impl ToString for Board { impl ToString for Board {

View File

@@ -42,6 +42,7 @@ impl Cell {
pub fn show(&mut self) { pub fn show(&mut self) {
self.hidden = false; self.hidden = false;
self.flagged = false;
} }
pub fn is_hidden(&self) -> bool { pub fn is_hidden(&self) -> bool {
@@ -53,6 +54,10 @@ impl Cell {
} }
pub fn set_flag(&mut self, new_flag: bool) { pub fn set_flag(&mut self, new_flag: bool) {
if !self.hidden {
self.flagged = false;
return;
}
self.flagged = new_flag; self.flagged = new_flag;
} }
@@ -72,11 +77,12 @@ impl ToString for Cell {
return " ".to_string(); return " ".to_string();
} }
if self.is_mine() { if self.is_mine() {
return "*".to_string(); return " ".to_string();
} }
if self.value == 0 { if self.value == 0 {
return " ".to_string(); return " ".to_string();
} }
return self.value.to_string(); return self.value.to_string();
} }
} }

View File

@@ -34,7 +34,6 @@ impl Game {
} }
} }
// Set values
for i in 0..self.board.get_height() { for i in 0..self.board.get_height() {
for j in 0..self.board.get_width() { for j in 0..self.board.get_width() {
self.board.set_value((i, j), self.board.calculate_value((i, j))) self.board.set_value((i, j), self.board.calculate_value((i, j)))
@@ -52,10 +51,11 @@ impl Game {
cells_to_show.push(init_pos); cells_to_show.push(init_pos);
self.board.get_cell(init_pos).set_delay(0.0);
let mut added_cells = 1; let mut added_cells = 1;
while added_cells > 0 { while added_cells > 0 {
// info!("{:?}", cells_to_show.len() - added_cells);
let new_cells = cells_to_show.len() - added_cells; let new_cells = cells_to_show.len() - added_cells;
added_cells = 0; added_cells = 0;
@@ -77,51 +77,41 @@ impl Game {
cells_to_show.push(new_pos); cells_to_show.push(new_pos);
added_cells += 1; added_cells += 1;
} }
self.board.set_delay(new_pos, f32::sqrt(((init_pos.0 as isize - new_pos.0 as isize).pow(2) + (init_pos.1 as isize - new_pos.1 as isize).pow(2)) as f32) * 0.05);
// let delay = f32::sqrt(((init_pos.0 as isize - new_pos.0 as isize).pow(2) + (init_pos.1 as isize - new_pos.1 as isize).pow(2)) as f32) * 0.05;
let delay = self.board.get_cell(pos).get_delay() + 0.05;
self.board.set_delay(new_pos, delay);
self.board.show_cell(new_pos); self.board.show_cell(new_pos);
} }
} }
} }
} }
// for pos in cells_to_show {
// self.board.show_cell(pos);
// }
// self.board.show_cell(pos);
// if self.board.get_value(pos) == 0 {
// for i in -1..=1 {
// for j in -1..=1 {
// if pos.0 as isize + i >= 0 &&
// pos.0 as isize + i < self.get_height() as isize &&
// pos.1 as isize + j >= 0 &&
// pos.1 as isize + j < self.get_width() as isize &&
// self.board.get_cell(((pos.0 as isize + i) as usize , (pos.1 as isize + j) as usize)).is_hidden() {
// self.show(((pos.0 as isize + i) as usize , (pos.1 as isize + j) as usize))
// }
// }
// }
// }
} }
pub fn get_height(&self) -> usize { pub fn get_height(&self) -> usize {
return self.board.get_height(); self.board.get_height()
} }
pub fn get_width(&self) -> usize { pub fn get_width(&self) -> usize {
return self.board.get_width(); self.board.get_width()
} }
pub fn get_board(&self) -> &Board { pub fn get_board(&self) -> &Board {
return &self.board; &self.board
} }
pub fn get_cell(&self, pos: (usize, usize)) -> Cell { pub fn get_cell(&self, pos: (usize, usize)) -> Cell {
self.board.get_cell(pos) self.board.get_cell(pos)
} }
}
pub fn is_flagged(&self, pos: (usize, usize)) -> bool {
self.board.get_cell(pos).is_flagged()
}
pub fn set_flag(&mut self, pos: (usize, usize), flag: bool) {
self.board.set_flag(pos, flag);
}
}

View File

@@ -4,7 +4,7 @@
line-height: 24px; line-height: 24px;
font-weight: 400; font-weight: 400;
/* Verdana , Avenir, Helvetica, Arial, sans-serif */ /* Verdana , Avenir, Helvetica, Arial, sans-serif */
color: #0f0f0f; color: #0f0f0f98;
background-color: #f6f6f6; background-color: #f6f6f6;
font-synthesis: none; font-synthesis: none;
@@ -67,8 +67,9 @@ button {
text-align: center; text-align: center;
border-radius: 8px; border-radius: 8px;
border: 1px solid transparent; border: 1px solid transparent;
font-weight: 500; /* font-weight: 500; */
color: #0f0f0f98; font-size: 25px;
color: rgba(15, 15, 15, 0.0);
background-color: #0f0f0f98; background-color: #0f0f0f98;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
height: 50px; height: 50px;
@@ -84,9 +85,9 @@ button {
text-align: center; text-align: center;
border-radius: 8px; border-radius: 8px;
border: 1px solid transparent; border: 1px solid transparent;
font-size: 20px; font-size: 25px;
font-weight: 500; font-weight: 700;
/* color: #2f2f2f; */ color: #0f0f0f98;
background-color: #2f2f2f; background-color: #2f2f2f;
height: 50px; height: 50px;
width: 50px; width: 50px;