X-Git-Url: https://git.ctpug.org.za/?p=erdslangetjie.git;a=blobdiff_plain;f=erdslangetjie%2Fplayer.py;h=841b5097b0f938121059b55625e3bf255bc9918a;hp=6fc26e887dcd2a4e057293e3dbe204b49024acd3;hb=HEAD;hpb=191d328780140fad352f168ecb03069f10b4459b diff --git a/erdslangetjie/player.py b/erdslangetjie/player.py index 6fc26e8..841b509 100644 --- a/erdslangetjie/player.py +++ b/erdslangetjie/player.py @@ -1,30 +1,107 @@ # Player and Player-like objects +from erdslangetjie.data import load_image, load_sound -from erdslangetjie.data import load_image - -class PlayerSprite(object): +class GameSprite(object): def __init__(self): self.pos = (0, 0) self.sprite = None - def move(self, direction): - self.pos = (self.pos[0] + direction[0], self.pos[1] + direction[1]) - def get_image(self): return self.sprite + def get_texture(self): + return self.sprite.texture + + +class FigureSprite(GameSprite): -class ThePlayer(PlayerSprite): + def can_move(self, direction, level): + '''Check if we can move in the given direction''' + cand_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1]) + return not level.blocked(cand_pos) + + +class ThePlayer(FigureSprite): def __init__(self): super(ThePlayer, self).__init__() self.sprite = load_image('sprites/player.png') + def move(self, direction, level): + if self.can_move(direction, level): + self.pos = (self.pos[0] + direction[0], self.pos[1] + direction[1]) + return True + return False -class Nemesis(PlayerSprite): - def __init__(self): - super(ThePlayer, self).__init__() +class Nemesis(FigureSprite): + + def __init__(self, config): + super(Nemesis, self).__init__() self.sprite = load_image('sprites/nemesis.png') + self.reset_pos() + self._config = config + self._deadends = set([]) + self._been = {} + self._bend = load_sound('sounds/bend.ogg') + + def move(self, level, player_pos): + if not self.on_board(): + # Advance towards the map a step at a time + self.pos = (self.pos[0] + 1, self.pos[1]) + if self.on_board(): + self.pos = level.enter_pos + return + # AI goes here + # First, if we're standing next to a gate, we attack it + neighbours = [(self.pos[0] + 1, self.pos[1]), + (self.pos[0] - 1, self.pos[1]), + (self.pos[0], self.pos[1] + 1), + (self.pos[0], self.pos[1] - 1)] + for cand in neighbours: + if level.is_gate(cand) and level.blocked(cand): + level.damage_gate(cand) + if self._config.getdefault('bane', 'sound', '0') != '0': + self._bend.play() + return + # check for dead-ends + if self._in_dead_end(level): + self._deadends.add(self.pos) + self._been.setdefault(self.pos, 0) + mindist = 999999 + best_pos = None + for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]: + new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1]) + if new_pos in self._deadends: + continue + if self.can_move(direction, level): + # We weigh stuff by the number of times we've stepped there, to + # avoid certain types of loop + dist = (level.calc_dist(new_pos, player_pos) + + self._been.get(new_pos, 0)) + if dist < mindist: + mindist = dist + best_pos = new_pos + if best_pos: + self._been[self.pos] += 1 + self.pos = best_pos + + def reset_pos(self): + self.pos = (-7, 0) + self._deadends = set([]) + self._been = {} + + def on_board(self): + return self.pos[0] >= 0 + + def _in_dead_end(self, level): + # Check if this is a dead end + blocked = 0 + for direction in [(1, 0), (-1, 0), (0, -1), (0, 1)]: + new_pos = (self.pos[0] + direction[0], self.pos[1] + direction[1]) + if level.is_wall(new_pos) or new_pos in self._deadends: + blocked += 1 + # A dead end has only 1 exit, and recurse back from there + return blocked >= 3