2022-03-10 07:17:16 +00:00
|
|
|
use crate::ai::AIDifficulty;
|
2022-03-07 04:14:57 +00:00
|
|
|
use crate::yew_components::MainMenuMessage;
|
2022-03-02 07:25:01 +00:00
|
|
|
use std::cell::Cell;
|
2022-03-02 08:51:14 +00:00
|
|
|
use std::fmt::Display;
|
2022-03-02 06:18:10 +00:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2022-03-04 07:22:30 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum GameState {
|
|
|
|
MainMenu,
|
2022-03-10 07:17:16 +00:00
|
|
|
SinglePlayer(Turn, AIDifficulty),
|
2022-03-04 07:22:30 +00:00
|
|
|
LocalMultiplayer,
|
2022-03-15 04:16:09 +00:00
|
|
|
NetworkedMultiplayer(Turn),
|
2022-03-09 08:29:53 +00:00
|
|
|
PostGameResults(BoardState),
|
2022-03-04 07:22:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for GameState {
|
|
|
|
fn default() -> Self {
|
|
|
|
GameState::MainMenu
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-07 04:14:57 +00:00
|
|
|
impl From<MainMenuMessage> for GameState {
|
|
|
|
fn from(msg: MainMenuMessage) -> Self {
|
|
|
|
match msg {
|
2022-03-10 07:17:16 +00:00
|
|
|
MainMenuMessage::SinglePlayer(t, ai) => GameState::SinglePlayer(t, ai),
|
2022-03-07 04:14:57 +00:00
|
|
|
MainMenuMessage::LocalMultiplayer => GameState::LocalMultiplayer,
|
2022-03-15 04:16:09 +00:00
|
|
|
MainMenuMessage::NetworkedMultiplayer(t) => GameState::NetworkedMultiplayer(t),
|
2022-03-07 04:14:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-02 06:18:10 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum BoardState {
|
|
|
|
Empty,
|
|
|
|
Cyan,
|
|
|
|
Magenta,
|
2022-03-09 09:10:13 +00:00
|
|
|
CyanWin,
|
|
|
|
MagentaWin,
|
2022-03-02 06:18:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for BoardState {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::Empty
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-02 08:51:14 +00:00
|
|
|
impl Display for BoardState {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
match *self {
|
|
|
|
BoardState::Empty => f.write_str("open"),
|
|
|
|
BoardState::Cyan => f.write_str("cyan"),
|
2022-03-09 09:10:13 +00:00
|
|
|
BoardState::CyanWin => f.write_str("cyan win"),
|
2022-03-02 08:51:14 +00:00
|
|
|
BoardState::Magenta => f.write_str("magenta"),
|
2022-03-09 09:10:13 +00:00
|
|
|
BoardState::MagentaWin => f.write_str("magenta win"),
|
2022-03-02 08:51:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-03 09:01:46 +00:00
|
|
|
impl From<Turn> for BoardState {
|
|
|
|
fn from(t: Turn) -> Self {
|
|
|
|
match t {
|
|
|
|
Turn::CyanPlayer => BoardState::Cyan,
|
|
|
|
Turn::MagentaPlayer => BoardState::Magenta,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BoardState {
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
*self == BoardState::Empty
|
|
|
|
}
|
2022-03-09 09:10:13 +00:00
|
|
|
|
2022-03-10 06:43:03 +00:00
|
|
|
pub fn is_win(self) -> bool {
|
|
|
|
match self {
|
|
|
|
BoardState::Empty | BoardState::Cyan | BoardState::Magenta => false,
|
|
|
|
BoardState::CyanWin | BoardState::MagentaWin => true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-09 09:14:01 +00:00
|
|
|
pub fn into_win(self) -> Self {
|
|
|
|
match self {
|
2022-03-09 09:10:13 +00:00
|
|
|
BoardState::Empty => BoardState::Empty,
|
|
|
|
BoardState::Cyan | BoardState::CyanWin => BoardState::CyanWin,
|
|
|
|
BoardState::Magenta | BoardState::MagentaWin => BoardState::MagentaWin,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 06:43:03 +00:00
|
|
|
pub fn from_win(&self) -> Self {
|
|
|
|
match *self {
|
2022-03-09 09:10:13 +00:00
|
|
|
BoardState::Empty => BoardState::Empty,
|
|
|
|
BoardState::Cyan | BoardState::CyanWin => BoardState::Cyan,
|
2022-03-09 10:29:00 +00:00
|
|
|
BoardState::Magenta | BoardState::MagentaWin => BoardState::Magenta,
|
2022-03-09 09:10:13 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-03 09:01:46 +00:00
|
|
|
}
|
|
|
|
|
2022-03-02 06:18:10 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum Turn {
|
|
|
|
CyanPlayer,
|
|
|
|
MagentaPlayer,
|
|
|
|
}
|
|
|
|
|
2022-03-02 08:51:14 +00:00
|
|
|
impl Display for Turn {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
match *self {
|
|
|
|
Turn::CyanPlayer => f.write_str("CyanPlayer"),
|
|
|
|
Turn::MagentaPlayer => f.write_str("MagentaPlayer"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-03 09:01:46 +00:00
|
|
|
impl From<BoardState> for Turn {
|
|
|
|
fn from(board_state: BoardState) -> Self {
|
|
|
|
match board_state {
|
2022-03-09 09:10:13 +00:00
|
|
|
BoardState::Empty | BoardState::Cyan | BoardState::CyanWin => Turn::CyanPlayer,
|
|
|
|
BoardState::Magenta | BoardState::MagentaWin => Turn::MagentaPlayer,
|
2022-03-03 09:01:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-03 08:36:51 +00:00
|
|
|
impl Turn {
|
|
|
|
pub fn get_color(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
Turn::CyanPlayer => "cyan",
|
|
|
|
Turn::MagentaPlayer => "magenta",
|
|
|
|
}
|
|
|
|
}
|
2022-03-03 09:01:46 +00:00
|
|
|
|
|
|
|
pub fn get_opposite(&self) -> Self {
|
|
|
|
match *self {
|
|
|
|
Turn::CyanPlayer => Turn::MagentaPlayer,
|
|
|
|
Turn::MagentaPlayer => Turn::CyanPlayer,
|
|
|
|
}
|
|
|
|
}
|
2022-03-03 08:36:51 +00:00
|
|
|
}
|
|
|
|
|
2022-03-07 04:12:05 +00:00
|
|
|
pub type BoardType = [Rc<Cell<BoardState>>; 56];
|
|
|
|
|
2022-03-09 08:29:53 +00:00
|
|
|
pub fn new_empty_board() -> BoardType {
|
|
|
|
[
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
Rc::new(Cell::new(BoardState::default())),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2022-03-10 07:39:26 +00:00
|
|
|
pub fn board_deep_clone(board: &BoardType) -> BoardType {
|
|
|
|
let cloned_board = new_empty_board();
|
|
|
|
for i in 0..board.len() {
|
|
|
|
cloned_board[i].replace(board[i].get());
|
|
|
|
}
|
|
|
|
|
|
|
|
cloned_board
|
|
|
|
}
|
|
|
|
|
2022-03-10 06:43:03 +00:00
|
|
|
pub type PlacedType = [Rc<Cell<bool>>; 56];
|
|
|
|
|
|
|
|
pub fn new_placed() -> PlacedType {
|
|
|
|
[
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
Rc::new(Cell::new(false)),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2022-03-02 06:18:10 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub struct SharedState {
|
2022-03-07 04:12:05 +00:00
|
|
|
pub board: BoardType,
|
2022-03-04 07:22:30 +00:00
|
|
|
pub game_state: Rc<Cell<GameState>>,
|
2022-03-02 08:51:14 +00:00
|
|
|
pub turn: Rc<Cell<Turn>>,
|
2022-03-10 06:43:03 +00:00
|
|
|
pub placed: PlacedType,
|
2022-03-02 06:18:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for SharedState {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
// cannot use [<type>; 56] because Rc does not impl Copy
|
2022-03-09 08:29:53 +00:00
|
|
|
board: new_empty_board(),
|
2022-03-04 07:22:30 +00:00
|
|
|
game_state: Rc::new(Cell::new(GameState::default())),
|
2022-03-02 08:51:14 +00:00
|
|
|
turn: Rc::new(Cell::new(Turn::CyanPlayer)),
|
2022-03-10 06:43:03 +00:00
|
|
|
placed: new_placed(),
|
2022-03-02 06:18:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|