diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index e512089..20b83d6 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -102,38 +102,23 @@ impl BattleSession { let card = filled .get(self.random.next(filled.len() as i32).max(0) as usize)? .clone(); - let towers: Vec<(i32, i32)> = self - .mode - .battle - .objects - .objects + let leader = self.mode.battle.leader(crate::bot::BOT_OWNER_INDEX as usize)?; + let (king_x, king_y) = leader.position(); + let towers: Vec<(i32, i32)> = self.mode.battle.leader_towers + [crate::bot::BOT_OWNER_INDEX as usize] .iter() - .filter(|entry| { - entry.owner_index() == crate::bot::BOT_OWNER_INDEX - && entry.stats().is_building() - && entry.is_alive() + .filter_map(|tower| { + self.mode + .battle + .objects + .objects + .iter() + .find(|entry| entry.global_id == *tower && entry.is_alive()) }) .map(|entry| entry.position()) .collect(); - let leader = self.mode.battle.leader(crate::bot::BOT_OWNER_INDEX as usize)?; - let (king_x, king_y) = leader.position(); - let front = towers - .iter() - .copied() - .fold((king_x, king_y), |best, tower| { - if (tower.1 - king_y).abs() > (best.1 - king_y).abs() { - tower - } else { - best - } - }); - let lane: Vec<(i32, i32)> = towers - .iter() - .copied() - .filter(|(_, y)| *y == front.1) - .collect(); - let (x, tower_y) = lane - .get(self.random.next(lane.len().max(1) as i32).max(0) as usize) + let (x, tower_y) = towers + .get(self.random.next(towers.len().max(1) as i32).max(0) as usize) .copied() .unwrap_or((king_x, king_y)); let ahead = tower_y + (tower_y - king_y).signum() * BOT_DEPLOY_AHEAD; diff --git a/crates/game-service/tests/walk_to_tower.rs b/crates/game-service/tests/walk_to_tower.rs index 2cd8eef..2ca867c 100644 --- a/crates/game-service/tests/walk_to_tower.rs +++ b/crates/game-service/tests/walk_to_tower.rs @@ -91,7 +91,7 @@ fn the_bot_deploys_in_front_of_its_own_towers() { } let builder = BattleBuilder::new(&root); let mut deck = logic::model::LogicSpellDeck::default(); - for (slot, name) in ["Knight", "Archers", "Goblins", "Giant"].iter().enumerate() { + for (slot, name) in ["Knight", "Cannon", "GoblinHut", "Giant"].iter().enumerate() { deck.slots[slot] = Some(logic::model::LogicSpell { data: LogicDataRef::spell(name), ..logic::model::LogicSpell::default() @@ -113,12 +113,26 @@ fn the_bot_deploys_in_front_of_its_own_towers() { if tick % 20 == 0 { if let Some((card, at, instance)) = session.bot_play() { let entries = builder.summon(&card, at, 1, 0, instance); + let entries_debug = entries.clone(); session.reserve_instances(entries.len()); for entry in entries { session.push(entry); } + assert!( + (17000..25000).contains(&at.y) && (at.x == 3500 || at.x == 14500), + "the bot deployed at {:?}, which is not in front of one of its towers", + (at.x, at.y) + ); plays += 1; - if plays <= 6 { println!("bot played at {:?}", (at.x, at.y)); } + if plays <= 8 { + println!( + "bot played {:?} at {:?}, {} entries, speeds {:?}", + card, + (at.x, at.y), + entries_debug.len(), + entries_debug.iter().map(|e| e.stats().speed).collect::>() + ); + } } } session.advance_to(tick); @@ -140,13 +154,10 @@ fn the_bot_deploys_in_front_of_its_own_towers() { break; } for entry in session.mode().battle.objects.objects.iter() { - if entry.stats().speed < 1 { - continue; - } let (x, y) = entry.position(); if !((500..=17500).contains(&x) && (1000..=31000).contains(&y)) { println!( - "t={tick}: troop owner={} speed={} alive={} at ({x}, {y})", + "t={tick}: object owner={} speed={} alive={} at ({x}, {y})", entry.owner_index(), entry.stats().speed, entry.is_alive()