mirror of
https://github.com/szymon-jozef/checkers.git
synced 2026-10-27 11:10:48 +01:00
refactor: move update function of the network client to the constructor
This commit is contained in:
@@ -88,13 +88,11 @@ async fn run_bot() {
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init();
|
||||
|
||||
let Some(mut client) = Client::new().await else {
|
||||
let Some(mut client) = Client::new(None).await else {
|
||||
println!("Not worky, ending");
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
client.update();
|
||||
|
||||
let (stdin_sender, mut stdin_receiver) = mpsc::channel(1024);
|
||||
|
||||
let mut context: ClientContext = ClientContext::default();
|
||||
|
||||
@@ -23,25 +23,24 @@ pub enum ClientCommands {
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
conn_reciever_incoming: Option<Receiver<(SocketAddr, Message<ServerMessage>)>>,
|
||||
conn_sender_outgoing: Sender<Message<ClientMessage>>,
|
||||
settings: ClientSettings,
|
||||
|
||||
update_sender: Sender<ServerMessage>,
|
||||
update_receiver: Option<Receiver<ServerMessage>>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Creates a new instance of clients, connects it to the server and starts update loop
|
||||
pub async fn new(settings: Option<ClientSettings>) -> Option<Client> {
|
||||
let Some(settings) = settings.or(Some(ClientSettings::new())) else {
|
||||
error!("Could not load client settings");
|
||||
return None;
|
||||
};
|
||||
|
||||
let (conn_sender, conn_reciever) =
|
||||
let (conn_sender, mut conn_reciever) =
|
||||
mpsc::channel::<(SocketAddr, Message<ServerMessage>)>(1024);
|
||||
|
||||
let mut conn: Connection<ServerMessage, ClientMessage> =
|
||||
Connection::new(ConnectionType::Server, conn_sender);
|
||||
|
||||
let conn_sender_outgoing = conn.get_sender();
|
||||
|
||||
let (update_sender, update_receiver) = mpsc::channel(1024);
|
||||
@@ -55,32 +54,14 @@ impl Client {
|
||||
conn.start_listening().await;
|
||||
});
|
||||
|
||||
Some(Client {
|
||||
conn_reciever_incoming: Some(conn_reciever),
|
||||
conn_sender_outgoing,
|
||||
|
||||
settings,
|
||||
|
||||
update_sender,
|
||||
update_receiver: Some(update_receiver),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update(&mut self) {
|
||||
let Some(mut conn_reciever_incoming) = self.conn_reciever_incoming.take() else {
|
||||
error!("Tried updating, but there's no conn_reciever of incoming messages!");
|
||||
return;
|
||||
};
|
||||
|
||||
let conn_sender = self.conn_sender_outgoing.clone();
|
||||
|
||||
let settings = self.settings.clone();
|
||||
let update_sender = self.update_sender.clone();
|
||||
let conn_sender_outgoing_clone = conn_sender_outgoing.clone();
|
||||
let settings_clone = settings.clone();
|
||||
let update_sender_clone = update_sender.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::select! {
|
||||
oldest_msg = conn_reciever_incoming.recv() => {
|
||||
oldest_msg = conn_reciever.recv() => {
|
||||
if let Some(oldest_msg) = oldest_msg {
|
||||
let (addr, msg) = oldest_msg;
|
||||
debug!("Got message from: {:?}", addr);
|
||||
@@ -89,10 +70,10 @@ impl Client {
|
||||
ServerMessage::RequestHandshake => {
|
||||
info!("Server requested handshake!");
|
||||
let msg = Message::new(ClientMessage::AnswerHandshake {
|
||||
player_name: settings.name.clone(),
|
||||
player_name: settings_clone.name.clone(),
|
||||
});
|
||||
|
||||
let _ = conn_sender.send(msg.unwrap()).await;
|
||||
let _ = conn_sender_outgoing_clone.send(msg.unwrap()).await;
|
||||
}
|
||||
|
||||
ServerMessage::AcceptHandshake => {
|
||||
@@ -106,7 +87,7 @@ impl Client {
|
||||
|
||||
_ => { // Pass all messages that require player intervention to the
|
||||
// local client
|
||||
let _ = update_sender.send(msg.content).await;
|
||||
let _ = update_sender_clone.send(msg.content).await;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -117,6 +98,11 @@ impl Client {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Some(Client {
|
||||
conn_sender_outgoing,
|
||||
update_receiver: Some(update_receiver),
|
||||
})
|
||||
}
|
||||
|
||||
async fn send_message(&mut self, msg: Result<Message<ClientMessage>, postcard::Error>) {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
use log::{error, info};
|
||||
use rand::seq::IndexedRandom;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{logic::game_master::GameResult, network::client::Client};
|
||||
use crate::{
|
||||
logic::game_master::GameResult,
|
||||
network::client::Client,
|
||||
settings::{client_settings::ClientSettings, general_settings::DEFAULT_URL},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum BotDificulty {
|
||||
@@ -23,12 +28,14 @@ impl Bot {
|
||||
Self { dificulty }
|
||||
}
|
||||
|
||||
pub async fn game_loop(&self) {
|
||||
let mut client = Client::new()
|
||||
.await
|
||||
.expect("Couldn't connect to the server. Is it online?");
|
||||
pub async fn game_loop(&self) -> Option<Uuid> {
|
||||
let mut client = Client::new(Some(ClientSettings {
|
||||
name: "Bot".to_string(),
|
||||
server_url: DEFAULT_URL,
|
||||
}))
|
||||
.await
|
||||
.expect("Couldn't connect to the server. Is it online?");
|
||||
|
||||
client.update();
|
||||
client.signal_readiness().await; // bot is always ready
|
||||
|
||||
let mut receiver = client
|
||||
@@ -37,76 +44,74 @@ impl Bot {
|
||||
|
||||
let dificulty = self.dificulty;
|
||||
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match receiver.recv().await {
|
||||
Some(message) => match message {
|
||||
crate::network::message::ServerMessage::GameStart { identity } => {
|
||||
info!("Bot got identity: {}", identity);
|
||||
}
|
||||
crate::network::message::ServerMessage::AvailableCaptures { captures } => {
|
||||
let capture = captures
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Could not select random capture");
|
||||
client.send_capture(capture.clone()).await;
|
||||
}
|
||||
crate::network::message::ServerMessage::AvailableMoves { moves } => {
|
||||
let rand_pawn = moves
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Couldn't select random move");
|
||||
let rand_move = rand_pawn
|
||||
.available_steps
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Could not get random move");
|
||||
|
||||
client.send_move(rand_pawn.from, rand_move.clone()).await;
|
||||
}
|
||||
crate::network::message::ServerMessage::BroadcastBoardState {
|
||||
board: _,
|
||||
} => {
|
||||
info!("Got server state!");
|
||||
|
||||
match dificulty.clone() {
|
||||
BotDificulty::Easy => {} // we do nothing with it because easy bot
|
||||
// just does random stuff. In future
|
||||
// board_view can be used to calculate the
|
||||
// best possible move atm
|
||||
BotDificulty::Normal => todo!(),
|
||||
BotDificulty::Hard => todo!(),
|
||||
}
|
||||
}
|
||||
crate::network::message::ServerMessage::BroadcastCurrentTurn {
|
||||
active_player: _,
|
||||
} => {} // we do nothing with this - bot doesn't need to know if it's the
|
||||
// active player, as it's only responding to messages
|
||||
crate::network::message::ServerMessage::BroadCastTextMessage {
|
||||
sender,
|
||||
content,
|
||||
} => {
|
||||
info!("Bot got message from [{}] - {}", sender, content);
|
||||
}
|
||||
|
||||
crate::network::message::ServerMessage::GameEnd { result } => {
|
||||
info!("Game has ended!");
|
||||
match result {
|
||||
GameResult::Draw => {
|
||||
info!("Draw!");
|
||||
}
|
||||
GameResult::Lost(loser) => {
|
||||
info!("ID: {} lost!", loser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
None => {
|
||||
error!("Connection broken! Super advanced ai logging out!");
|
||||
break;
|
||||
loop {
|
||||
match receiver.recv().await {
|
||||
Some(message) => match message {
|
||||
crate::network::message::ServerMessage::GameStart { identity } => {
|
||||
info!("Bot got identity: {}", identity);
|
||||
}
|
||||
crate::network::message::ServerMessage::AvailableCaptures { captures } => {
|
||||
let capture = captures
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Could not select random capture");
|
||||
client.send_capture(capture.clone()).await;
|
||||
}
|
||||
crate::network::message::ServerMessage::AvailableMoves { moves } => {
|
||||
let rand_pawn = moves
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Couldn't select random move");
|
||||
let rand_move = rand_pawn
|
||||
.available_steps
|
||||
.choose(&mut rand::rng())
|
||||
.expect("Could not get random move");
|
||||
|
||||
client.send_move(rand_pawn.from, rand_move.clone()).await;
|
||||
}
|
||||
crate::network::message::ServerMessage::BroadcastBoardState { board: _ } => {
|
||||
info!("Got server state!");
|
||||
|
||||
match dificulty.clone() {
|
||||
BotDificulty::Easy => {} // we do nothing with it because easy bot
|
||||
// just does random stuff. In future
|
||||
// board_view can be used to calculate the
|
||||
// best possible move atm
|
||||
BotDificulty::Normal => todo!(),
|
||||
BotDificulty::Hard => todo!(),
|
||||
}
|
||||
}
|
||||
crate::network::message::ServerMessage::BroadcastCurrentTurn {
|
||||
active_player: _,
|
||||
} => {} // we do nothing with this - bot doesn't need to know if it's the
|
||||
// active player, as it's only responding to messages
|
||||
crate::network::message::ServerMessage::BroadCastTextMessage {
|
||||
sender,
|
||||
content,
|
||||
} => {
|
||||
info!("Bot got message from [{}] - {}", sender, content);
|
||||
}
|
||||
|
||||
crate::network::message::ServerMessage::GameEnd { result } => {
|
||||
info!("Game has ended!");
|
||||
match result {
|
||||
GameResult::Draw => {
|
||||
info!("Draw!");
|
||||
return None;
|
||||
}
|
||||
GameResult::Lost(loser) => {
|
||||
info!("ID: {} lost!", loser);
|
||||
return Some(loser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
None => {
|
||||
error!("Connection broken! Super advanced ai logging out!");
|
||||
return None;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user