working win game
This commit is contained in:
parent
5a9ac5c436
commit
1d7eaa028b
@ -24,12 +24,7 @@ ws.onmessage = (event) => {
|
||||
let msg = JSON.parse(event.data);
|
||||
let cells = [];
|
||||
for (let i = 0; i < 9; i++) {
|
||||
let owner = null;
|
||||
if (((msg.board >> (17 - i)) & 1) == 1) {
|
||||
owner = 0;
|
||||
} else if (((msg.board >> (8 - i)) & 1) == 1) {
|
||||
owner = 1;
|
||||
}
|
||||
let owner = msg.board[i];
|
||||
|
||||
let tagName;
|
||||
if (msg.turn == team && owner === null) {
|
||||
|
@ -16,31 +16,63 @@ use super::App;
|
||||
|
||||
// bits [0; 8] : player zero board / bits [9; 17] : player one board / is_ended [18] / is_draw [19] / winner [20]: 0=blue 1=green / current_turn [21]: 0=blue 1=green
|
||||
|
||||
#[derive(Debug, Serialize, Clone, PartialEq, Eq, Default)]
|
||||
#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
|
||||
struct Game {
|
||||
board: [Option<Team>; 9],
|
||||
turn: Option<Team>,
|
||||
winner: Option<Team>,
|
||||
}
|
||||
static GAME: Mutex<ThreadModeRawMutex, Game> = Mutex::new(Game {
|
||||
impl Game {
|
||||
const fn default() -> Self {
|
||||
Game {
|
||||
board: [None; 9],
|
||||
turn: Some(Team::Zero),
|
||||
winner: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
fn check_end(&mut self) -> bool {
|
||||
for [a, b, c] in [
|
||||
[0, 1, 2],
|
||||
[3, 4, 5],
|
||||
[6, 7, 8],
|
||||
[0, 3, 6],
|
||||
[1, 4, 7],
|
||||
[2, 5, 8],
|
||||
[0, 4, 8],
|
||||
[2, 4, 6],
|
||||
] {
|
||||
if let Some(t) = self.board[a] {
|
||||
if self.board[b] == Some(t) && self.board[c] == Some(t) {
|
||||
self.winner = Some(t);
|
||||
self.turn = None;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
static GAME: Mutex<ThreadModeRawMutex, Game> = Mutex::new(Game::default());
|
||||
|
||||
// {"board"=[null,null,null,null,null,null,null,null,null],"turn"=null,"winner":null}
|
||||
|
||||
pub struct TttApp {
|
||||
team: Team,
|
||||
last_game: Game,
|
||||
end: Option<(Instant, Option<Team>)>,
|
||||
/// Only one socket manages the end, this can be None even when it's the end
|
||||
end: Option<Instant>,
|
||||
json_buf: [u8; 128],
|
||||
}
|
||||
impl TttApp {
|
||||
pub fn new(team: Team) -> Self {
|
||||
Self {
|
||||
team,
|
||||
last_game: Game::default(),
|
||||
last_game: Game {
|
||||
board: [None; 9],
|
||||
turn: None,
|
||||
winner: None,
|
||||
},
|
||||
end: None,
|
||||
json_buf: [0; 128],
|
||||
}
|
||||
@ -134,24 +166,35 @@ impl App for TttApp {
|
||||
ws.send(WsMsg::Ping(&[])).await?;
|
||||
info!("ping");
|
||||
}
|
||||
if self.end.map(|e| e.elapsed()).unwrap_or_default() > Duration::from_secs(5) {
|
||||
self.end = None;
|
||||
*game = Game {
|
||||
turn: Some(!unwrap_opt(game.winner).await),
|
||||
..Game::default()
|
||||
};
|
||||
}
|
||||
while let Some(r) = ws.rcv().await? {
|
||||
info!("{:?}", r);
|
||||
if let WsMsg::Bytes([c]) = r {
|
||||
let c = *c;
|
||||
let c = *c as usize;
|
||||
info!("c={}", c);
|
||||
if c > 8 {}
|
||||
match game.board.get_mut(c as usize) {
|
||||
None => {
|
||||
if c >= game.board.len() {
|
||||
warn!("Cell played is too big!");
|
||||
return;
|
||||
}
|
||||
Some(Some(_)) => {
|
||||
if game.board[c].is_some() {
|
||||
warn!("Cell is already taken!");
|
||||
return;
|
||||
}
|
||||
Some(cell) => {
|
||||
*cell = Some(self.team);
|
||||
if game.turn == Some(self.team) {
|
||||
game.board[c] = Some(self.team);
|
||||
game.turn = Some(!self.team);
|
||||
if game.check_end() {
|
||||
self.end = Some(Instant::now());
|
||||
}
|
||||
} else {
|
||||
warn!("It's not your turn!");
|
||||
return;
|
||||
}
|
||||
info!("{:#?}", game);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user