From aaf8ef99b00483fc12928441ff4b0f893354352b Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 8 Sep 2024 14:01:41 +0100 Subject: [PATCH] Add more actions --- clashroyalebuildabot/actions/__init__.py | 32 +++++++++++++++++-- .../actions/archers_action.py | 2 +- clashroyalebuildabot/actions/arrows_action.py | 2 +- clashroyalebuildabot/actions/bats_action.py | 2 +- .../actions/fireball_action.py | 2 +- .../actions/generic/__init__.py | 0 .../actions/{ => generic}/action.py | 0 .../actions/generic/bridge_action.py | 25 +++++++++++++++ .../actions/generic/defense_action.py | 31 ++++++++++++++++++ .../actions/generic/king_action.py | 23 +++++++++++++ .../actions/{ => generic}/overhead_action.py | 2 +- .../actions/{ => generic}/spell_action.py | 6 +++- clashroyalebuildabot/actions/giant_action.py | 2 +- .../actions/goblin_barrel_action.py | 2 +- clashroyalebuildabot/actions/knight_action.py | 14 ++------ .../actions/minions_action.py | 2 +- .../actions/minipekka_action.py | 19 ++--------- .../actions/musketeer_action.py | 2 +- clashroyalebuildabot/actions/witch_action.py | 6 ++++ clashroyalebuildabot/actions/zap_action.py | 2 +- main.py | 24 +++++++------- 21 files changed, 145 insertions(+), 55 deletions(-) create mode 100644 clashroyalebuildabot/actions/generic/__init__.py rename clashroyalebuildabot/actions/{ => generic}/action.py (100%) create mode 100644 clashroyalebuildabot/actions/generic/bridge_action.py create mode 100644 clashroyalebuildabot/actions/generic/defense_action.py create mode 100644 clashroyalebuildabot/actions/generic/king_action.py rename clashroyalebuildabot/actions/{ => generic}/overhead_action.py (88%) rename clashroyalebuildabot/actions/{ => generic}/spell_action.py (84%) create mode 100644 clashroyalebuildabot/actions/witch_action.py diff --git a/clashroyalebuildabot/actions/__init__.py b/clashroyalebuildabot/actions/__init__.py index af8c024..2a828c2 100644 --- a/clashroyalebuildabot/actions/__init__.py +++ b/clashroyalebuildabot/actions/__init__.py @@ -1,3 +1,31 @@ -from .action import Action +from .archers_action import ArchersAction +from .arrows_action import ArrowsAction +from .bats_action import BatsAction +from .cannon_action import CannonAction +from .fireball_action import FireballAction +from .giant_action import GiantAction +from .goblin_barrel_action import GoblinBarrelAction +from .hungry_dragon_action import HungryDragonAction +from .knight_action import KnightAction +from .minions_action import MinionsAction +from .minipekka_action import MinipekkaAction +from .musketeer_action import MusketeerAction +from .witch_action import WitchAction +from .zap_action import ZapAction -__all__ = ["Action"] +__all__ = [ + "ArchersAction", + "ArrowsAction", + "BatsAction", + "CannonAction", + "FireballAction", + "GiantAction", + "GoblinBarrelAction", + "HungryDragonAction", + "KnightAction", + "MinionsAction", + "MinipekkaAction", + "MusketeerAction", + "WitchAction", + "ZapAction", +] diff --git a/clashroyalebuildabot/actions/archers_action.py b/clashroyalebuildabot/actions/archers_action.py index 9177a30..d3e0d94 100644 --- a/clashroyalebuildabot/actions/archers_action.py +++ b/clashroyalebuildabot/actions/archers_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action class ArchersAction(Action): diff --git a/clashroyalebuildabot/actions/arrows_action.py b/clashroyalebuildabot/actions/arrows_action.py index 4c34d4d..30ffafa 100644 --- a/clashroyalebuildabot/actions/arrows_action.py +++ b/clashroyalebuildabot/actions/arrows_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.spell_action import SpellAction +from clashroyalebuildabot.actions.generic.spell_action import SpellAction class ArrowsAction(SpellAction): diff --git a/clashroyalebuildabot/actions/bats_action.py b/clashroyalebuildabot/actions/bats_action.py index 956cf44..44153d0 100644 --- a/clashroyalebuildabot/actions/bats_action.py +++ b/clashroyalebuildabot/actions/bats_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.overhead_action import OverheadAction +from clashroyalebuildabot.actions.generic.overhead_action import OverheadAction class BatsAction(OverheadAction): diff --git a/clashroyalebuildabot/actions/fireball_action.py b/clashroyalebuildabot/actions/fireball_action.py index c64135e..30927ec 100644 --- a/clashroyalebuildabot/actions/fireball_action.py +++ b/clashroyalebuildabot/actions/fireball_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.spell_action import SpellAction +from clashroyalebuildabot.actions.generic.spell_action import SpellAction class FireballAction(SpellAction): diff --git a/clashroyalebuildabot/actions/generic/__init__.py b/clashroyalebuildabot/actions/generic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/clashroyalebuildabot/actions/action.py b/clashroyalebuildabot/actions/generic/action.py similarity index 100% rename from clashroyalebuildabot/actions/action.py rename to clashroyalebuildabot/actions/generic/action.py diff --git a/clashroyalebuildabot/actions/generic/bridge_action.py b/clashroyalebuildabot/actions/generic/bridge_action.py new file mode 100644 index 0000000..59f29c8 --- /dev/null +++ b/clashroyalebuildabot/actions/generic/bridge_action.py @@ -0,0 +1,25 @@ +from clashroyalebuildabot.actions.generic.action import Action + + +class BridgeAction(Action): + """ + If you have 10 elixir, + play this card at the bridge on the side of the weakest tower + """ + + def calculate_score(self, state): + if (self.tile_x, self.tile_y) not in {(3, 15), (14, 15)}: + return [0] + + if state.numbers.elixir.number != 10: + return [0] + + left_hp = state.numbers.left_enemy_princess_hp.number + right_hp = state.numbers.right_enemy_princess_hp.number + if self.tile_x == 3: + score = [1, left_hp > 0, left_hp <= right_hp] + else: + # self.tile_x == 14 + score = [1, right_hp > 0, right_hp <= left_hp] + + return score diff --git a/clashroyalebuildabot/actions/generic/defense_action.py b/clashroyalebuildabot/actions/generic/defense_action.py new file mode 100644 index 0000000..ddd5e46 --- /dev/null +++ b/clashroyalebuildabot/actions/generic/defense_action.py @@ -0,0 +1,31 @@ +from clashroyalebuildabot.actions.generic.action import Action + + +class DefenseAction(Action): + """ + If there are enemies on our side, + play the card in a defensive position + """ + + def calculate_score(self, state): + if (self.tile_x, self.tile_y) not in {(8, 9), (9, 9)}: + return [0] + + lhs = 0 + rhs = 0 + for det in state.enemies: + if det.position.tile_y > 16: + continue + + if det.position.tile_x >= 9: + rhs += 1 + else: + lhs += 1 + + if lhs == rhs == 0: + return [0] + + if lhs >= rhs and self.tile_x == 9: + return [0] + + return [1] diff --git a/clashroyalebuildabot/actions/generic/king_action.py b/clashroyalebuildabot/actions/generic/king_action.py new file mode 100644 index 0000000..3417330 --- /dev/null +++ b/clashroyalebuildabot/actions/generic/king_action.py @@ -0,0 +1,23 @@ +import math + +from clashroyalebuildabot.actions.generic.action import Action + + +class KingAction(Action): + """ + Play the card behind the king, on the side of the closest enemy + """ + + def calculate_score(self, state): + if (self.tile_x, self.tile_y) not in {(8, 0), (9, 0)}: + return [0] + + min_distance = float("inf") + for det in state.enemies: + distance = math.hypot( + det.position.tile_x - self.tile_x, + det.position.tile_y - self.tile_y, + ) + min_distance = min(min_distance, distance) + + return [0.5, -min_distance] diff --git a/clashroyalebuildabot/actions/overhead_action.py b/clashroyalebuildabot/actions/generic/overhead_action.py similarity index 88% rename from clashroyalebuildabot/actions/overhead_action.py rename to clashroyalebuildabot/actions/generic/overhead_action.py index 0313ec7..61c153a 100644 --- a/clashroyalebuildabot/actions/overhead_action.py +++ b/clashroyalebuildabot/actions/generic/overhead_action.py @@ -1,6 +1,6 @@ import math -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action class OverheadAction(Action): diff --git a/clashroyalebuildabot/actions/spell_action.py b/clashroyalebuildabot/actions/generic/spell_action.py similarity index 84% rename from clashroyalebuildabot/actions/spell_action.py rename to clashroyalebuildabot/actions/generic/spell_action.py index 01ed29f..964100f 100644 --- a/clashroyalebuildabot/actions/spell_action.py +++ b/clashroyalebuildabot/actions/generic/spell_action.py @@ -1,10 +1,14 @@ import math -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action from clashroyalebuildabot.namespaces.units import Units class SpellAction(Action): + """ + Play the spell to hit as many enemy units as possible + """ + RADIUS = None MIN_SCORE = 5 UNIT_TO_SCORE = {Units.SKELETON: 1} diff --git a/clashroyalebuildabot/actions/giant_action.py b/clashroyalebuildabot/actions/giant_action.py index d5b1ee2..808bf44 100644 --- a/clashroyalebuildabot/actions/giant_action.py +++ b/clashroyalebuildabot/actions/giant_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action class GiantAction(Action): diff --git a/clashroyalebuildabot/actions/goblin_barrel_action.py b/clashroyalebuildabot/actions/goblin_barrel_action.py index 5cf37d7..fa6669f 100644 --- a/clashroyalebuildabot/actions/goblin_barrel_action.py +++ b/clashroyalebuildabot/actions/goblin_barrel_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action class GoblinBarrelAction(Action): diff --git a/clashroyalebuildabot/actions/knight_action.py b/clashroyalebuildabot/actions/knight_action.py index 8159563..64223ee 100644 --- a/clashroyalebuildabot/actions/knight_action.py +++ b/clashroyalebuildabot/actions/knight_action.py @@ -1,16 +1,6 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.defense_action import DefenseAction -class KnightAction(Action): +class KnightAction(DefenseAction): CARD = Cards.KNIGHT - - def calculate_score(self, state): - score = [0.5] if state.numbers.elixir.number == 10 else [0] - for det in state.enemies: - lhs = det.position.tile_x <= 8 and self.tile_x == 8 - rhs = det.position.tile_x > 8 and self.tile_x == 9 - - if self.tile_y < det.position.tile_y <= 14 and (lhs or rhs): - score = [1, self.tile_y - det.position.tile_y] - return score diff --git a/clashroyalebuildabot/actions/minions_action.py b/clashroyalebuildabot/actions/minions_action.py index 0b2e9c3..0a872e7 100644 --- a/clashroyalebuildabot/actions/minions_action.py +++ b/clashroyalebuildabot/actions/minions_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.overhead_action import OverheadAction +from clashroyalebuildabot.actions.generic.overhead_action import OverheadAction class MinionsAction(OverheadAction): diff --git a/clashroyalebuildabot/actions/minipekka_action.py b/clashroyalebuildabot/actions/minipekka_action.py index 3eb9fc5..5e463ce 100644 --- a/clashroyalebuildabot/actions/minipekka_action.py +++ b/clashroyalebuildabot/actions/minipekka_action.py @@ -1,21 +1,6 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.bridge_action import BridgeAction -class MinipekkaAction(Action): +class MinipekkaAction(BridgeAction): CARD = Cards.MINIPEKKA - - def calculate_score(self, state): - if state.numbers.elixir.number != 10: - return [0] - - left_hp = state.numbers.left_enemy_princess_hp.number - right_hp = state.numbers.right_enemy_princess_hp.number - - if (self.tile_x, self.tile_y) == (3, 15): - return [1, left_hp > 0, left_hp <= right_hp] - - if (self.tile_x, self.tile_y) == (14, 15): - return [1, right_hp > 0, right_hp <= left_hp] - - return [0] diff --git a/clashroyalebuildabot/actions/musketeer_action.py b/clashroyalebuildabot/actions/musketeer_action.py index 26d0ba8..548bd66 100644 --- a/clashroyalebuildabot/actions/musketeer_action.py +++ b/clashroyalebuildabot/actions/musketeer_action.py @@ -1,7 +1,7 @@ import math from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.action import Action +from clashroyalebuildabot.actions.generic.action import Action class MusketeerAction(Action): diff --git a/clashroyalebuildabot/actions/witch_action.py b/clashroyalebuildabot/actions/witch_action.py new file mode 100644 index 0000000..7c99681 --- /dev/null +++ b/clashroyalebuildabot/actions/witch_action.py @@ -0,0 +1,6 @@ +from clashroyalebuildabot import Cards +from clashroyalebuildabot.actions.generic.king_action import KingAction + + +class WitchAction(KingAction): + CARD = Cards.WITCH diff --git a/clashroyalebuildabot/actions/zap_action.py b/clashroyalebuildabot/actions/zap_action.py index 9c4091b..3349576 100644 --- a/clashroyalebuildabot/actions/zap_action.py +++ b/clashroyalebuildabot/actions/zap_action.py @@ -1,5 +1,5 @@ from clashroyalebuildabot import Cards -from clashroyalebuildabot.actions.spell_action import SpellAction +from clashroyalebuildabot.actions.generic.spell_action import SpellAction class ZapAction(SpellAction): diff --git a/main.py b/main.py index 1667cdc..04d8e86 100644 --- a/main.py +++ b/main.py @@ -6,16 +6,14 @@ from loguru import logger -from clashroyalebuildabot.actions.archers_action import ArchersAction -from clashroyalebuildabot.actions.giant_action import GiantAction -from clashroyalebuildabot.actions.goblin_barrel_action import ( - GoblinBarrelAction, -) -from clashroyalebuildabot.actions.knight_action import KnightAction -from clashroyalebuildabot.actions.minions_action import MinionsAction -from clashroyalebuildabot.actions.minipekka_action import MinipekkaAction -from clashroyalebuildabot.actions.musketeer_action import MusketeerAction -from clashroyalebuildabot.actions.zap_action import ZapAction +from clashroyalebuildabot.actions import ArchersAction +from clashroyalebuildabot.actions import CannonAction +from clashroyalebuildabot.actions import GoblinBarrelAction +from clashroyalebuildabot.actions import HungryDragonAction +from clashroyalebuildabot.actions import KnightAction +from clashroyalebuildabot.actions import MinipekkaAction +from clashroyalebuildabot.actions import MusketeerAction +from clashroyalebuildabot.actions import WitchAction from clashroyalebuildabot.bot import Bot start_time = datetime.now() @@ -43,13 +41,13 @@ def update_terminal_title(): def main(): actions = { ArchersAction, - ZapAction, + CannonAction, GoblinBarrelAction, - GiantAction, KnightAction, - MinionsAction, + HungryDragonAction, MinipekkaAction, MusketeerAction, + WitchAction, } try: bot = Bot(actions=actions)