16069
|
1 |
mod action;
|
16078
|
2 |
pub mod ammo;
|
16082
|
3 |
mod attack_tests;
|
16069
|
4 |
|
16068
|
5 |
use crate::GameField;
|
16069
|
6 |
use action::*;
|
16078
|
7 |
use integral_geometry::Point;
|
|
8 |
use std::collections::HashMap;
|
16068
|
9 |
|
|
10 |
pub struct Target {
|
|
11 |
point: Point,
|
|
12 |
health: i32,
|
|
13 |
radius: u32,
|
|
14 |
density: f32,
|
|
15 |
}
|
|
16 |
|
|
17 |
pub struct Hedgehog {
|
|
18 |
pub(crate) x: f32,
|
|
19 |
pub(crate) y: f32,
|
16078
|
20 |
pub(crate) ammo: [u32; ammo::AmmoType::Count as usize],
|
16068
|
21 |
}
|
|
22 |
|
|
23 |
pub struct AI<'a> {
|
|
24 |
game_field: &'a GameField,
|
16078
|
25 |
ammo: [u32; ammo::AmmoType::Count as usize],
|
16068
|
26 |
targets: Vec<Target>,
|
|
27 |
team: Vec<Hedgehog>,
|
16069
|
28 |
planned_actions: Option<Actions>,
|
16068
|
29 |
}
|
|
30 |
|
|
31 |
#[derive(Clone)]
|
16082
|
32 |
pub(crate) struct Waypoint {
|
16068
|
33 |
x: f32,
|
|
34 |
y: f32,
|
|
35 |
ticks: usize,
|
|
36 |
damage: usize,
|
|
37 |
previous_point: Option<(usize, Action)>,
|
|
38 |
}
|
|
39 |
|
|
40 |
#[derive(Default)]
|
16082
|
41 |
pub(crate) struct Waypoints {
|
16068
|
42 |
key_points: Vec<Waypoint>,
|
|
43 |
points: HashMap<Point, Waypoint>,
|
|
44 |
}
|
|
45 |
|
|
46 |
impl Waypoints {
|
|
47 |
fn add_keypoint(&mut self, waypoint: Waypoint) {
|
|
48 |
let [x, y] = [waypoint.x, waypoint.y].map(|i| i as i32);
|
|
49 |
let point = Point::new(x, y);
|
|
50 |
self.key_points.push(waypoint.clone());
|
|
51 |
self.points.insert(point, waypoint);
|
|
52 |
}
|
|
53 |
}
|
|
54 |
|
16082
|
55 |
impl IntoIterator for Waypoints {
|
|
56 |
type Item = Waypoint;
|
|
57 |
type IntoIter = std::collections::hash_map::IntoValues<Point, Waypoint>;
|
|
58 |
|
|
59 |
fn into_iter(self) -> Self::IntoIter {
|
|
60 |
self.points.into_values()
|
|
61 |
}
|
|
62 |
}
|
|
63 |
|
16068
|
64 |
impl<'a> AI<'a> {
|
|
65 |
pub fn new(game_field: &'a GameField) -> AI<'a> {
|
|
66 |
Self {
|
|
67 |
game_field,
|
16078
|
68 |
ammo: [0; ammo::AmmoType::Count as usize],
|
16068
|
69 |
targets: vec![],
|
|
70 |
team: vec![],
|
16069
|
71 |
planned_actions: None,
|
16068
|
72 |
}
|
|
73 |
}
|
|
74 |
|
16078
|
75 |
pub fn set_available_ammo(&mut self, ammo: [u32; ammo::AmmoType::Count as usize]) {
|
|
76 |
self.ammo = ammo;
|
|
77 |
}
|
|
78 |
|
16068
|
79 |
pub fn get_team_mut(&mut self) -> &mut Vec<Hedgehog> {
|
|
80 |
&mut self.team
|
|
81 |
}
|
|
82 |
|
16082
|
83 |
pub fn walk(&self, hedgehog: &Hedgehog) {
|
16068
|
84 |
let mut stack = Vec::<usize>::new();
|
|
85 |
let mut waypoints = Waypoints::default();
|
|
86 |
|
16078
|
87 |
waypoints.add_keypoint(Waypoint {
|
16068
|
88 |
x: hedgehog.x,
|
|
89 |
y: hedgehog.y,
|
|
90 |
ticks: 0,
|
|
91 |
damage: 0,
|
|
92 |
previous_point: None,
|
|
93 |
});
|
|
94 |
|
16082
|
95 |
while let Some(waypoint) = stack.pop() {
|
|
96 |
// find other positions
|
|
97 |
}
|
|
98 |
|
|
99 |
for Waypoint { x, y, .. } in waypoints {
|
|
100 |
self.analyze_position_attacks(x, y);
|
|
101 |
}
|
|
102 |
}
|
|
103 |
|
|
104 |
fn analyze_position_attacks(&self, x: f32, y: f32) {
|
|
105 |
self.ammo
|
|
106 |
.iter()
|
|
107 |
.enumerate()
|
|
108 |
.filter(|&(_, &count)| count > 0u32)
|
|
109 |
.for_each(|(a, &count)| {
|
|
110 |
let a = ammo::AmmoType::try_from(a).expect("What are you iterating over?");
|
|
111 |
|
|
112 |
a.analyze_attacks(self.game_field, &self.targets, x, y)
|
|
113 |
});
|
16068
|
114 |
}
|
16069
|
115 |
|
|
116 |
pub fn have_plan(&self) -> bool {
|
|
117 |
self.planned_actions.is_some()
|
|
118 |
}
|
|
119 |
}
|