from .game_objects import GameObject
from ._helper_methods import _convert_number
import math
import sys
MAX_NB_OBJECTS = {"Player" : 1, "Enemy": 8, "Reward" : 8, "Consumable" : 8}
MAX_NB_OBJECTS_HUD = {"Player" : 1, "Enemy": 8, "Reward" : 8, "Consumable" : 8, "Score" : 1}
[docs]
class Player(GameObject):
def __init__(self):
super().__init__()
self.rgb = 187, 187, 53
self._xy = 0, 0
self.wh = 8, 11 # at some point 16, 11. advanced other player (obelix) is (6, 11)
self.hud = False
[docs]
class Enemy(GameObject):
def __init__(self):
super().__init__()
self.rgb = 228, 111, 111
self._xy = 0, 0
self.wh = 7, 11
self.hud = False
[docs]
class Score(GameObject):
def __init__(self):
super().__init__()
self.rgb = 187, 187, 53
self._xy = 0, 0
self.wh = 8, 11
self.hud = True
self.value = 0
[docs]
class Lives(GameObject):
def __init__(self):
super().__init__()
self.rgb = 187, 187, 53
self._xy = 0, 0
self.wh = 6, 7
self.hud = True
[docs]
class Consumable(GameObject):
def __init__(self):
super().__init__()
self.rgb = 200, 200, 200 #can have different colors
self._xy = 0, 0
self.wh = 7, 11
self.hud = False
[docs]
class Reward(GameObject):
def __init__(self):
super().__init__()
self.rgb = 200, 200, 200 #can have different colors
self._xy = 0, 0
self.wh = 8, 11
self.hud = False
# parses MAX_NB* dicts, returns default init list of objects
def _get_max_objects(hud=False):
def fromdict(max_obj_dict):
objects = []
mod = sys.modules[__name__]
for k, v in max_obj_dict.items():
for _ in range(0, v):
objects.append(getattr(mod, k)())
return objects
if hud:
return fromdict(MAX_NB_OBJECTS_HUD)
return fromdict(MAX_NB_OBJECTS)
def _init_objects_ram(hud=False):
"""
(Re)Initialize the objects
"""
objects = [Player()]
if hud:
objects.extend([Score(), Lives(), Lives()])
objects += [None for i in range(8)]
return objects
def _detect_objects_asterix_raw(info, ram_state):
info["x_positions"] = ram_state[41:50] # 41 for player, 42 for obj in upper lane...
info["y_player"] = ram_state[39] # from 0 to 7 (8 lanes)
info["score"] = ram_state[94:97] # on ram in decimal/ on screen in hex(like other 2 games)
info["score_dec"] = ram_state[94:97]
info["lives"] = ram_state[83]
info["kind_of_visible_objs"] = ram_state[54] % 8
info["rewards_visible"] = ram_state[73:81]
info["enemy_or_eatable_object"] = ram_state[29:37] % 2 # = 1 for enemy
# info["maybe_useful"] = ram_state[10:18], ram_state[40], ram_state[19:27], ram_state[29:37], ram_state[87],
# ram_state[7]
# not known what they are for exactly
def _detect_objects_ram(objects, ram_state, hud=False):
# player
player = objects[0]
player.xy = ram_state[41], 26 + ram_state[39] * 16
if ram_state[71] < 82:
if ram_state[54] < 5: # asterix playing
player.wh = 8, 11
else: # obelix playing
player.wh = 6, 11
else: # player is wide (is dying)
player.wh = 16, 11
lives_nr = ram_state[83]
#reward_class = (Reward50, Reward100, Reward200, Reward300, Reward400, Reward500) # , Reward500, Reward500)
#eatable_class = (Cauldron, Helmet, Shield, Lamp, Apple, Fish, Meat, Mug)
# get lanes
if hud:
offset = 1 + lives_nr
else:
offset = 1
lanes = objects[offset:]
#const = ram_state[54] % 8
reward_lanes = []
for i in range(8):
if ram_state[18-i] == 11:
objects[offset + i] = None
elif ram_state[73 + i]: # set to lane number if there is reward in that lane
reward_lanes.append(i) # 0-7 instead actual 1-8
if type(lanes[i]) is not Reward:
rew = Reward()
objects[offset + i] = rew
else:
rew = lanes[i]
rew.xy = ram_state[42 + i], 26 + i * 16
elif ram_state[29 + i] % 2 == 1:
if not isinstance(lanes[i], Enemy):
en = Enemy()
objects[offset + i] = en
else:
en = lanes[i]
en.xy = ram_state[42 + i], 26 + i * 16
else:
if type(lanes[i]) is not Consumable:
instance = Consumable()
objects[offset + i] = instance
else:
instance = lanes[i]
instance.xy = ram_state[42 + i] + 1, 26 + i * 16 + 1
if hud:
score = objects[1]
dec_value = _convert_number(ram_state[94]) * 10000 + _convert_number(ram_state[95]) * 100 + _convert_number(
ram_state[96])
score.value = dec_value
if dec_value == 0:
score.xy = 96, 184
score.wh = 6, 7
else:
digits = int(math.log10(dec_value))
score.xy = 96 - digits * 8, 184
score.wh = 6 + digits * 8, 7
if lives_nr >= 2:
lives = objects[2]
if lives is None:
lives = Lives()
objects[2] = lives
lives.xy = 60, 169
lives.wh = 8, 11
elif isinstance(objects[2], Lives):
del objects[2]
if lives_nr >= 3:
lives = objects[3]
if lives is None:
lives = Lives()
objects[3] = lives
lives.xy = 60 + 16, 169
lives.wh = 8, 11
elif isinstance(objects[3], Lives):
del objects[3]