working win game

This commit is contained in:
Arkitu 2025-08-09 14:43:33 +02:00
parent 5a9ac5c436
commit 1d7eaa028b
2 changed files with 65 additions and 27 deletions

View File

@ -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) {

View File

@ -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 {
board: [None; 9],
turn: Some(Team::Zero),
winner: None,
});
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 => {
warn!("Cell played is too big!");
return;
}
Some(Some(_)) => {
warn!("Cell is already taken!");
return;
}
Some(cell) => {
*cell = Some(self.team);
if c >= game.board.len() {
warn!("Cell played is too big!");
return;
}
if game.board[c].is_some() {
warn!("Cell is already taken!");
return;
}
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);
}