Show the username that played received move
This commit is contained in:
parent
c692be6159
commit
ee7d52f401
@ -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(¤t_position, client.side)
|
clichess::board_representation(¤t_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));
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user