| """Hardcoded opponent intelligence profiles for OpenRA AI bots. |
| |
| Provides scouting reports and behavioral profiles based on the AI difficulty |
| level. These are static assessments based on observed AI behavior patterns. |
| """ |
|
|
| from typing import Optional |
|
|
|
|
| |
|
|
| AI_PROFILES: dict[str, dict] = { |
| "beginner": { |
| "difficulty": "Beginner", |
| "display_name": "Beginner AI", |
| "aggressiveness": "minimal", |
| "expansion_tendency": "none", |
| "unit_diversity": "very_low", |
| "build_order_quality": "very_poor", |
| "estimated_win_rate_vs_new_player": 0.10, |
| "typical_first_attack_tick": 150000, |
| "behavioral_traits": [ |
| "Almost never attacks โ first attack after 100+ minutes", |
| "Builds only basic infantry (rifle soldiers, grenadiers)", |
| "No vehicles, no aircraft, no navy", |
| "Tiny squads of 3-5 units that pose almost no threat", |
| "Stays at starting base, never expands", |
| "Extremely slow economy โ one refinery, one harvester", |
| "Does not repair damaged buildings", |
| "Very slow construction speed โ 8x slower than normal AI", |
| "Does not use superweapons or advanced tech", |
| "Barely defends base โ minimal turrets placed very late", |
| ], |
| "recommended_counters": [ |
| "Any military force will win โ even 3-4 infantry can overwhelm", |
| "Take your time building economy and army โ no rush needed", |
| "Good difficulty for learning basic game mechanics", |
| "Practice build orders without pressure", |
| ], |
| "typical_army_composition": { |
| "infantry": 1.0, |
| "vehicles": 0.0, |
| "aircraft": 0.0, |
| "ships": 0.0, |
| }, |
| "recent_match_history": [ |
| {"result": "loss", "duration_ticks": 8000, "score": 400}, |
| {"result": "loss", "duration_ticks": 6000, "score": 300}, |
| {"result": "loss", "duration_ticks": 10000, "score": 600}, |
| ], |
| }, |
| "easy": { |
| "difficulty": "Easy", |
| "display_name": "Easy AI", |
| "aggressiveness": "low", |
| "expansion_tendency": "very_low", |
| "unit_diversity": "low", |
| "build_order_quality": "poor", |
| "estimated_win_rate_vs_new_player": 0.25, |
| "typical_first_attack_tick": 80000, |
| "behavioral_traits": [ |
| "Passive โ first attack after ~50 minutes of game time", |
| "Builds basic infantry and some light vehicles (light tanks, APCs)", |
| "No aircraft, no navy, no advanced tech", |
| "Small attack squads of 8-12 units", |
| "Rarely expands beyond starting base", |
| "Slow economy โ 1-2 refineries with 2-4 harvesters", |
| "Repairs buildings slowly (5x slower than normal)", |
| "Moderate construction speed โ 3x slower than normal AI", |
| "Limited unit caps โ cannot mass large armies", |
| "Defenses delayed but eventually builds pillboxes and turrets", |
| ], |
| "recommended_counters": [ |
| "Build a small army of 10-15 units and attack before their defenses solidify", |
| "Any combined arms force (infantry + tanks) will overwhelm them", |
| "Economy is their weakness โ denying resources cripples them further", |
| "No need to rush โ focus on good build order first", |
| ], |
| "typical_army_composition": { |
| "infantry": 0.6, |
| "vehicles": 0.4, |
| "aircraft": 0.0, |
| "ships": 0.0, |
| }, |
| "recent_match_history": [ |
| {"result": "loss", "duration_ticks": 5000, "score": 800}, |
| {"result": "loss", "duration_ticks": 7000, "score": 1200}, |
| {"result": "win", "duration_ticks": 15000, "score": 2500}, |
| ], |
| }, |
| "medium": { |
| "difficulty": "Medium", |
| "display_name": "Medium AI", |
| "aggressiveness": "moderate", |
| "expansion_tendency": "moderate", |
| "unit_diversity": "moderate", |
| "build_order_quality": "decent", |
| "estimated_win_rate_vs_new_player": 0.50, |
| "typical_first_attack_tick": 5000, |
| "behavioral_traits": [ |
| "Moderately aggressive โ sends first attack around tick 5000 (~3 minutes)", |
| "Builds a balanced ground force (infantry, tanks, artillery)", |
| "No aircraft or naval units โ ground-focused only", |
| "Medium-sized attack squads of 20-35 units", |
| "Will expand to a second base if resources allow", |
| "Decent economy โ 2-3 refineries with up to 6 harvesters", |
| "Repairs buildings at normal speed", |
| "Slightly slower construction than Hard/Brutal AI", |
| "Builds advanced tech eventually (tech centers delayed ~8 minutes)", |
| "Uses superweapons if available but slowly", |
| "Limited production capacity โ fewer factories than Hard AI", |
| ], |
| "recommended_counters": [ |
| "Build early defenses โ first attack comes around tick 5000", |
| "Scout by tick 2000 to identify expansion attempts", |
| "Match their economy with 2+ refineries minimum", |
| "Combined arms with anti-armor focus works well", |
| "Their lack of air power means you can skip AA early", |
| "Deny expansion to keep resource advantage", |
| ], |
| "typical_army_composition": { |
| "infantry": 0.35, |
| "vehicles": 0.65, |
| "aircraft": 0.0, |
| "ships": 0.0, |
| }, |
| "recent_match_history": [ |
| {"result": "win", "duration_ticks": 7000, "score": 3200}, |
| {"result": "loss", "duration_ticks": 9000, "score": 3800}, |
| {"result": "win", "duration_ticks": 8000, "score": 4200}, |
| {"result": "loss", "duration_ticks": 10000, "score": 3500}, |
| ], |
| }, |
| "normal": { |
| "difficulty": "Normal", |
| "display_name": "Normal AI", |
| "aggressiveness": "high", |
| "expansion_tendency": "high", |
| "unit_diversity": "high", |
| "build_order_quality": "good", |
| "estimated_win_rate_vs_new_player": 0.65, |
| "typical_first_attack_tick": 1500, |
| "behavioral_traits": [ |
| "Very aggressive โ sends attack waves frequently starting around tick 1500", |
| "Masters all different unit types (infantry, tanks, aircraft, ships)", |
| "Eager to open a second base near your position or mid-way on the map", |
| "Strong economy โ builds 2-3 refineries with multiple harvesters", |
| "Rebuilds destroyed buildings quickly and adapts composition", |
| "Will target your harvesters and exposed, undefended buildings", |
| "Uses combined arms effectively (infantry + vehicles + air strikes)", |
| "Scouts your base early and adjusts strategy based on what you build", |
| ], |
| "recommended_counters": [ |
| "Build early defenses (turrets) at base entrance โ first attack comes ~tick 1500", |
| "Scout early (by tick 500) to find and deny expansion attempts", |
| "Send a small raiding force to destroy their second base before it's established", |
| "Maintain power surplus at all times โ their attacks exploit brownouts", |
| "Build anti-air (SAM/AA Gun) by mid-game to counter their aircraft", |
| "Match their economy: build 2+ refineries minimum to keep up", |
| "Don't turtle โ they will out-expand and out-resource you", |
| ], |
| "typical_army_composition": { |
| "infantry": 0.30, |
| "vehicles": 0.45, |
| "aircraft": 0.15, |
| "ships": 0.10, |
| }, |
| "recent_match_history": [ |
| {"result": "win", "duration_ticks": 8000, "score": 5200}, |
| {"result": "win", "duration_ticks": 6500, "score": 4800}, |
| {"result": "loss", "duration_ticks": 10000, "score": 6100}, |
| {"result": "win", "duration_ticks": 7200, "score": 5500}, |
| {"result": "loss", "duration_ticks": 9000, "score": 4000}, |
| ], |
| }, |
| "hard": { |
| "difficulty": "Hard", |
| "display_name": "Hard AI", |
| "aggressiveness": "very_high", |
| "expansion_tendency": "very_high", |
| "unit_diversity": "very_high", |
| "build_order_quality": "optimal", |
| "estimated_win_rate_vs_new_player": 0.85, |
| "typical_first_attack_tick": 1000, |
| "behavioral_traits": [ |
| "Extremely aggressive โ attacks within first 1000 ticks with combined forces", |
| "Optimal build orders โ wastes no time or resources, perfect macro", |
| "Expands aggressively with multiple bases across the map", |
| "Uses superweapons if tech allows (nuclear missile, iron curtain)", |
| "Coordinates multi-front attacks simultaneously from different angles", |
| "Excellent at resource denial โ prioritizes harvesters and refineries", |
| "Rapid tech progression to advanced units (Mammoth tanks, MiGs)", |
| "Will cheat slightly on resource gathering speed", |
| ], |
| "recommended_counters": [ |
| "MUST build defenses immediately โ turrets before second refinery", |
| "Scout by tick 300 โ their expansion is very fast", |
| "Deny expansions aggressively or you'll be completely out-resourced", |
| "Build multiple production buildings for faster unit output", |
| "Never let power go negative โ they will exploit it ruthlessly", |
| "Mix anti-air into every attack group โ they will use aircraft", |
| "Prepare for superweapons by mid-game โ keep army spread out", |
| ], |
| "typical_army_composition": { |
| "infantry": 0.20, |
| "vehicles": 0.45, |
| "aircraft": 0.25, |
| "ships": 0.10, |
| }, |
| "recent_match_history": [ |
| {"result": "win", "duration_ticks": 5000, "score": 7200}, |
| {"result": "win", "duration_ticks": 4500, "score": 6800}, |
| {"result": "win", "duration_ticks": 6000, "score": 8100}, |
| {"result": "loss", "duration_ticks": 12000, "score": 9500}, |
| {"result": "win", "duration_ticks": 5500, "score": 7500}, |
| ], |
| }, |
| } |
|
|
|
|
| def get_opponent_profile(difficulty: str) -> Optional[dict]: |
| """Get the opponent intelligence profile for a given AI difficulty. |
| |
| Args: |
| difficulty: One of "beginner", "easy", "medium", "normal", "hard". |
| Also accepts "bot_" prefix (strips it). |
| |
| Returns: |
| Profile dict or None if not found. |
| """ |
| clean = difficulty.lower().replace("bot_", "") |
| return AI_PROFILES.get(clean) |
|
|
|
|
| def get_opponent_summary(difficulty: str) -> str: |
| """Get a human-readable scouting report for LLM consumption.""" |
| profile = get_opponent_profile(difficulty) |
| if profile is None: |
| return f"Unknown AI difficulty: {difficulty}" |
|
|
| traits = "\n".join(f" - {t}" for t in profile["behavioral_traits"]) |
| counters = "\n".join(f" - {c}" for c in profile["recommended_counters"]) |
|
|
| wins = sum(1 for m in profile["recent_match_history"] if m["result"] == "win") |
| total = len(profile["recent_match_history"]) |
| avg_score = sum(m["score"] for m in profile["recent_match_history"]) // total |
|
|
| army = profile["typical_army_composition"] |
| army_str = ", ".join(f"{k}: {v:.0%}" for k, v in army.items() if v > 0) |
|
|
| return ( |
| f"## Opponent Scouting Report: {profile['display_name']}\n" |
| f"Aggressiveness: {profile['aggressiveness']}\n" |
| f"Expansion tendency: {profile['expansion_tendency']}\n" |
| f"Unit diversity: {profile['unit_diversity']}\n" |
| f"Build order quality: {profile['build_order_quality']}\n" |
| f"Estimated first attack: ~tick {profile['typical_first_attack_tick']}\n" |
| f"Win rate vs new players: {profile['estimated_win_rate_vs_new_player']:.0%}\n" |
| f"Recent record: {wins}W-{total - wins}L (avg score: {avg_score})\n" |
| f"Typical army mix: {army_str}\n" |
| f"\nBehavioral traits:\n{traits}\n" |
| f"\nRecommended counters:\n{counters}" |
| ) |
|
|