Skip to content

Commit

Permalink
Merge pull request #41 from Pbatch/pb_redo_unit_state
Browse files Browse the repository at this point in the history
Pb redo unit state
  • Loading branch information
Pbatch authored Jul 4, 2022
2 parents ce8735e + 9663e8c commit 9755a2a
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 152 deletions.
19 changes: 6 additions & 13 deletions clashroyalebuildabot/bot/pete/pete_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ def _distance(x1, y1, x2, y2):
def _calculate_building_score(self, units):
score = [0, 0, 0]

n_enemies = sum([len(v)
for k, v in units.items() if k[:5] == 'enemy'])
n_enemies = sum([len(v) for k, v in units['enemy'].items()])

# Play defensively if the enemy has a unit in our half
if n_enemies != 0:
rhs = 0
lhs = 0
for k, v in units.items():
if k[:4] == 'ally':
continue
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if tile_x > 8 and tile_y <= 17:
Expand Down Expand Up @@ -50,18 +48,15 @@ def _calculate_troop_score(self, units):
score = [0.5, 0, 0]

# Play aggressively if the enemy has no units
n_enemies = sum([len(v)
for k, v in units.items() if k[:5] == 'enemy'])
n_enemies = sum([len(v) for k, v in units['enemy'].items()])
if self.target == 'buildings' and n_enemies == 0:
score[0] = 1

# Play defensively if the enemy has a unit in our half
elif n_enemies != 0:
rhs = 0
lhs = 0
for k, v in units.items():
if k[:4] == 'ally':
continue
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if tile_x > 8 and tile_y <= 17:
Expand All @@ -87,9 +82,7 @@ def _calculate_spell_score(self, units):
C is the negative distance to the furthest unit
"""
score = [0, 0, 0]
for k, v in units.items():
if k[:4] == 'ally':
continue
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
# Assume the unit will move down a space
Expand Down
19 changes: 10 additions & 9 deletions clashroyalebuildabot/bot/pete/pete_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ def _preprocess(self):
Estimate the tile of each unit to be the bottom of their bounding box
"""
for k, v in self.state['units'].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)
for side in ['ally', 'enemy']:
for k, v in self.state['units'][side].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)

