Reset the board at the end of the game

The two players must press enter to reset. For spectators, the game is
stopped.
This commit is contained in:
Artlef 2020-12-06 22:47:02 +01:00
parent 8377717cc3
commit ae3791a24b
3 changed files with 87 additions and 21 deletions

View File

@ -97,26 +97,12 @@ fn main() {
.unwrap(); .unwrap();
} }
client.display_sender.send(DisplayMessage::Help).unwrap(); loop {
let current_position = game_loop(&mut client, &mut stream); client.display_sender.send(DisplayMessage::Help).unwrap();
let end_message = match current_position.outcome() { if !game_loop(&mut client, &mut stream) {
None => "", break;
Some(Outcome::Draw) => "Draw game.",
Some(Outcome::Decisive { winner }) => {
if winner == Color::White {
"White has won the game."
} else {
"Black has won the game."
}
} }
} client.display_sender.send(DisplayMessage::Clear).unwrap();
.to_string();
if !end_message.is_empty() {
client
.display_sender
.send(DisplayMessage::Message(end_message))
.unwrap();
thread::sleep(time::Duration::from_secs(5));
} }
client.display_sender.send(DisplayMessage::Clear).unwrap(); client.display_sender.send(DisplayMessage::Clear).unwrap();
send_request(&client, &mut stream, ClientRequest::Exit); send_request(&client, &mut stream, ClientRequest::Exit);
@ -152,7 +138,8 @@ fn login(client: &mut Client, stream: &mut UnixStream) -> LoginResult {
LoginResult::Success LoginResult::Success
} }
fn game_loop(client: &mut Client, stream: &mut UnixStream) -> Chess { fn game_loop(client: &mut Client, stream: &mut UnixStream) -> bool {
let mut replay = false;
let mut current_position = fetch_initial_chess_position(client, stream); let mut current_position = fetch_initial_chess_position(client, stream);
loop { loop {
@ -223,7 +210,55 @@ fn game_loop(client: &mut Client, stream: &mut UnixStream) -> Chess {
}; };
} }
} }
current_position let end_message = match current_position.outcome() {
None => "",
Some(Outcome::Draw) => "Draw game.",
Some(Outcome::Decisive { winner }) => {
if winner == Color::White {
"White has won the game."
} else {
"Black has won the game."
}
}
}
.to_string();
if !end_message.is_empty() {
//accept input
if client.player.role != UserRole::Spectator {
client
.display_sender
.send(DisplayMessage::Message(format!(
"{}\n\rPress enter to rematch.",
end_message
)))
.unwrap();
let mut is_player_turn = client.is_player_turn.lock().unwrap();
*is_player_turn = true;
} else {
client
.display_sender
.send(DisplayMessage::Message(format!("{}", end_message)))
.unwrap();
thread::sleep(time::Duration::from_secs(5));
return false;
}
let buffer = client.keyboard_input_recv.recv().unwrap();
if buffer == EXIT_MSG {
client.waiting_server_msg_receiver.recv().unwrap();
} else {
replay = true;
client
.display_sender
.send(DisplayMessage::Message(format!(
"{}\n\rWaiting for your opponent to restart...",
end_message
)))
.unwrap();
send_request(client, stream, ClientRequest::Reset);
}
}
replay
} }
fn send_request(client: &Client, stream: &mut UnixStream, request: ClientRequest) -> String { fn send_request(client: &Client, stream: &mut UnixStream, request: ClientRequest) -> String {

View File

@ -19,6 +19,7 @@ struct Server {
cvar: Arc<(Mutex<bool>, Condvar)>, cvar: Arc<(Mutex<bool>, Condvar)>,
opponent_name: Arc<Mutex<Option<String>>>, opponent_name: Arc<Mutex<Option<String>>>,
last_move: Arc<Mutex<Option<String>>>, last_move: Arc<Mutex<Option<String>>>,
confirm_reset: Arc<(Mutex<bool>, Condvar)>,
} }
fn main() { fn main() {
@ -31,6 +32,9 @@ fn main() {
let listener = UnixListener::bind("/tmp/clichess.socket").unwrap(); let listener = UnixListener::bind("/tmp/clichess.socket").unwrap();
//boolean shared amongst all server instances
let confirm_reset = Arc::new((Mutex::new(false), Condvar::new()));
// accept connections and process them, spawning a new thread for each one // accept connections and process them, spawning a new thread for each one
for stream in listener.incoming() { for stream in listener.incoming() {
match stream { match stream {
@ -48,6 +52,7 @@ fn main() {
cvar: condvar_pair, cvar: condvar_pair,
opponent_name: Arc::new(Mutex::new(Option::None)), opponent_name: Arc::new(Mutex::new(Option::None)),
last_move: Arc::new(Mutex::new(Option::None)), last_move: Arc::new(Mutex::new(Option::None)),
confirm_reset: confirm_reset.clone(),
}; };
/* connection succeeded */ /* connection succeeded */
thread::spawn(move || handle_player(stream, &mut server, others_serv_msg_sender)); thread::spawn(move || handle_player(stream, &mut server, others_serv_msg_sender));
@ -94,6 +99,7 @@ fn handle_player(
} }
} }
Ok(ClientRequest::Play(movestr)) => play(&mut stream, server, movestr), Ok(ClientRequest::Play(movestr)) => play(&mut stream, server, movestr),
Ok(ClientRequest::Reset) => reset(&mut stream, server),
Ok(ClientRequest::Exit) => { Ok(ClientRequest::Exit) => {
send_ok(&mut stream); send_ok(&mut stream);
break; break;
@ -291,6 +297,30 @@ fn play(stream: &mut UnixStream, server: &Server, movestr: String) {
.unwrap(); .unwrap();
} }
fn reset(stream: &mut UnixStream, server: &Server) {
//wait for the other server.
println!("client {} wants to restart game.", server.id);
let (lock, cvar) = &*server.confirm_reset;
let mut reset_confirmed = lock.lock().unwrap();
if *reset_confirmed {
println!("restarting game.");
{
let mut chess = server.chess_position.lock().unwrap();
*chess = Chess::default();
}
*reset_confirmed = false;
cvar.notify_one();
} else {
//wait for other server
println!("client {} is waiting.", server.id);
*reset_confirmed = true;
while *reset_confirmed {
reset_confirmed = cvar.wait(reset_confirmed).unwrap();
}
}
send_ok(stream);
}
fn send_ok(stream: &mut UnixStream) { fn send_ok(stream: &mut UnixStream) {
clichess::write_to_stream(stream, String::from("OK")).unwrap(); clichess::write_to_stream(stream, String::from("OK")).unwrap();
} }

View File

@ -47,6 +47,7 @@ pub enum ClientRequest {
GetGameInfo, GetGameInfo,
WaitForNextMove, WaitForNextMove,
Play(String), Play(String),
Reset,
Exit, Exit,
} }