Ask for role on connection
This commit is contained in:
parent
2cd79b6715
commit
175e8fafe6
@ -2,12 +2,20 @@ extern crate ctrlc;
|
|||||||
use shakmaty::fen::Fen;
|
use shakmaty::fen::Fen;
|
||||||
use shakmaty::{Chess, Color, Outcome, Position, Setup};
|
use shakmaty::{Chess, Color, Outcome, Position, Setup};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time;
|
use std::time;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
struct Client {
|
||||||
|
player: clichess::Player,
|
||||||
|
side: Color,
|
||||||
|
running: Arc<AtomicBool>,
|
||||||
|
input_buffer: Arc<Mutex<String>>,
|
||||||
|
server_message: Arc<Mutex<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
enum RecvPositionError {
|
enum RecvPositionError {
|
||||||
UserCanceledError,
|
UserCanceledError,
|
||||||
@ -19,7 +27,6 @@ fn main() {
|
|||||||
let running = setupctrlc();
|
let running = setupctrlc();
|
||||||
let username = std::env::args().nth(1).expect("no name given");
|
let username = std::env::args().nth(1).expect("no name given");
|
||||||
let public_key = std::env::args().nth(2).expect("no public key given");
|
let public_key = std::env::args().nth(2).expect("no public key given");
|
||||||
println!("Name: {}, Public key: {}", username, public_key);
|
|
||||||
//send username and public key to server
|
//send username and public key to server
|
||||||
let mut stream = match UnixStream::connect("/tmp/clichess.socket") {
|
let mut stream = match UnixStream::connect("/tmp/clichess.socket") {
|
||||||
Ok(sock) => sock,
|
Ok(sock) => sock,
|
||||||
@ -28,39 +35,55 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
clichess::write_to_stream(&mut stream, username).unwrap();
|
let username_pubkey_json = json!({
|
||||||
clichess::write_to_stream(&mut stream, public_key).unwrap();
|
"username": username,
|
||||||
let (client, chess) = get_connection_info_from_stream(&stream);
|
"pubkey": public_key,
|
||||||
//First prompt when connecting to the server
|
});
|
||||||
println!(
|
clichess::write_to_stream(&mut stream, username_pubkey_json.to_string()).unwrap();
|
||||||
"Hello, {} !\n\r You're playing with the {} pieces",
|
|
||||||
client.username,
|
|
||||||
client.role.to_string()
|
|
||||||
);
|
|
||||||
//then we get the initial role of the connected client.
|
|
||||||
let mut current_position = chess;
|
|
||||||
let input_buffer = setup_input_buffer();
|
let input_buffer = setup_input_buffer();
|
||||||
//start a thread to listen to server messages
|
//start a thread to listen to server messages
|
||||||
let server_message = setup_server_message_recv(&stream).unwrap();
|
let server_message = setup_server_message_recv(&stream).unwrap();
|
||||||
|
|
||||||
|
let mut client = Client {
|
||||||
|
player: clichess::Player {
|
||||||
|
role: clichess::UserRole::Spectator,
|
||||||
|
username: username,
|
||||||
|
public_key: public_key,
|
||||||
|
},
|
||||||
|
side: Color::White,
|
||||||
|
running: running.clone(),
|
||||||
|
input_buffer: input_buffer.clone(),
|
||||||
|
server_message: server_message.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let role = prompt_user_for_role(&client, &mut stream);
|
||||||
|
client.player.role = role.clone();
|
||||||
|
println!(
|
||||||
|
"Hello, {} !\n\r You're playing with the {} pieces",
|
||||||
|
client.player.username,
|
||||||
|
client.player.role.to_string()
|
||||||
|
);
|
||||||
|
println!("Fetching initial chess position...");
|
||||||
|
let mut current_position = fetch_initial_chess_position(&client);
|
||||||
loop {
|
loop {
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
clichess::board_representation(¤t_position, clichess::to_color(client.side))
|
clichess::board_representation(¤t_position, client.side)
|
||||||
);
|
);
|
||||||
//check if game is over.
|
//check if game is over.
|
||||||
if current_position.is_game_over() {
|
if current_position.is_game_over() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if clichess::is_player_turn(&client, current_position.turn()) {
|
if clichess::is_player_turn(&client.player, current_position.turn()) {
|
||||||
//it's the user turn, taking user input
|
//it's the user turn, taking user input
|
||||||
let input = read_user_input(running.clone(), input_buffer.clone());
|
let input = read_user_input(&client);
|
||||||
clichess::write_to_stream(&mut stream, String::from(input.trim())).unwrap();
|
clichess::write_to_stream(&mut stream, String::from(input.trim())).unwrap();
|
||||||
if input.trim() == "exit" {
|
if input.trim() == "exit" {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//update position after playing.
|
//update position after playing.
|
||||||
match get_current_position(running.clone(), server_message.clone()) {
|
match get_current_position(&client) {
|
||||||
Ok(position) => current_position = position,
|
Ok(position) => current_position = position,
|
||||||
Err(RecvPositionError::UserCanceledError) => break,
|
Err(RecvPositionError::UserCanceledError) => break,
|
||||||
Err(RecvPositionError::CommunicationError) => break,
|
Err(RecvPositionError::CommunicationError) => break,
|
||||||
@ -135,17 +158,17 @@ fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Arc<Mutex<String
|
|||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_user_input(running: Arc<AtomicBool>, input_buffer: Arc<Mutex<String>>) -> String {
|
fn read_user_input(client: &Client) -> String {
|
||||||
//clear input before waiting for a new one
|
//clear input before waiting for a new one
|
||||||
{
|
{
|
||||||
let mut user_input = 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 mut input = String::new();
|
||||||
while running.load(Ordering::SeqCst) {
|
while client.running.load(Ordering::SeqCst) {
|
||||||
thread::sleep(time::Duration::from_millis(10));
|
thread::sleep(time::Duration::from_millis(10));
|
||||||
{
|
{
|
||||||
let user_input = input_buffer.lock().unwrap();
|
let user_input = client.input_buffer.lock().unwrap();
|
||||||
if user_input.is_empty() {
|
if user_input.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -154,7 +177,7 @@ fn read_user_input(running: Arc<AtomicBool>, input_buffer: Arc<Mutex<String>>) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if running.load(Ordering::SeqCst) {
|
if client.running.load(Ordering::SeqCst) {
|
||||||
input
|
input
|
||||||
} else {
|
} else {
|
||||||
String::from("exit")
|
String::from("exit")
|
||||||
@ -162,15 +185,21 @@ fn read_user_input(running: Arc<AtomicBool>, input_buffer: Arc<Mutex<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(
|
fn get_current_position(client: &Client) -> Result<Chess, RecvPositionError> {
|
||||||
running: Arc<AtomicBool>,
|
let response = fetch_message_from_server(client);
|
||||||
server_message: Arc<Mutex<String>>,
|
if response.is_empty() {
|
||||||
) -> Result<Chess, RecvPositionError> {
|
Err(RecvPositionError::UserCanceledError)
|
||||||
|
} else {
|
||||||
|
Ok(parse_position(&response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_message_from_server(client: &Client) -> String {
|
||||||
let mut response = String::new();
|
let mut response = String::new();
|
||||||
while running.load(Ordering::SeqCst) {
|
while client.running.load(Ordering::SeqCst) {
|
||||||
thread::sleep(time::Duration::from_millis(10));
|
thread::sleep(time::Duration::from_millis(10));
|
||||||
{
|
{
|
||||||
let mut server_response = server_message.lock().unwrap();
|
let mut server_response = client.server_message.lock().unwrap();
|
||||||
if server_response.is_empty() {
|
if server_response.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -180,11 +209,7 @@ fn get_current_position(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if response.is_empty() {
|
response
|
||||||
Err(RecvPositionError::UserCanceledError)
|
|
||||||
} else {
|
|
||||||
Ok(parse_position(&response))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_position(string: &str) -> Chess {
|
fn parse_position(string: &str) -> Chess {
|
||||||
@ -193,19 +218,68 @@ fn parse_position(string: &str) -> Chess {
|
|||||||
position
|
position
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_connection_info_from_stream(stream: &UnixStream) -> (clichess::Client, Chess) {
|
fn prompt_user_for_role(client: &Client, stream: &mut UnixStream) -> clichess::UserRole {
|
||||||
println!("Read lines from stream...");
|
let mut role: clichess::UserRole;
|
||||||
let mut buf = String::new();
|
loop {
|
||||||
let mut reader = BufReader::new(stream);
|
println!("fetching roles from server...");
|
||||||
//first, client as json.
|
let available_roles = fetch_available_roles(client);
|
||||||
reader
|
println!("available roles fetched.");
|
||||||
.read_line(&mut buf)
|
let mut prompt = String::new();
|
||||||
.expect("Server closed connection.");
|
if !available_roles.contains(&clichess::UserRole::White)
|
||||||
let client = serde_json::from_str(&(buf.trim())).unwrap();
|
&& !available_roles.contains(&clichess::UserRole::Black)
|
||||||
buf.clear();
|
{
|
||||||
reader
|
prompt.push_str("You can only spectate this game.");
|
||||||
.read_line(&mut buf)
|
} else if available_roles.contains(&clichess::UserRole::White) {
|
||||||
.expect("Server closed connection.");
|
prompt = String::from("Do you want to play as White (W)");
|
||||||
let chess = parse_position(buf.trim());
|
if available_roles.contains(&clichess::UserRole::White) {
|
||||||
(client, chess)
|
prompt.push_str(", Black (B)");
|
||||||
|
}
|
||||||
|
prompt.push_str(" or Spectate (S)?");
|
||||||
|
} else {
|
||||||
|
prompt = String::from("Do you want to play as Black (B) or Spectate (S)?");
|
||||||
|
}
|
||||||
|
println!("{}", prompt);
|
||||||
|
//wait for user to give a correct answer.
|
||||||
|
let input = String::from(read_user_input(client).trim());
|
||||||
|
match clichess::parse_to_role(&input) {
|
||||||
|
Ok(r) => role = r,
|
||||||
|
Err(e) => {
|
||||||
|
println!("{}", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if !available_roles.contains(&role) {
|
||||||
|
println!("Sorry, this side is not available.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//send info to server
|
||||||
|
println!("Sending choice {} to server", input);
|
||||||
|
clichess::write_to_stream(stream, String::from(input)).unwrap();
|
||||||
|
println!("Sent.");
|
||||||
|
//get confirmation from server
|
||||||
|
println!("Get response from server...");
|
||||||
|
let response = fetch_message_from_server(&client);
|
||||||
|
if response != "OK" {
|
||||||
|
println!(
|
||||||
|
"There was an issue with the server. Maybe your choice is not available anymore?"
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
println!("Ok!");
|
||||||
|
clichess::write_to_stream(stream, String::from("OK")).unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
role
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_initial_chess_position(client: &Client) -> Chess {
|
||||||
|
parse_position(&fetch_message_from_server(client))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_available_roles(client: &Client) -> Vec<clichess::UserRole> {
|
||||||
|
roles_from_str(&fetch_message_from_server(client)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn roles_from_str(s: &str) -> Result<Vec<clichess::UserRole>, String> {
|
||||||
|
s.split(',').map(clichess::parse_to_role).collect()
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use clichess;
|
use clichess;
|
||||||
use clichess::Client;
|
use clichess::Player;
|
||||||
use clichess::UserRole;
|
use clichess::UserRole;
|
||||||
|
use serde_json::Value;
|
||||||
use shakmaty::{fen, Chess, Color, Setup};
|
use shakmaty::{fen, Chess, Color, Setup};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use std::os::unix::net::{UnixListener, UnixStream};
|
use std::os::unix::net::{UnixListener, UnixStream};
|
||||||
use std::sync::{Arc, Condvar, Mutex};
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
|
|
||||||
@ -14,13 +14,13 @@ use std::thread;
|
|||||||
struct Server {
|
struct Server {
|
||||||
id: usize,
|
id: usize,
|
||||||
chess_position: Arc<Mutex<Chess>>,
|
chess_position: Arc<Mutex<Chess>>,
|
||||||
clients: Arc<Mutex<HashMap<usize, (Client, Arc<(Mutex<String>, Condvar)>)>>>,
|
players: Arc<Mutex<HashMap<usize, (Player, Arc<(Mutex<String>, Condvar)>)>>>,
|
||||||
receiving_buffer: Arc<(Mutex<String>, Condvar)>,
|
receiving_buffer: Arc<(Mutex<String>, Condvar)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let chess = Arc::new(Mutex::new(Chess::default()));
|
let chess = Arc::new(Mutex::new(Chess::default()));
|
||||||
let clients = Arc::new(Mutex::new(HashMap::new()));
|
let players = Arc::new(Mutex::new(HashMap::new()));
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
fs::remove_file("/tmp/clichess.socket");
|
fs::remove_file("/tmp/clichess.socket");
|
||||||
|
|
||||||
@ -33,11 +33,11 @@ fn main() {
|
|||||||
let server = Server {
|
let server = Server {
|
||||||
id: counter,
|
id: counter,
|
||||||
chess_position: chess.clone(),
|
chess_position: chess.clone(),
|
||||||
clients: clients.clone(),
|
players: players.clone(),
|
||||||
receiving_buffer: Arc::new((Mutex::new(String::new()), Condvar::new())),
|
receiving_buffer: Arc::new((Mutex::new(String::new()), Condvar::new())),
|
||||||
};
|
};
|
||||||
/* connection succeeded */
|
/* connection succeeded */
|
||||||
thread::spawn(|| handle_client(stream, server));
|
thread::spawn(move || handle_player(stream, server));
|
||||||
counter += 1;
|
counter += 1;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -48,20 +48,13 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_client(mut stream: UnixStream, server: Server) {
|
fn handle_player(mut stream: UnixStream, server: Server) {
|
||||||
//create client
|
//create player
|
||||||
let client = create_client(&server, &stream);
|
let player = create_player(&server, &mut stream);
|
||||||
//send its information to the client
|
|
||||||
println!(
|
|
||||||
"server {}, send first information to the client...",
|
|
||||||
server.id
|
|
||||||
);
|
|
||||||
clichess::write_to_stream(&mut stream, serde_json::to_string(&client).unwrap());
|
|
||||||
println!("server {}, information to the client sent", server.id);
|
|
||||||
let mut player_turn: Color;
|
let mut player_turn: Color;
|
||||||
//send current position to the client
|
//send current position to the player
|
||||||
println!(
|
println!(
|
||||||
"server {}, send current position to the client...",
|
"server {}, send current position to the player...",
|
||||||
server.id
|
server.id
|
||||||
);
|
);
|
||||||
{
|
{
|
||||||
@ -69,11 +62,11 @@ fn handle_client(mut stream: UnixStream, server: Server) {
|
|||||||
player_turn = chess.turn();
|
player_turn = chess.turn();
|
||||||
clichess::write_to_stream(&mut stream, fen::fen(&*chess)).unwrap();
|
clichess::write_to_stream(&mut stream, fen::fen(&*chess)).unwrap();
|
||||||
}
|
}
|
||||||
println!("server {}, current position to the client sent", server.id);
|
println!("server {}, current position to the player sent", server.id);
|
||||||
loop {
|
loop {
|
||||||
if clichess::is_player_turn(&client, 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.
|
||||||
println!("server {}, waiting for client move..", server.id);
|
println!("server {}, waiting for player move..", server.id);
|
||||||
let input;
|
let input;
|
||||||
match clichess::read_line_from_stream(&stream) {
|
match clichess::read_line_from_stream(&stream) {
|
||||||
Ok(i) => input = i,
|
Ok(i) => input = i,
|
||||||
@ -87,14 +80,14 @@ fn handle_client(mut stream: UnixStream, server: Server) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut chess = server.chess_position.lock().unwrap();
|
let mut chess = server.chess_position.lock().unwrap();
|
||||||
let clients = server.clients.lock().unwrap();
|
let players = server.players.lock().unwrap();
|
||||||
println!("User tried to play {}", input);
|
println!("User tried to play {}", input);
|
||||||
match clichess::try_to_play_move(&chess, input) {
|
match clichess::try_to_play_move(&chess, input) {
|
||||||
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 chessfen = fen::fen(&*chess);
|
||||||
for (id, (_, cvar_buffer)) in clients.iter() {
|
for (id, (_, cvar_buffer)) in players.iter() {
|
||||||
if server.id != *id {
|
if server.id != *id {
|
||||||
cvar_buffer.0.lock().unwrap().push_str(&chessfen);
|
cvar_buffer.0.lock().unwrap().push_str(&chessfen);
|
||||||
cvar_buffer.1.notify_one();
|
cvar_buffer.1.notify_one();
|
||||||
@ -124,38 +117,87 @@ fn handle_client(mut stream: UnixStream, server: Server) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Client disconnected.")
|
println!("Player disconnected.")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_client(server: &Server, stream: &UnixStream) -> Client {
|
fn create_player(server: &Server, stream: &mut UnixStream) -> Player {
|
||||||
println!("Creating client {}...", server.id);
|
println!("Creating player {}...", server.id);
|
||||||
//get client name and pubkey
|
//get player name and pubkey
|
||||||
println!("Read lines from stream...");
|
let username_pubkey_json =
|
||||||
let mut buf = String::new();
|
clichess::read_line_from_stream(stream).expect("Player closed connection.");
|
||||||
let mut reader = BufReader::new(stream);
|
let username_pubkey_value: Value = serde_json::from_str(&username_pubkey_json).unwrap();
|
||||||
//first, username.
|
let username = username_pubkey_value["username"].to_string();
|
||||||
reader
|
let public_key = username_pubkey_value["pubkey"].to_string();
|
||||||
.read_line(&mut buf)
|
println!("got username: {}", username);
|
||||||
.expect("Client closed connection.");
|
println!("got pubkey: {}", public_key);
|
||||||
let username = String::from(buf.trim());
|
let role = receive_user_role(server, stream);
|
||||||
buf.clear();
|
let mut players = server.players.lock().unwrap();
|
||||||
reader
|
let player = Player {
|
||||||
.read_line(&mut buf)
|
|
||||||
.expect("Client closed connection.");
|
|
||||||
let public_key = String::from(buf.trim());
|
|
||||||
let role = match server.id {
|
|
||||||
0 => UserRole::White,
|
|
||||||
1 => UserRole::Black,
|
|
||||||
_ => UserRole::Spectator,
|
|
||||||
};
|
|
||||||
let mut clients = server.clients.lock().unwrap();
|
|
||||||
let client = Client {
|
|
||||||
role,
|
role,
|
||||||
side: clichess::from_color(clichess::get_default_side(role)),
|
|
||||||
username,
|
username,
|
||||||
public_key,
|
public_key,
|
||||||
};
|
};
|
||||||
clients.insert(server.id, (client.clone(), server.receiving_buffer.clone()));
|
players.insert(server.id, (player.clone(), server.receiving_buffer.clone()));
|
||||||
println!("Created client {}", server.id);
|
println!("Created player {}", server.id);
|
||||||
client
|
player
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive_user_role(server: &Server, stream: &mut UnixStream) -> UserRole {
|
||||||
|
let mut chosen_role: UserRole;
|
||||||
|
loop {
|
||||||
|
//send available roles
|
||||||
|
let available_roles = compute_available_roles_to_str(server);
|
||||||
|
println!("Computed available_roles as str: {}", available_roles);
|
||||||
|
clichess::write_to_stream(stream, available_roles.clone()).unwrap();
|
||||||
|
//receive chosen role
|
||||||
|
let chosen_role_str =
|
||||||
|
clichess::read_line_from_stream(stream).expect("Player closed connection.");
|
||||||
|
println!("Client id {} has chosen {}", server.id, chosen_role_str);
|
||||||
|
chosen_role =
|
||||||
|
clichess::parse_to_role(&chosen_role_str).expect("Client did not send parsable role.");
|
||||||
|
//check if role is still available after the choice
|
||||||
|
{
|
||||||
|
let mut available_roles_after_choice =
|
||||||
|
vec![UserRole::White, UserRole::Black, UserRole::Spectator];
|
||||||
|
let players = server.players.lock().unwrap();
|
||||||
|
for (_, (player, _)) in players.iter() {
|
||||||
|
match available_roles_after_choice
|
||||||
|
.iter()
|
||||||
|
.position(|r| *r == player.role)
|
||||||
|
{
|
||||||
|
Some(index) => available_roles_after_choice.remove(index),
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if available_roles_after_choice.contains(&chosen_role) {
|
||||||
|
println!("OK");
|
||||||
|
clichess::write_to_stream(stream, String::from("OK")).unwrap();
|
||||||
|
|
||||||
|
let get_confirmation =
|
||||||
|
clichess::read_line_from_stream(stream).expect("Player closed connection.");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
println!("KO");
|
||||||
|
clichess::write_to_stream(stream, String::from("KO")).unwrap();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chosen_role
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_available_roles_to_str(server: &Server) -> String {
|
||||||
|
let mut available_roles = vec![UserRole::White, UserRole::Black, UserRole::Spectator];
|
||||||
|
let players = server.players.lock().unwrap();
|
||||||
|
for (_, (player, _)) in players.iter() {
|
||||||
|
match available_roles.iter().position(|r| *r == player.role) {
|
||||||
|
Some(index) => available_roles.remove(index),
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let available_roles_str: Vec<String> = available_roles
|
||||||
|
.iter()
|
||||||
|
.map(|r| clichess::role_to_str(r))
|
||||||
|
.collect();
|
||||||
|
available_roles_str.join(",")
|
||||||
}
|
}
|
||||||
|
45
src/lib.rs
45
src/lib.rs
@ -1,5 +1,4 @@
|
|||||||
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;
|
||||||
@ -9,23 +8,16 @@ use std::io;
|
|||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::{BufReader, Write};
|
use std::io::{BufReader, Write};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::str;
|
use std::ops::Add;
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone)]
|
||||||
pub struct Client {
|
pub struct Player {
|
||||||
pub role: UserRole,
|
pub role: UserRole,
|
||||||
pub side: BoardSide,
|
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub public_key: String,
|
pub public_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
pub enum BoardSide {
|
|
||||||
White,
|
|
||||||
Black,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum UserRole {
|
pub enum UserRole {
|
||||||
White,
|
White,
|
||||||
Black,
|
Black,
|
||||||
@ -208,23 +200,24 @@ pub fn get_default_side(role: UserRole) -> Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_color(board_side: BoardSide) -> Color {
|
pub fn parse_to_role(s: &str) -> Result<UserRole, String> {
|
||||||
if board_side == BoardSide::White {
|
match &*s.to_ascii_lowercase() {
|
||||||
Color::White
|
"w" => Ok(UserRole::White),
|
||||||
} else {
|
"b" => Ok(UserRole::Black),
|
||||||
Color::Black
|
"s" => Ok(UserRole::Spectator),
|
||||||
|
_ => Err(String::from("Please enter a valid answer."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_color(color: Color) -> BoardSide {
|
pub fn role_to_str(r: &UserRole) -> String {
|
||||||
if color == Color::White {
|
String::from(match *r {
|
||||||
BoardSide::White
|
UserRole::White => "w",
|
||||||
} else {
|
UserRole::Black => "b",
|
||||||
BoardSide::Black
|
UserRole::Spectator => "s"
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_player_turn(client: &Client, playing_side: Color) -> bool {
|
pub fn is_player_turn(player: &Player, playing_side: Color) -> bool {
|
||||||
(playing_side == Color::White && client.role == UserRole::White)
|
(playing_side == Color::White && player.role == UserRole::White)
|
||||||
|| (playing_side == Color::Black && client.role == UserRole::Black)
|
|| (playing_side == Color::Black && player.role == UserRole::Black)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user