Send the complete board when joining a room
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
use crate::types::{Position2dRef, TileRef};
|
use crate::types::{BoardRef, Position2dRef, TileRef};
|
||||||
use board_shared::{position::Position2d, tile::Tile};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A message sent by the client to the server.
|
/// A message sent by the client to the server.
|
||||||
@@ -20,9 +19,9 @@ pub enum ClientMessage {
|
|||||||
/// Try to place a tile from the hand on the board.
|
/// Try to place a tile from the hand on the board.
|
||||||
///
|
///
|
||||||
/// The server will validate the move and answer with a TilePlaced if the message is valid.
|
/// The server will validate the move and answer with a TilePlaced if the message is valid.
|
||||||
TileUse(#[serde(with = "Position2dRef")] Position2d, usize),
|
TileUse(Position2dRef, usize),
|
||||||
/// Try to remove a tile from the board to add it to the hand.
|
/// Try to remove a tile from the board to add it to the hand.
|
||||||
TileTake(#[serde(with = "Position2dRef")] Position2d),
|
TileTake(Position2dRef),
|
||||||
/// Get the server to validate the current player moves.
|
/// Get the server to validate the current player moves.
|
||||||
Validate,
|
Validate,
|
||||||
}
|
}
|
||||||
@@ -34,6 +33,7 @@ pub enum ServerMessage {
|
|||||||
JoinedRoom {
|
JoinedRoom {
|
||||||
room_name: String,
|
room_name: String,
|
||||||
players: Vec<(String, u32, bool)>,
|
players: Vec<(String, u32, bool)>,
|
||||||
|
board: BoardRef,
|
||||||
active_player: usize,
|
active_player: usize,
|
||||||
has_started: bool,
|
has_started: bool,
|
||||||
},
|
},
|
||||||
@@ -48,13 +48,10 @@ pub enum ServerMessage {
|
|||||||
/// Change the current player
|
/// Change the current player
|
||||||
PlayerTurn(usize),
|
PlayerTurn(usize),
|
||||||
/// Update the current hand of the player
|
/// Update the current hand of the player
|
||||||
SyncHand(#[serde(with = "TileRef")] Tile), // TODO: Vec<Tile>
|
SyncHand(Vec<TileRef>),
|
||||||
/// Informs that a tile has been placed
|
/// Informs that a tile has been placed
|
||||||
TilePlaced(
|
TilePlaced(Position2dRef, TileRef),
|
||||||
#[serde(with = "Position2dRef")] Position2d,
|
|
||||||
#[serde(with = "TileRef")] Tile,
|
|
||||||
),
|
|
||||||
/// Informs that a tile has been removed
|
/// Informs that a tile has been removed
|
||||||
TileRemoved(#[serde(with = "Position2dRef")] Position2d),
|
TileRemoved(Position2dRef),
|
||||||
TurnRejected(String),
|
TurnRejected(String),
|
||||||
}
|
}
|
||||||
|
@@ -1,17 +1,25 @@
|
|||||||
use board_shared::position::Position2d;
|
use board_shared::{
|
||||||
use board_shared::tile::{Digit, Operator, Tile};
|
board::Board,
|
||||||
|
position::{Grid2d, Position2d},
|
||||||
|
tile::{Digit, Operator, Tile},
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(remote = "Tile")]
|
pub struct BoardRef {
|
||||||
|
pub tiles: Vec<Option<TileRef>>,
|
||||||
|
pub width: usize,
|
||||||
|
pub height: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum TileRef {
|
pub enum TileRef {
|
||||||
Digit(#[serde(with = "DigitRef")] Digit),
|
Digit(DigitRef),
|
||||||
Operator(#[serde(with = "OperatorRef")] Operator),
|
Operator(OperatorRef),
|
||||||
Equals,
|
Equals,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(remote = "Digit")]
|
|
||||||
pub struct DigitRef {
|
pub struct DigitRef {
|
||||||
pub value: i8,
|
pub value: i8,
|
||||||
pub has_left_parenthesis: bool,
|
pub has_left_parenthesis: bool,
|
||||||
@@ -19,7 +27,6 @@ pub struct DigitRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(remote = "Operator")]
|
|
||||||
pub enum OperatorRef {
|
pub enum OperatorRef {
|
||||||
Add,
|
Add,
|
||||||
Subtract,
|
Subtract,
|
||||||
@@ -28,8 +35,69 @@ pub enum OperatorRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
#[serde(remote = "Position2d")]
|
|
||||||
pub struct Position2dRef {
|
pub struct Position2dRef {
|
||||||
pub x: usize,
|
pub x: usize,
|
||||||
pub y: usize,
|
pub y: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&Board> for BoardRef {
|
||||||
|
fn from(value: &Board) -> Self {
|
||||||
|
Self {
|
||||||
|
tiles: value
|
||||||
|
.iter()
|
||||||
|
.map(|tile| tile.map(Into::into))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
width: value.width(),
|
||||||
|
height: value.height(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Tile> for TileRef {
|
||||||
|
fn from(value: Tile) -> Self {
|
||||||
|
match value {
|
||||||
|
Tile::Digit(digit) => TileRef::Digit(digit.into()),
|
||||||
|
Tile::Operator(operator) => TileRef::Operator(operator.into()),
|
||||||
|
Tile::Equals => TileRef::Equals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Digit> for DigitRef {
|
||||||
|
fn from(value: Digit) -> Self {
|
||||||
|
Self {
|
||||||
|
value: value.value,
|
||||||
|
has_left_parenthesis: value.has_left_parenthesis,
|
||||||
|
has_right_parenthesis: value.has_right_parenthesis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Operator> for OperatorRef {
|
||||||
|
fn from(value: Operator) -> Self {
|
||||||
|
match value {
|
||||||
|
Operator::Add => OperatorRef::Add,
|
||||||
|
Operator::Subtract => OperatorRef::Subtract,
|
||||||
|
Operator::Multiply => OperatorRef::Multiply,
|
||||||
|
Operator::Divide => OperatorRef::Divide,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Position2d> for Position2dRef {
|
||||||
|
fn from(value: Position2d) -> Self {
|
||||||
|
Self {
|
||||||
|
x: value.x,
|
||||||
|
y: value.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Position2dRef> for Position2d {
|
||||||
|
fn from(value: Position2dRef) -> Self {
|
||||||
|
Self {
|
||||||
|
x: value.x,
|
||||||
|
y: value.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -71,6 +71,7 @@ impl Room {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|p| (p.name.clone(), p.score, p.ws.is_some()))
|
.map(|p| (p.name.clone(), p.score, p.ws.is_some()))
|
||||||
.collect(),
|
.collect(),
|
||||||
|
board: (&self.board).into(),
|
||||||
active_player: self.active_player,
|
active_player: self.active_player,
|
||||||
has_started: self.has_started,
|
has_started: self.has_started,
|
||||||
})?;
|
})?;
|
||||||
@@ -103,7 +104,7 @@ impl Room {
|
|||||||
ClientMessage::TileUse(pos, tile_idx) => {
|
ClientMessage::TileUse(pos, tile_idx) => {
|
||||||
if let Some(p) = self.connections.get(&addr) {
|
if let Some(p) = self.connections.get(&addr) {
|
||||||
if *p == self.active_player {
|
if *p == self.active_player {
|
||||||
self.on_tile_use(pos, tile_idx);
|
self.on_tile_use(pos.into(), tile_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,7 +177,7 @@ impl Room {
|
|||||||
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 {
|
||||||
self.broadcast(ServerMessage::TileRemoved(pos));
|
self.broadcast(ServerMessage::TileRemoved(pos.into()));
|
||||||
}
|
}
|
||||||
self.board = self.validated_board.clone();
|
self.board = self.validated_board.clone();
|
||||||
}
|
}
|
||||||
|
@@ -134,6 +134,20 @@ impl Board {
|
|||||||
Self::is_aligned(positions, Alignment::Horizontal)
|
Self::is_aligned(positions, Alignment::Horizontal)
|
||||||
|| Self::is_aligned(positions, Alignment::Vertical)
|
|| Self::is_aligned(positions, Alignment::Vertical)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a linear iterator over the tiles, row by row.
|
||||||
|
///
|
||||||
|
/// # Example:
|
||||||
|
/// ```
|
||||||
|
/// use board_shared::board::Board;
|
||||||
|
///
|
||||||
|
/// let board = Board::default();
|
||||||
|
/// let placed_tiles = board.iter().filter(Option::is_some).count();
|
||||||
|
/// assert_eq!(placed_tiles, 0);
|
||||||
|
/// ```
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item = Option<Tile>> + '_ {
|
||||||
|
self.tiles.iter().copied()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Grid2d for Board {
|
impl Grid2d for Board {
|
||||||
|
Reference in New Issue
Block a user