def run(self):
while True:
Expand Down
16 changes: 6 additions & 10 deletions clashroyalebuildabot/bot/standard/standard_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def _calculate_knight_score(self, state):
Play the knight in the center, vertically aligned with the troop
"""
score = [0] if state['numbers']['elixir']['number'] != 10 else [0.5]
for k, v in state['units'].items():
for k, v in state['units']['enemy'].items():
if k[:4] == 'ally':
continue
for unit in v['positions']:
Expand All @@ -59,9 +59,7 @@ def _calculate_minions_score(self, state):
Only play minions on top of enemy units
"""
score = [0] if state['numbers']['elixir']['number'] != 10 else [0.5]
for k, v in state['units'].items():
if k[:4] == 'ally':
continue
for k, v in state['units']['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
distance = self._distance(tile_x, tile_y, self.tile_x, self.tile_y)
Expand All @@ -74,24 +72,22 @@ def _calculate_fireball_score(self, state):
Only play fireball if at least 3 units will be hit
Try to hit as many units as possible
"""
return self._calculate_spell_score(state['units'], radius=2.5, min_to_hit=3)
return self._calculate_spell_score(state['units']['enemy'], radius=2.5, min_to_hit=3)

def _calculate_arrows_score(self, state):
"""
Only play arrows if at least 5 units will be hit
Try to hit as many units as possible
"""
return self._calculate_spell_score(state['units'], radius=4, min_to_hit=5)
return self._calculate_spell_score(state['units']['enemy'], radius=4, min_to_hit=5)

def _calculate_archers_score(self, state):
"""
Only play the archers if there is a troop on our side of the battlefield
Play the archers in the center, vertically aligned with the troop
"""
score = [0] if state['numbers']['elixir']['number'] != 10 else [0.5]
for k, v in state['units'].items():
if k[:4] == 'ally':
continue
for k, v in state['units']['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if self.tile_y < tile_y <= 14:
Expand Down Expand Up @@ -136,7 +132,7 @@ def _calculate_musketeer_score(self, state):
That should be just within her range
"""
score = [0]
for k, v in state['units'].items():
for k, v in state['units']['enemy'].items():
if k[:4] == 'ally':
continue
for unit in v['positions']:
Expand Down
21 changes: 11 additions & 10 deletions clashroyalebuildabot/bot/standard/standard_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ def _preprocess(self):
Estimate the tile of each unit to be the bottom of their bounding box
"""
for k, v in self.state['units'].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)
for side in ['ally', 'enemy']:
for k, v in self.state['units'][side].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)

def run(self):
while True:
Expand All @@ -49,4 +50,4 @@ def run(self):
self.play_action(action)
# Log the result
print(f'Playing {action} with score {action.score} and sleeping for 1 second')
time.sleep(1.0)
time.sleep(0.5)
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ def _distance(x1, y1, x2, y2):
return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5

def _calculate_enemy_troops(self, state):
for k, v in state['units'].items():
if k[:4] == 'ally':
continue
for k, v in state['units']['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if self.tile_y < tile_y <= 14:
Expand All @@ -26,9 +24,7 @@ def _calculate_hog_rider_score(self, state):
Place hog rider on the bridge as high up as possible
Try to target the lowest hp tower
"""
for k, v in state['units'].items():
if k[:4] == 'ally':
continue
for k, v in state['units']['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if self.tile_y < tile_y <= 14:
Expand Down Expand Up @@ -57,14 +53,15 @@ def _calculate_cannon_score(self, state):
"""

score = [0]
for k, v in state['units'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if v['transport'] == 'ground':
if tile_y >= 10:
if 8 < self.tile_x < 10:
if self.tile_y == 10:
score = [2]
for side in ['ally', 'enemy']:
for k, v in state['units'][side].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if v['transport'] == 'ground':
if tile_y >= 10:
if 8 < self.tile_x < 10:
if self.tile_y == 10:
score = [2]
return score

def _calculate_musketeer_score(self, state):
Expand All @@ -74,11 +71,12 @@ def _calculate_musketeer_score(self, state):
That should be just within her range and not too close to the enemy
"""
score = [0]
for k, v in state['units'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if v['transport'] == 'air' and self.tile_y == tile_y - 7:
score = [2]
for side in ['ally', 'enemy']:
for k, v in state['units'][side].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if v['transport'] == 'air' and self.tile_y == tile_y - 7:
score = [2]
return score

def _calculate_ice_golem_score(self, state):
Expand All @@ -87,16 +85,17 @@ def _calculate_ice_golem_score(self, state):
arena one tile away from the enemy
"""
score = [0]
for k, v in state['units'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if (18 >= tile_y >= 15) and (v['transport'] == 'ground'):
if tile_x > 8:
if self.tile_y == 14 and self.tile_x == 8:
score = [2]
if tile_x <= 8:
if self.tile_y == 14 and self.tile_x == 9:
score = [2]
for side in ['ally', 'enemy']:
for k, v in state['units'][side].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if (18 >= tile_y >= 15) and (v['transport'] == 'ground'):
if tile_x > 8:
if self.tile_y == 14 and self.tile_x == 8:
score = [2]
if tile_x <= 8:
if self.tile_y == 14 and self.tile_x == 9:
score = [2]

return score

Expand All @@ -106,16 +105,17 @@ def _calculate_ice_spirit_score(self, state):
"""
score = [0] if state['numbers']['elixir']['number'] != 10 else [0.5]
score = [0]
for k, v in state['units'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if (18 >= tile_y >= 15) and (v['transport'] == 'ground'):
if tile_x > 8:
if self.tile_y == 10 and self.tile_x == 8:
score = [2]
if tile_x <= 8:
if self.tile_y == 10 and self.tile_x == 9:
score = [2]
for side in ['ally', 'enemy']:
for k, v in state['units'][side].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if (18 >= tile_y >= 15) and (v['transport'] == 'ground'):
if tile_x > 8:
if self.tile_y == 10 and self.tile_x == 8:
score = [2]
if tile_x <= 8:
if self.tile_y == 10 and self.tile_x == 9:
score = [2]

return score

Expand All @@ -129,9 +129,7 @@ def _calculate_spell_score(self, units, radius, min_to_hit):
C is the negative distance to the furthest unit
"""
score = [0, 0, 0]
for k, v in units.items():
if k[:4] == 'ally':
continue
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
# Assume the unit will move down a few spaces
Expand All @@ -155,9 +153,7 @@ def _calculate_log_score(self, state):
"""
units = state['units']
score = [0]
for k, v in units.items():
if k[:4] == 'ally':
break
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if tile_y <= 8 and v['transport'] == 'ground':
Expand All @@ -172,10 +168,10 @@ def _calculate_fireball_score(self, state):
"""
units = state['units']
score = [0]
for k, v in units.items():
for k, v in units['enemy'].items():
for unit in v['positions']:
tile_x, tile_y = unit['tile_xy']
if v['transport'] == 'air':
if v['transport'] == 'air':
if self.tile_y == tile_y - 4 and self.tile_x == tile_x:
score = [1]
return score
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ def _preprocess(self):
Estimate the tile of each unit to be the bottom of their bounding box
"""
for k, v in self.state['units'].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)
for side in ['ally', 'enemy']:
for k, v in self.state['units'][side].items():
for unit in v['positions']:
bbox = unit['bounding_box']
bbox[0] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[1] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox[2] *= DISPLAY_WIDTH / SCREENSHOT_WIDTH
bbox[3] *= DISPLAY_HEIGHT / SCREENSHOT_HEIGHT
bbox_bottom = [((bbox[0] + bbox[2]) / 2), bbox[3]]
unit['tile_xy'] = self._get_nearest_tile(*bbox_bottom)

def run(self):
while True:
Expand Down
Loading

0 comments on commit 9755a2a

Please sign in to comment.