Refactor game loop

This commit is contained in:
Artlef 2020-11-29 21:50:26 +01:00
parent d167e1c84f
commit 4748d61bca

View File

@ -22,6 +22,7 @@ struct Client {
server_message_recv: Receiver<String>,
opponent_name: Option<String>,
last_move: Option<String>,
is_player_turn: Arc<Mutex<bool>>,
}
fn main() {
@ -64,6 +65,7 @@ fn main() {
server_message_recv,
opponent_name: Option::None,
last_move: Option::None,
is_player_turn,
};
let login_result = login(&mut client, &mut stream);
@ -96,74 +98,7 @@ fn main() {
}
client.display_sender.send(DisplayMessage::Help).unwrap();
let mut current_position = fetch_initial_chess_position(&client, &mut stream);
loop {
let is_player_turn_loop = clichess::is_player_turn(&client.player, current_position.turn());
{
let mut is_player_turn = is_player_turn.lock().unwrap();
*is_player_turn = is_player_turn_loop;
}
if is_player_turn_loop || client.player.role == UserRole::Spectator {
let mut message = String::from("");
let opponent_name = client.opponent_name.clone();
if opponent_name.is_some() {
message.push_str(&format!("{} played", opponent_name.expect("is some")));
client
.last_move
.clone()
.map(|chessmove| message.push_str(&format!(" {}", chessmove)));
}
if message.len() > 0 {
display_sender
.send(DisplayMessage::Information(message))
.unwrap();
}
}
display_sender
.send(DisplayMessage::Chessboard {
fen: fen::fen(&current_position),
side: client.side.clone(),
})
.unwrap();
//check if game is over.
if current_position.is_game_over() {
break;
}
if is_player_turn_loop {
//it's the user turn, taking user input
let mut input = client.keyboard_input_recv.recv().unwrap();
input = String::from(input.trim());
if input == EXIT_MSG {
client.waiting_server_msg_receiver.recv().unwrap();
break;
}
let response = send_request(&client, &mut stream, ClientRequest::Play(input.clone()));
if response == String::from("KO") {
display_sender
.send(DisplayMessage::Message(format!("Invalid move: {}", input)))
.unwrap();
//go back to taking user input
continue;
}
client.last_move = Some(input);
match get_current_position(&mut client, &mut stream) {
Ok(position) => current_position = position,
Err(_) => break,
};
//clear message
display_sender
.send(DisplayMessage::Message(String::default()))
.unwrap();
} else {
match wait_for_next_move(&mut client, &mut stream) {
Ok(position) => current_position = position,
Err(_) => break,
};
}
}
client.display_sender.send(DisplayMessage::Clear).unwrap();
let current_position = game_loop(&mut client, &mut stream);
let end_message = match current_position.outcome() {
None => "",
Some(Outcome::Draw) => "Draw game.",
@ -181,8 +116,9 @@ fn main() {
.display_sender
.send(DisplayMessage::Message(end_message))
.unwrap();
thread::sleep(time::Duration::from_secs(1));
thread::sleep(time::Duration::from_secs(5));
}
client.display_sender.send(DisplayMessage::Clear).unwrap();
send_request(&client, &mut stream, ClientRequest::Exit);
client.display_sender.send(DisplayMessage::Exit).unwrap();
}
@ -216,6 +152,80 @@ fn login(client: &mut Client, stream: &mut UnixStream) -> LoginResult {
LoginResult::Success
}
fn game_loop(client: &mut Client, stream: &mut UnixStream) -> Chess {
let mut current_position = fetch_initial_chess_position(client, stream);
loop {
let is_player_turn_loop = clichess::is_player_turn(&client.player, current_position.turn());
{
let mut is_player_turn = client.is_player_turn.lock().unwrap();
*is_player_turn = is_player_turn_loop;
}
if is_player_turn_loop || client.player.role == UserRole::Spectator {
let mut message = String::from("");
let opponent_name = client.opponent_name.clone();
if opponent_name.is_some() {
message.push_str(&format!("{} played", opponent_name.expect("is some")));
client
.last_move
.clone()
.map(|chessmove| message.push_str(&format!(" {}", chessmove)));
}
if message.len() > 0 {
client
.display_sender
.send(DisplayMessage::Information(message))
.unwrap();
}
}
client
.display_sender
.send(DisplayMessage::Chessboard {
fen: fen::fen(&current_position),
side: client.side.clone(),
})
.unwrap();
//check if game is over.
if current_position.is_game_over() {
break;
}
if is_player_turn_loop {
//it's the user turn, taking user input
let mut input = client.keyboard_input_recv.recv().unwrap();
input = String::from(input.trim());
if input == EXIT_MSG {
client.waiting_server_msg_receiver.recv().unwrap();
break;
}
let response = send_request(client, stream, ClientRequest::Play(input.clone()));
if response == String::from("KO") {
client
.display_sender
.send(DisplayMessage::Message(format!("Invalid move: {}", input)))
.unwrap();
//go back to taking user input
continue;
}
client.last_move = Some(input);
match get_current_position(client, stream) {
Ok(position) => current_position = position,
Err(_) => break,
};
//clear message
client
.display_sender
.send(DisplayMessage::Message(String::default()))
.unwrap();
} else {
match wait_for_next_move(client, stream) {
Ok(position) => current_position = position,
Err(_) => break,
};
}
}
current_position
}
fn send_request(client: &Client, stream: &mut UnixStream, request: ClientRequest) -> String {
let response: String;
match serde_json::to_string(&request) {