Show the username that played received move

This commit is contained in:
Artlef 2020-05-23 22:36:24 +02:00
parent c692be6159
commit ee7d52f401
3 changed files with 67 additions and 25 deletions

View File

@ -1,5 +1,5 @@
extern crate ctrlc; extern crate ctrlc;
use clichess::{RecvPositionError, UserRole, EXIT_MSG}; use clichess::{GameInfo, RecvPositionError, UserRole, EXIT_MSG};
use serde_json::json; use serde_json::json;
use shakmaty::fen::Fen; use shakmaty::fen::Fen;
use shakmaty::{Chess, Color, Outcome, Position, Setup}; use shakmaty::{Chess, Color, Outcome, Position, Setup};
@ -15,6 +15,7 @@ struct Client {
side: Color, side: Color,
input_buffer: Arc<Mutex<String>>, input_buffer: Arc<Mutex<String>>,
server_message_recv: Receiver<String>, server_message_recv: Receiver<String>,
opponent_name: Option<String>,
} }
fn main() { fn main() {
@ -46,6 +47,7 @@ fn main() {
side: Color::White, side: Color::White,
input_buffer: input_buffer.clone(), input_buffer: input_buffer.clone(),
server_message_recv, server_message_recv,
opponent_name: Option::None,
}; };
match prompt_user_for_role(&client, &mut stream) { match prompt_user_for_role(&client, &mut stream) {
@ -69,6 +71,10 @@ fn main() {
} }
let mut current_position = fetch_initial_chess_position(&client); let mut current_position = fetch_initial_chess_position(&client);
loop { loop {
client
.opponent_name
.clone()
.map(|name| println!("{} played", &name[1..(name.len() - 1)]));
println!( println!(
"{}", "{}",
clichess::board_representation(&current_position, client.side) clichess::board_representation(&current_position, client.side)
@ -86,7 +92,7 @@ fn main() {
} }
} }
//update position after playing. //update position after playing.
match get_current_position(&client) { match get_current_position(&mut client) {
Ok(position) => current_position = position, Ok(position) => current_position = position,
Err(_) => { Err(_) => {
clichess::write_to_stream(&mut stream, String::from(EXIT_MSG)).unwrap(); clichess::write_to_stream(&mut stream, String::from(EXIT_MSG)).unwrap();
@ -150,7 +156,7 @@ fn read_user_input(client: &Client) -> String {
let mut user_input = client.input_buffer.lock().unwrap(); let mut user_input = client.input_buffer.lock().unwrap();
user_input.clear(); user_input.clear();
} }
let mut input = String::new(); let input;
loop { loop {
thread::sleep(time::Duration::from_millis(10)); thread::sleep(time::Duration::from_millis(10));
{ {
@ -167,17 +173,21 @@ fn read_user_input(client: &Client) -> String {
} }
//wait for next position from server, then return the current board. //wait for next position from server, then return the current board.
fn get_current_position(client: &Client) -> Result<Chess, RecvPositionError> { fn get_current_position(client: &mut Client) -> Result<Chess, RecvPositionError> {
let response = fetch_message_from_server(client); let response = fetch_message_from_server(client);
let game_info: GameInfo = serde_json::from_str(&response).unwrap();
if game_info.opponent_name != "" {
client.opponent_name = Some(game_info.opponent_name);
}
if response.is_empty() { if response.is_empty() {
Err(RecvPositionError::UserCanceledError) Err(RecvPositionError::UserCanceledError)
} else { } else {
Ok(parse_position(&response)) Ok(parse_position(&game_info.game_fen))
} }
} }
fn fetch_message_from_server(client: &Client) -> String { fn fetch_message_from_server(client: &Client) -> String {
let mut response = String::new(); let response;
loop { loop {
thread::sleep(time::Duration::from_millis(10)); thread::sleep(time::Duration::from_millis(10));
{ {

View File

@ -1,5 +1,5 @@
use clichess; use clichess;
use clichess::{Player, RecvPositionError, UserRole, EXIT_MSG}; use clichess::{GameInfo, Player, RecvPositionError, UserRole, EXIT_MSG};
use serde_json::Value; use serde_json::Value;
use shakmaty::{fen, Chess, Color, Setup}; use shakmaty::{fen, Chess, Color, Setup};
use std::collections::HashMap; use std::collections::HashMap;
@ -14,10 +14,11 @@ use std::thread;
struct Server { struct Server {
id: usize, id: usize,
chess_position: Arc<Mutex<Chess>>, chess_position: Arc<Mutex<Chess>>,
players: Arc<Mutex<HashMap<usize, (Player, Sender<String>, Arc<(Mutex<bool>, Condvar)>)>>>, players: Arc<Mutex<HashMap<usize, (Player, Sender<GameInfo>, Arc<(Mutex<bool>, Condvar)>)>>>,
others_serv_msg_recv: Receiver<String>, others_serv_msg_recv: Receiver<GameInfo>,
client_message_recv: Receiver<String>, client_message_recv: Receiver<String>,
cvar: Arc<(Mutex<bool>, Condvar)>, cvar: Arc<(Mutex<bool>, Condvar)>,
opponent_name: Option<String>,
} }
fn main() { fn main() {
@ -36,16 +37,17 @@ fn main() {
let client_message_recv = let client_message_recv =
setup_client_message_recv(&stream, condvar_pair.clone()).unwrap(); setup_client_message_recv(&stream, condvar_pair.clone()).unwrap();
let (others_serv_msg_sender, others_serv_msg_recv) = channel(); let (others_serv_msg_sender, others_serv_msg_recv) = channel();
let server = Server { let mut server = Server {
id: counter, id: counter,
chess_position: chess.clone(), chess_position: chess.clone(),
players: players.clone(), players: players.clone(),
others_serv_msg_recv, others_serv_msg_recv,
client_message_recv, client_message_recv,
cvar: condvar_pair, cvar: condvar_pair,
opponent_name: Option::None,
}; };
/* connection succeeded */ /* connection succeeded */
thread::spawn(move || handle_player(stream, server, others_serv_msg_sender)); thread::spawn(move || handle_player(stream, &mut server, others_serv_msg_sender));
counter += 1; counter += 1;
} }
Err(err) => { Err(err) => {
@ -56,9 +58,13 @@ fn main() {
} }
} }
fn handle_player(mut stream: UnixStream, server: Server, others_serv_msg_sender: Sender<String>) { fn handle_player(
mut stream: UnixStream,
server: &mut Server,
others_serv_msg_sender: Sender<GameInfo>,
) {
match initialize_client(&mut stream, &server, others_serv_msg_sender) { match initialize_client(&mut stream, &server, others_serv_msg_sender) {
Ok((player, player_turn)) => main_loop(&mut stream, &server, player, player_turn), Ok((player, player_turn)) => main_loop(&mut stream, server, player, player_turn),
Err(e) => println!("User id {} could not be initialized: {}", server.id, e), Err(e) => println!("User id {} could not be initialized: {}", server.id, e),
}; };
player_disconnected(&server); player_disconnected(&server);
@ -67,7 +73,7 @@ fn handle_player(mut stream: UnixStream, server: Server, others_serv_msg_sender:
fn initialize_client( fn initialize_client(
stream: &mut UnixStream, stream: &mut UnixStream,
server: &Server, server: &Server,
others_serv_msg_sender: Sender<String>, others_serv_msg_sender: Sender<GameInfo>,
) -> Result<(Player, Color), RecvPositionError> { ) -> Result<(Player, Color), RecvPositionError> {
//create player //create player
let player = create_player(server, stream, others_serv_msg_sender)?; let player = create_player(server, stream, others_serv_msg_sender)?;
@ -86,7 +92,7 @@ fn initialize_client(
Ok((player, player_turn)) Ok((player, player_turn))
} }
fn main_loop(stream: &mut UnixStream, server: &Server, player: Player, mut player_turn: Color) { fn main_loop(stream: &mut UnixStream, server: &mut Server, player: Player, mut player_turn: Color) {
loop { loop {
if clichess::is_player_turn(&player, player_turn) { if clichess::is_player_turn(&player, player_turn) {
//let go of the lock while waiting for user input. //let go of the lock while waiting for user input.
@ -110,36 +116,55 @@ fn main_loop(stream: &mut UnixStream, server: &Server, player: Player, mut playe
Ok(played_chess) => *chess = played_chess, Ok(played_chess) => *chess = played_chess,
Err(e) => println!("Error: {}", e), Err(e) => println!("Error: {}", e),
}; };
let chessfen = fen::fen(&*chess); let game_info_to_send = GameInfo {
game_fen: fen::fen(&*chess),
opponent_name: players
.get(&server.id)
.expect("current server is in the server list")
.0
.username
.clone(),
};
for (id, (_, others_serv_msg_sender, cvar_pair)) in players.iter() { for (id, (_, others_serv_msg_sender, cvar_pair)) in players.iter() {
if server.id != *id { if server.id != *id {
others_serv_msg_sender.send(chessfen.clone()); others_serv_msg_sender
.send(game_info_to_send.clone())
.unwrap();
let (lock, cvar) = &**cvar_pair; let (lock, cvar) = &**cvar_pair;
let mut message_sent = lock.lock().unwrap(); let mut message_sent = lock.lock().unwrap();
*message_sent = true; *message_sent = true;
cvar.notify_one(); cvar.notify_one();
} }
} }
if clichess::write_to_stream(stream, chessfen).is_err() { if clichess::write_to_stream(
stream,
serde_json::to_string(&GameInfo {
game_fen: fen::fen(&*chess),
opponent_name: server.opponent_name.clone().unwrap_or_default(),
})
.unwrap(),
)
.is_err()
{
break; break;
} }
player_turn = chess.turn(); player_turn = chess.turn();
} }
} else { } else {
let position_as_fen_result = wait_for_opponent_move(server); let game_info_result = wait_for_opponent_move(server);
if position_as_fen_result.is_err() { if game_info_result.is_err() {
break; break;
} }
let position_as_fen = position_as_fen_result.unwrap(); let game_info = game_info_result.unwrap();
println!("server id: {}, sending {}", server.id, position_as_fen); clichess::write_to_stream(stream, serde_json::to_string(&game_info).unwrap()).unwrap();
clichess::write_to_stream(stream, position_as_fen.clone()).unwrap(); server.opponent_name = Some(game_info.opponent_name);
let chess = server.chess_position.lock().unwrap(); let chess = server.chess_position.lock().unwrap();
player_turn = chess.turn(); player_turn = chess.turn();
} }
} }
} }
fn wait_for_opponent_move(server: &Server) -> Result<String, RecvPositionError> { fn wait_for_opponent_move(server: &Server) -> Result<GameInfo, RecvPositionError> {
println!("server id: {}, waiting for move to send...", server.id); println!("server id: {}, waiting for move to send...", server.id);
//wait: either we receive next position from other server threads, or we receive //wait: either we receive next position from other server threads, or we receive
//"exit" from the client. //"exit" from the client.
@ -179,7 +204,7 @@ fn wait_for_opponent_move(server: &Server) -> Result<String, RecvPositionError>
fn create_player( fn create_player(
server: &Server, server: &Server,
stream: &mut UnixStream, stream: &mut UnixStream,
others_serv_msg_sender: Sender<String>, others_serv_msg_sender: Sender<GameInfo>,
) -> Result<Player, RecvPositionError> { ) -> Result<Player, RecvPositionError> {
println!("Creating player {}...", server.id); println!("Creating player {}...", server.id);
//get player name and pubkey //get player name and pubkey

View File

@ -1,4 +1,5 @@
use colored::Colorize; use colored::Colorize;
use serde::{Deserialize, Serialize};
use shakmaty::san::ParseSanError; use shakmaty::san::ParseSanError;
use shakmaty::san::San; use shakmaty::san::San;
use shakmaty::san::SanError; use shakmaty::san::SanError;
@ -20,6 +21,12 @@ pub struct Player {
pub public_key: String, pub public_key: String,
} }
#[derive(Serialize, Deserialize, Clone)]
pub struct GameInfo {
pub game_fen: String,
pub opponent_name: String,
}
#[derive(PartialEq, Copy, Clone)] #[derive(PartialEq, Copy, Clone)]
pub enum UserRole { pub enum UserRole {
White, White,