138 lines
3.8 KiB
Rust
138 lines
3.8 KiB
Rust
use rand::Rng;
|
|
use std::net::SocketAddr;
|
|
use std::vec;
|
|
use tokio::sync::mpsc::UnboundedSender;
|
|
use tokio_tungstenite::tungstenite::Message;
|
|
|
|
#[derive(PartialEq, Clone)]
|
|
pub enum Color {
|
|
Red,
|
|
Yellow,
|
|
None,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Client {
|
|
pub username: String,
|
|
pub connection: UnboundedSender<Message>,
|
|
pub ready: bool,
|
|
pub color: Color,
|
|
pub current_match: Option<u32>,
|
|
pub round_robin_id: u32,
|
|
pub score: u32,
|
|
pub addr: SocketAddr,
|
|
}
|
|
|
|
impl Client {
|
|
pub fn new(username: String, connection: UnboundedSender<Message>, addr: SocketAddr) -> Client {
|
|
Client {
|
|
username,
|
|
connection,
|
|
ready: false,
|
|
color: Color::None,
|
|
current_match: None,
|
|
round_robin_id: 0,
|
|
score: 0,
|
|
addr,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Match {
|
|
pub id: u32,
|
|
pub board: Vec<Vec<Color>>,
|
|
pub viewers: Vec<SocketAddr>,
|
|
pub ledger: Vec<(Color, usize)>,
|
|
pub move_to_dispatch: (Color, usize),
|
|
pub wait_thread: Option<tokio::task::JoinHandle<()>>,
|
|
pub player1: SocketAddr,
|
|
pub player2: SocketAddr,
|
|
}
|
|
|
|
impl Match {
|
|
pub fn new(id: u32, player1: SocketAddr, player2: SocketAddr) -> Match {
|
|
let first = if rand::rng().random_range(0..=1) == 0 {
|
|
player1.to_string().parse().unwrap()
|
|
} else {
|
|
player2.to_string().parse().unwrap()
|
|
};
|
|
|
|
Match {
|
|
id,
|
|
board: vec![vec![Color::None; 6]; 7],
|
|
viewers: Vec::new(),
|
|
ledger: Vec::new(),
|
|
move_to_dispatch: (Color::None, 0),
|
|
wait_thread: None,
|
|
player1: if player1 == first { player1 } else { player2 },
|
|
player2: if player1 == first { player2 } else { player1 },
|
|
}
|
|
}
|
|
|
|
pub fn place_token(&mut self, color: Color, column: usize) {
|
|
for i in 0..6 {
|
|
if self.board[column][i] == Color::None {
|
|
self.board[column][i] = color;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn end_game_check(&self) -> (Color, bool) {
|
|
let mut result = (Color::None, false);
|
|
|
|
let mut any_empty = true;
|
|
for x in 0..7 {
|
|
for y in 0..6 {
|
|
let color = self.board[x][y].clone();
|
|
let mut horizontal_end = true;
|
|
let mut vertical_end = true;
|
|
let mut diagonal_end_up = true;
|
|
let mut diagonal_end_down = true;
|
|
|
|
if any_empty && color == Color::None {
|
|
any_empty = false;
|
|
}
|
|
|
|
for i in 0..4 {
|
|
if x + i >= 7 || self.board[x + i][y] != color && horizontal_end {
|
|
horizontal_end = false;
|
|
}
|
|
|
|
if y + i >= 6 || self.board[x][y + i] != color && vertical_end {
|
|
vertical_end = false;
|
|
}
|
|
|
|
if x + i >= 7
|
|
|| y + i >= 6
|
|
|| self.board[x + i][y + i] != color && diagonal_end_up
|
|
{
|
|
diagonal_end_up = false;
|
|
}
|
|
|
|
if x + i >= 7
|
|
|| (y as i32 - i as i32) < 0
|
|
|| self.board[x + i][y - i] != color && diagonal_end_down
|
|
{
|
|
diagonal_end_down = false;
|
|
}
|
|
}
|
|
|
|
if horizontal_end || vertical_end || diagonal_end_up || diagonal_end_down {
|
|
result = (color.clone(), false);
|
|
break;
|
|
}
|
|
}
|
|
if result.0 != Color::None {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if any_empty && result.0 == Color::None {
|
|
result.1 = true;
|
|
}
|
|
|
|
result
|
|
}
|
|
}
|