From 97d7e70642f727f2e8d1fb8e7f5e23c2a9e04e14 Mon Sep 17 00:00:00 2001 From: szymon Date: Wed, 19 Aug 2026 09:56:51 +0200 Subject: [PATCH] feat: add super advanced ai --- src/lib.rs | 1 + src/super_advanced_ai.rs | 115 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 src/super_advanced_ai.rs diff --git a/src/lib.rs b/src/lib.rs index a15f61f..f5d0540 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ pub mod logic; pub mod network; pub mod settings; +pub mod super_advanced_ai; diff --git a/src/super_advanced_ai.rs b/src/super_advanced_ai.rs new file mode 100644 index 0000000..d4aebb6 --- /dev/null +++ b/src/super_advanced_ai.rs @@ -0,0 +1,115 @@ +use log::{error, info}; +use rand::seq::IndexedRandom; + +use crate::{logic::game_master::GameResult, network::client::Client}; + +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum BotDificulty { + Easy, + Normal, + Hard, +} + +pub struct Bot { + dificulty: BotDificulty, +} + +impl Bot { + pub async fn new(dificulty: BotDificulty) -> Self { + if dificulty == BotDificulty::Normal || dificulty == BotDificulty::Hard { + todo!("Only easy is implemented"); + } + + Self { dificulty } + } + + pub async fn game_loop(&self) { + let mut client = Client::new() + .await + .expect("Couldn't connect to the server. Is it online?"); + + client.signal_readiness().await; // bot is always ready + + let mut receiver = client + .get_update_receiver() + .expect("Could not receive the receiver"); + + 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); + client + .send_text_message( + "Why are you messaging bot? Are you stupid?".to_string(), + ) + .await; + } + 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; + } + } + } + }); + } +}