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();
}
client.display_sender.send(DisplayMessage::Help).unwrap();
let current_position = game_loop(&mut client, &mut stream);
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."
}
loop {
client.display_sender.send(DisplayMessage::Help).unwrap();
if !game_loop(&mut client, &mut stream) {
break;
}
}
.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);
@ -152,7 +138,8 @@ fn login(client: &mut Client, stream: &mut UnixStream) -> LoginResult {
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);
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 {

View File

@ -19,6 +19,7 @@ struct Server {
cvar: Arc<(Mutex<bool>, Condvar)>,
opponent_name: Arc<Mutex<Option<String>>>,
last_move: Arc<Mutex<Option<String>>>,
confirm_reset: Arc<(Mutex<bool>, Condvar)>,
}
fn main() {
@ -31,6 +32,9 @@ fn main() {
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
for stream in listener.incoming() {
match stream {
@ -48,6 +52,7 @@ fn main() {
cvar: condvar_pair,
opponent_name: Arc::new(Mutex::new(Option::None)),
last_move: Arc::new(Mutex::new(Option::None)),
confirm_reset: confirm_reset.clone(),
};
/* connection succeeded */
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::Reset) => reset(&mut stream, server),
Ok(ClientRequest::Exit) => {
send_ok(&mut stream);
break;
@ -291,6 +297,30 @@ fn play(stream: &mut UnixStream, server: &Server, movestr: String) {
.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) {
clichess::write_to_stream(stream, String::from("OK")).unwrap();
}

View File

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