Sync scores between players
This commit is contained in:
@@ -51,6 +51,8 @@ pub enum ServerMessage {
|
|||||||
PlayerTurn(usize),
|
PlayerTurn(usize),
|
||||||
/// Update the current hand of the player
|
/// Update the current hand of the player
|
||||||
SyncHand(Vec<TileRef>),
|
SyncHand(Vec<TileRef>),
|
||||||
|
/// Update the score of the n-th player.
|
||||||
|
SyncScore(usize, u32),
|
||||||
/// Informs that a tile has been placed
|
/// Informs that a tile has been placed
|
||||||
TilePlaced(Position2dRef, TileRef),
|
TilePlaced(Position2dRef, TileRef),
|
||||||
/// Informs that a tile has been removed
|
/// Informs that a tile has been removed
|
||||||
|
@@ -6,6 +6,7 @@ use board_shared::deck::RngDeck;
|
|||||||
use board_shared::expr::is_valid_guess;
|
use board_shared::expr::is_valid_guess;
|
||||||
use board_shared::game::Hand;
|
use board_shared::game::Hand;
|
||||||
use board_shared::position::Position2d;
|
use board_shared::position::Position2d;
|
||||||
|
use board_shared::score::calc_score;
|
||||||
use board_shared::tile::Tile;
|
use board_shared::tile::Tile;
|
||||||
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
@@ -189,6 +190,7 @@ impl Room {
|
|||||||
.hand
|
.hand
|
||||||
.complete(&mut self.deck)
|
.complete(&mut self.deck)
|
||||||
.ok();
|
.ok();
|
||||||
|
self.on_validated_move(self.active_player, &diff);
|
||||||
self.next_player();
|
self.next_player();
|
||||||
} else {
|
} else {
|
||||||
self.send(
|
self.send(
|
||||||
@@ -198,6 +200,23 @@ impl Room {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_validated_move(&mut self, player_id: usize, diff: &[Position2d]) {
|
||||||
|
let tiles_placed = diff
|
||||||
|
.iter()
|
||||||
|
.map(|&pos| {
|
||||||
|
self.board
|
||||||
|
.get(pos.x, pos.y)
|
||||||
|
.expect("A placed tile should not be empty.")
|
||||||
|
})
|
||||||
|
.collect::<Vec<Tile>>();
|
||||||
|
self.players[player_id].score += calc_score(&tiles_placed);
|
||||||
|
self.broadcast(ServerMessage::SyncScore(
|
||||||
|
player_id,
|
||||||
|
self.players[player_id].score,
|
||||||
|
));
|
||||||
|
self.validated_board = self.board.clone();
|
||||||
|
}
|
||||||
|
|
||||||
fn reset_player_moves(&mut self) {
|
fn reset_player_moves(&mut self) {
|
||||||
let diff = self.board.difference(&self.validated_board);
|
let diff = self.board.difference(&self.validated_board);
|
||||||
for pos in diff {
|
for pos in diff {
|
||||||
|
@@ -7,4 +7,5 @@ pub mod game;
|
|||||||
mod lexer;
|
mod lexer;
|
||||||
mod parser;
|
mod parser;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
|
pub mod score;
|
||||||
pub mod tile;
|
pub mod tile;
|
||||||
|
79
board-shared/src/score.rs
Normal file
79
board-shared/src/score.rs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
use crate::tile::{Operator, Tile};
|
||||||
|
|
||||||
|
/// Calculate the score for a given list of tiles.
|
||||||
|
pub fn calc_score(tiles: &[Tile]) -> u32 {
|
||||||
|
tiles
|
||||||
|
.split(|tile| matches!(tile, Tile::Equals))
|
||||||
|
.map(calc_expression_score)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_expression_score(tiles: &[Tile]) -> u32 {
|
||||||
|
let mut digit_score = 0u32;
|
||||||
|
let mut multiplier = 1u32;
|
||||||
|
for token in tiles {
|
||||||
|
match token {
|
||||||
|
Tile::Digit(_) => digit_score += 1,
|
||||||
|
Tile::Operator(op) => {
|
||||||
|
match op {
|
||||||
|
Operator::Add | Operator::Subtract => multiplier = 2,
|
||||||
|
Operator::Multiply => multiplier = 3,
|
||||||
|
Operator::Divide => digit_score += 10,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
digit_score * multiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::tile::Digit;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn only_digits() {
|
||||||
|
assert_eq!(
|
||||||
|
calc_score(&[
|
||||||
|
Tile::Digit(Digit::new(7)),
|
||||||
|
Tile::Digit(Digit::new(8)),
|
||||||
|
Tile::Equals,
|
||||||
|
Tile::Digit(Digit::new(9)),
|
||||||
|
Tile::Digit(Digit::new(4)),
|
||||||
|
]),
|
||||||
|
4
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn calc_individually() {
|
||||||
|
assert_eq!(
|
||||||
|
calc_score(&[
|
||||||
|
Tile::Digit(Digit::new(4)),
|
||||||
|
Tile::Operator(Operator::Add),
|
||||||
|
Tile::Digit(Digit::new(5)),
|
||||||
|
Tile::Equals,
|
||||||
|
Tile::Digit(Digit::new(3)),
|
||||||
|
Tile::Operator(Operator::Multiply),
|
||||||
|
Tile::Digit(Digit::new(3)),
|
||||||
|
]),
|
||||||
|
10
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn diviser_add_to_original_sum() {
|
||||||
|
assert_eq!(
|
||||||
|
calc_score(&[
|
||||||
|
Tile::Digit(Digit::new(8)),
|
||||||
|
Tile::Operator(Operator::Divide),
|
||||||
|
Tile::Digit(Digit::new(4)),
|
||||||
|
Tile::Equals,
|
||||||
|
Tile::Digit(Digit::new(2)),
|
||||||
|
]),
|
||||||
|
13
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user