# HG changeset patch # User unC0Rr # Date 1734446661 -3600 # Node ID db18f1a30b0c787505ca0c6c64021d81239d2b6e # Parent 67469603872abdf5179af0b370bf6238822d052f Implement passing of available ammo to rust AI diff -r 67469603872a -r db18f1a30b0c hedgewars/uAI2.pas --- a/hedgewars/uAI2.pas Sat Dec 14 18:07:29 2024 +0100 +++ b/hedgewars/uAI2.pas Tue Dec 17 15:44:21 2024 +0100 @@ -10,9 +10,12 @@ {$linklib hwengine_future} +type TAmmoCounts = array[TAmmoType] of Longword; + PAmmoCounts = ^TAmmoCounts; + function create_ai(game_field: pointer): pointer; cdecl; external; procedure ai_clear_team(ai: pointer); cdecl; external; -procedure ai_add_team_hedgehog(ai: pointer; x, y: real); cdecl; external; +procedure ai_add_team_hedgehog(ai: pointer; x, y: real; ammo_counts: PAmmoCounts); cdecl; external; procedure ai_think(ai: pointer); cdecl; external; function ai_have_plan(): boolean; cdecl; external; procedure dispose_ai(ai: pointer); cdecl; external; @@ -21,6 +24,8 @@ procedure ProcessBot; var currHedgehogIndex, itHedgehog: Longword; + itAmmo: TAmmoType; + ammoCounts: TAmmoCounts; begin if ai = nil then begin @@ -35,10 +40,15 @@ with CurrentTeam^.Hedgehogs[itHedgehog] do if (Gear <> nil) and (Effects[heFrozen] = 0) then begin - ai_add_team_hedgehog(ai, hwFloat2float(Gear^.X), hwFloat2float(Gear^.Y)) + for itAmmo:= Low(TAmmoType) to High(TAmmoType) do + ammoCounts[itAmmo]:= HHHasAmmo(CurrentTeam^.Hedgehogs[itHedgehog], itAmmo); + + ai_add_team_hedgehog(ai, hwFloat2float(Gear^.X), hwFloat2float(Gear^.Y), ammoCounts) end; itHedgehog:= Succ(itHedgehog) mod CurrentTeam^.HedgehogsNumber; until (itHedgehog = currHedgehogIndex); + + ai_think(ai); end; procedure initModule; diff -r 67469603872a -r db18f1a30b0c rust/lib-hwengine-future/src/ai/action.rs --- a/rust/lib-hwengine-future/src/ai/action.rs Sat Dec 14 18:07:29 2024 +0100 +++ b/rust/lib-hwengine-future/src/ai/action.rs Tue Dec 17 15:44:21 2024 +0100 @@ -1,24 +1,22 @@ #[derive(Clone)] pub enum Direction { Left, - Right + Right, } #[derive(Clone)] pub enum Action { Walk(Direction), LongJump, - HighJump(usize) + HighJump(usize), } pub struct Actions { - actions: Vec + actions: Vec, } impl Actions { pub fn new() -> Self { - Self { - actions: vec![], - } + Self { actions: vec![] } } pub fn push(&mut self, action: Action) { @@ -28,4 +26,4 @@ pub fn pop(&mut self) -> Option { self.actions.pop() } -} \ No newline at end of file +} diff -r 67469603872a -r db18f1a30b0c rust/lib-hwengine-future/src/ai/ammo.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/lib-hwengine-future/src/ai/ammo.rs Tue Dec 17 15:44:21 2024 +0100 @@ -0,0 +1,65 @@ +#[repr(usize)] +pub enum AmmoType { + Nothing, + Grenade, + ClusterBomb, + Bazooka, + Bee, + Shotgun, + PickHammer, // 6 + Skip, + Rope, + Mine, + DEagle, + Dynamite, + FirePunch, + Whip, // 13 + BaseballBat, + Parachute, + AirAttack, + MineStrike, + BlowTorch, // 18 + Girder, + Teleport, + Switch, + Mortar, + Kamikaze, + Cake, // 24 + Seduction, + Watermelon, + HellishBomb, + Napalm, + Drill, + Ballgun, // 30 + RCPlane, + LowGravity, + ExtraDamage, + Invulnerable, + ExtraTime, // 35 + LaserSight, + Vampiric, + SniperRifle, + Jetpack, + Molotov, + Birdy, + PortalGun, // 42 + Piano, + GasBomb, + SineGun, + Flamethrower, + SMine, + Hammer, // 48 + Resurrector, + DrillStrike, + Snowball, + Tardis, + LandGun, // 53 + IceGun, + Knife, + Rubber, + AirMine, + Creeper, + Minigun, + Sentry, // 60 + Count, +} diff -r 67469603872a -r db18f1a30b0c rust/lib-hwengine-future/src/ai/mod.rs --- a/rust/lib-hwengine-future/src/ai/mod.rs Sat Dec 14 18:07:29 2024 +0100 +++ b/rust/lib-hwengine-future/src/ai/mod.rs Tue Dec 17 15:44:21 2024 +0100 @@ -1,25 +1,28 @@ mod action; +pub mod ammo; -use std::collections::HashMap; -use integral_geometry::Point; use crate::GameField; use action::*; +use integral_geometry::Point; +use std::collections::HashMap; pub struct Target { point: Point, health: i32, radius: u32, density: f32, - } pub struct Hedgehog { pub(crate) x: f32, pub(crate) y: f32, + pub(crate) ammo: [u32; ammo::AmmoType::Count as usize], + } pub struct AI<'a> { game_field: &'a GameField, + ammo: [u32; ammo::AmmoType::Count as usize], targets: Vec, team: Vec, planned_actions: Option, @@ -53,12 +56,17 @@ pub fn new(game_field: &'a GameField) -> AI<'a> { Self { game_field, + ammo: [0; ammo::AmmoType::Count as usize], targets: vec![], team: vec![], planned_actions: None, } } + pub fn set_available_ammo(&mut self, ammo: [u32; ammo::AmmoType::Count as usize]) { + self.ammo = ammo; + } + pub fn get_team_mut(&mut self) -> &mut Vec { &mut self.team } @@ -67,7 +75,7 @@ let mut stack = Vec::::new(); let mut waypoints = Waypoints::default(); - waypoints.add_keypoint(Waypoint{ + waypoints.add_keypoint(Waypoint { x: hedgehog.x, y: hedgehog.y, ticks: 0, @@ -75,9 +83,7 @@ previous_point: None, }); - while let Some(wp) = stack.pop() { - - } + while let Some(wp) = stack.pop() {} } pub fn have_plan(&self) -> bool { diff -r 67469603872a -r db18f1a30b0c rust/lib-hwengine-future/src/lib.rs --- a/rust/lib-hwengine-future/src/lib.rs Sat Dec 14 18:07:29 2024 +0100 +++ b/rust/lib-hwengine-future/src/lib.rs Tue Dec 17 15:44:21 2024 +0100 @@ -2,9 +2,9 @@ use integral_geometry::{Point, Size}; +use ai::*; use landgen::{ - outline_template_based::outline_template::OutlineTemplate, - maze::MazeTemplate, + maze::MazeTemplate, outline_template_based::outline_template::OutlineTemplate, wavefront_collapse::generator::TemplateDescription as WfcTemplate, LandGenerationParameters, LandGenerator, }; @@ -12,7 +12,7 @@ use mapgen::{theme::Theme, MapGenerator}; use std::fs; use std::{ffi::CStr, path::Path}; -use ai::*; +use std::ptr::slice_from_raw_parts; #[repr(C)] pub struct GameField { @@ -24,18 +24,16 @@ #[no_mangle] pub extern "C" fn get_game_field_parameters( game_field: &GameField, - width: *mut i32, - height: *mut i32, - play_width: *mut i32, - play_height: *mut i32, + width: &mut i32, + height: &mut i32, + play_width: &mut i32, + play_height: &mut i32, ) { - unsafe { - *width = game_field.collision.width() as i32; - *height = game_field.collision.height() as i32; + *width = game_field.collision.width() as i32; + *height = game_field.collision.height() as i32; - *play_width = game_field.collision.play_width() as i32; - *play_height = game_field.collision.play_height() as i32; - } + *play_width = game_field.collision.play_width() as i32; + *play_height = game_field.collision.play_height() as i32; } #[no_mangle] @@ -50,17 +48,17 @@ } #[no_mangle] -pub extern "C" fn generate_outline_templated_game_field( +pub unsafe extern "C" fn generate_outline_templated_game_field( feature_size: u32, seed: *const i8, template_type: *const i8, data_path: *const i8, ) -> *mut GameField { - let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap(); + let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap(); let data_path = Path::new(&data_path); - let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap(); - let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap(); + let seed: &str = CStr::from_ptr(seed).to_str().unwrap(); + let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap(); let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes()); @@ -90,17 +88,17 @@ } #[no_mangle] -pub extern "C" fn generate_wfc_templated_game_field( +pub unsafe extern "C" fn generate_wfc_templated_game_field( feature_size: u32, seed: *const i8, template_type: *const i8, data_path: *const i8, ) -> *mut GameField { - let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap(); + let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap(); let data_path = Path::new(&data_path); - let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap(); - let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap(); + let seed: &str = CStr::from_ptr(seed).to_str().unwrap(); + let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap(); let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes()); @@ -130,17 +128,17 @@ } #[no_mangle] -pub extern "C" fn generate_maze_game_field( +pub unsafe extern "C" fn generate_maze_game_field( feature_size: u32, seed: *const i8, template_type: *const i8, data_path: *const i8, ) -> *mut GameField { - let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap(); + let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap(); let data_path = Path::new(&data_path); - let seed: &str = unsafe { CStr::from_ptr(seed) }.to_str().unwrap(); - let template_type: &str = unsafe { CStr::from_ptr(template_type) }.to_str().unwrap(); + let seed: &str = CStr::from_ptr(seed).to_str().unwrap(); + let template_type: &str = CStr::from_ptr(template_type).to_str().unwrap(); let mut random_numbers_gen = LaggedFibonacciPRNG::new(seed.as_bytes()); @@ -173,15 +171,15 @@ } #[no_mangle] -pub extern "C" fn apply_theme( +pub unsafe extern "C" fn apply_theme( game_field: &mut GameField, data_path: *const i8, theme_name: *const i8, ) { - let data_path: &str = unsafe { CStr::from_ptr(data_path) }.to_str().unwrap(); + let data_path: &str = CStr::from_ptr(data_path).to_str().unwrap(); let data_path = Path::new(&data_path); - let theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.to_str().unwrap(); + let theme_name: &str = CStr::from_ptr(theme_name).to_str().unwrap(); let map_gen = MapGenerator::<()>::new(data_path); let theme = Theme::load( @@ -244,8 +242,8 @@ } #[no_mangle] -pub extern "C" fn dispose_game_field(game_field: *mut GameField) { - unsafe { drop(Box::from_raw(game_field)) }; +pub unsafe extern "C" fn dispose_game_field(game_field: *mut GameField) { + drop(Box::from_raw(game_field)); } #[no_mangle] @@ -259,14 +257,15 @@ } #[no_mangle] -pub extern "C" fn ai_add_team_hedgehog(ai: &mut AI, x: f32, y: f32) { - ai.get_team_mut().push(Hedgehog{x, y}); +pub unsafe extern "C" fn ai_add_team_hedgehog(ai: &mut AI, x: f32, y: f32, ammo_counts: *const u32) { + let ammo_counts = &*slice_from_raw_parts(ammo_counts, crate::ai::ammo::AmmoType::Count as usize); + let ammo_counts = std::array::from_fn(|i| ammo_counts[i].clone()); + + ai.get_team_mut().push(Hedgehog { x, y, ammo: ammo_counts }); } #[no_mangle] -pub extern "C" fn ai_think(ai: &AI) { - -} +pub extern "C" fn ai_think(ai: &AI) {} #[no_mangle] pub extern "C" fn ai_have_plan(ai: &AI) -> bool { @@ -279,6 +278,6 @@ } #[no_mangle] -pub extern "C" fn dispose_ai(ai: *mut AI) { - unsafe { drop(Box::from_raw(ai)) }; +pub unsafe extern "C" fn dispose_ai(ai: *mut AI) { + drop(Box::from_raw(ai)); }