diff options
-rw-r--r-- | assets/index.html | 1 | ||||
-rw-r--r-- | src/main.rs | 8 | ||||
-rw-r--r-- | src/minesweeper.rs | 26 |
3 files changed, 22 insertions, 13 deletions
diff --git a/assets/index.html b/assets/index.html index 7961bde..614ccd0 100644 --- a/assets/index.html +++ b/assets/index.html @@ -27,6 +27,7 @@ <label>public, ie. shown in the lobby <input name="public" type="checkbox" checked></label><br> <label>safe first move (if possible) <input name="allsafe1move" type="checkbox" checked></label><br> <label>revealed borders <input name="rborders" type="checkbox"></label><br> + <label>reveal on lose <input name="revealonlose" type="checkbox" checked></label><br> <label>player limit <input name="limit" type="number" value="32"></label><br> <button id="createbtn">create</button> </fieldset> diff --git a/src/main.rs b/src/main.rs index ce1cd45..7a85e63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -309,7 +309,7 @@ async fn empty_rooms(rooms: &RoomMap) -> Vec<RoomId> { } fn room_from_form(uid: RoomId, rinfo: &HashMap<String,String>, conf: &Conf) -> Result<(types::Room, bool), Rejection> { - if let (Some(w),Some(h),Some(num),Some(denom),public,asfm,rborders,Some(limit)) = ( + if let (Some(w),Some(h),Some(num),Some(denom),public,asfm,rborders,revealol,Some(limit)) = ( rinfo.get("bwidth").and_then(|w| w.parse::<NonZeroUsize>().ok()), rinfo.get("bheight").and_then(|h| h.parse::<NonZeroUsize>().ok()), rinfo.get("mineratio-n").and_then(|n| n.parse::<usize>().ok()), @@ -317,12 +317,16 @@ fn room_from_form(uid: RoomId, rinfo: &HashMap<String,String>, conf: &Conf) -> R rinfo.get("public").map(|s| s == "on").unwrap_or(false), rinfo.get("allsafe1move").map(|s| s == "on").unwrap_or(false), rinfo.get("rborders").map(|s| s == "on").unwrap_or(false), + rinfo.get("revealonlose").map(|s| s == "on").unwrap_or(false), rinfo.get("limit").and_then(|l| l.parse::<NonZeroUsize>().ok()), ) { if w.get()*h.get() > conf.limits.board_area { return Err(warp::reject::custom(BoardTooBig)) } - let board_conf = minesweeper::BoardConf { w, h, mine_ratio: (num,denom), always_safe_first_move: asfm, revealed_borders: rborders }; + let board_conf = minesweeper::BoardConf { + w, h, mine_ratio: (num,denom), + always_safe_first_move: asfm, revealed_borders: rborders, reveal_on_lose: revealol + }; let name = { let n = rinfo.get("rname").unwrap().to_owned(); if n.is_empty() { uid.to_string() } else { n } diff --git a/src/minesweeper.rs b/src/minesweeper.rs index 9b6ac0c..ae4fe18 100644 --- a/src/minesweeper.rs +++ b/src/minesweeper.rs @@ -39,6 +39,7 @@ pub struct BoardConf { pub mine_ratio: (usize,NonZeroUsize), pub always_safe_first_move: bool, pub revealed_borders: bool, + pub reveal_on_lose: bool, } impl std::fmt::Display for BoardConf { @@ -110,6 +111,10 @@ impl Game { } } else if self.phase != Phase::Die && self.board.hidden_tiles == self.board.mine_count { self.phase = Phase::Win; + } else if self.phase == Phase::Die && self.board_conf.reveal_on_lose { + for tile in self.board.data.iter_mut().filter(|x| is_mine(**x)) { + *tile = unhide(*tile); + } } self } @@ -207,11 +212,12 @@ impl Board { let mut queue = vec![pos]; while let Some(pos) = queue.pop() { let off = self.pos_to_off_unchecked(pos); - let mut c = self.data[off]; - if c & HIDDEN_BIT > 0 { - c = self.unhide_offset(off); - if is_mine(c) { return true; } - if c > 0 { continue; } + let c = &mut self.data[off]; + if *c & HIDDEN_BIT > 0 { + *c = unhide(*c); + self.hidden_tiles -= 1; + if is_mine(*c) { return true; } + if *c > 0 { continue; } if let Some(mut adj) = self.neighs(pos) { queue.append(&mut adj); } @@ -248,11 +254,6 @@ impl Board { } } else { false } } - pub fn unhide_offset(&mut self, off: usize) -> u8 { - self.data[off] &= !(HIDDEN_BIT | FLAGGED_BIT); - self.hidden_tiles -= 1; - self.data[off] - } pub fn reveal(mut self, pos: (usize,usize)) -> MoveResult { let lost = self.reveal_in_place(pos); MoveResult(self, lost) @@ -330,7 +331,10 @@ fn pos_u2i(pos: (usize, usize)) -> Option<(isize, isize)> { { Some((x,y)) } else { None } } pub fn is_mine(v: u8) -> bool { - (v & !(FLAGGED_BIT | CORRECT_BIT)) == TILE_NUMBITS + (v & TILE_NUMBITS) == TILE_NUMBITS +} +pub fn unhide(tile: u8) -> u8 { + tile & !(HIDDEN_BIT | FLAGGED_BIT) } |