Initial commit
This commit is contained in:
0
retro_gamer/examples/beast/agents/__init__.py
Normal file
0
retro_gamer/examples/beast/agents/__init__.py
Normal file
67
retro_gamer/examples/beast/agents/beast.py
Normal file
67
retro_gamer/examples/beast/agents/beast.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from retro_gamer.examples.beast.helpers import add, distance, get_occupant
|
||||
from random import random, choice
|
||||
|
||||
class Beast:
|
||||
"""A beast that hunts the player."""
|
||||
character = "H"
|
||||
color = "red"
|
||||
probability_of_moving = 0.03
|
||||
probability_of_random_move = 0.2
|
||||
deadly = True
|
||||
|
||||
def __init__(self, position):
|
||||
self.position = position
|
||||
|
||||
def handle_push(self, vector, game):
|
||||
future_position = add(self.position, vector)
|
||||
on_board = game.on_board(future_position)
|
||||
obstacle = get_occupant(game, future_position)
|
||||
if obstacle or not on_board:
|
||||
self.die(game)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def play_turn(self, game):
|
||||
if self.should_move():
|
||||
possible_moves = []
|
||||
for position in self.get_adjacent_positions():
|
||||
if game.is_empty(position) and game.on_board(position):
|
||||
possible_moves.append(position)
|
||||
if possible_moves:
|
||||
if self.should_move_randomly():
|
||||
self.position = choice(possible_moves)
|
||||
else:
|
||||
self.position = self.choose_best_move(possible_moves, game)
|
||||
player = game.get_agent_by_name("player")
|
||||
if player and player.position == self.position:
|
||||
player.die(game)
|
||||
|
||||
def get_adjacent_positions(self):
|
||||
"""Returns all eight adjacent positions, including diagonals."""
|
||||
positions = []
|
||||
for i in [-1, 0, 1]:
|
||||
for j in [-1, 0, 1]:
|
||||
if i or j:
|
||||
positions.append(add(self.position, (i, j)))
|
||||
return positions
|
||||
|
||||
def should_move(self):
|
||||
return random() < self.probability_of_moving
|
||||
|
||||
def should_move_randomly(self):
|
||||
return random() < self.probability_of_random_move
|
||||
|
||||
def choose_best_move(self, possible_moves, game):
|
||||
player = game.get_agent_by_name("player")
|
||||
move_distances = [[distance(player.position, move), move] for move in possible_moves]
|
||||
shortest_distance, best_move = sorted(move_distances)[0]
|
||||
return best_move
|
||||
|
||||
def die(self, game):
|
||||
game.remove_agent(self)
|
||||
game.num_beasts -= 1
|
||||
game.state['beasts_killed'] += 1
|
||||
if game.num_beasts == 0:
|
||||
game.state["message"] = "You win!"
|
||||
game.end()
|
||||
25
retro_gamer/examples/beast/agents/block.py
Normal file
25
retro_gamer/examples/beast/agents/block.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from retro_gamer.examples.beast.helpers import add, get_occupant
|
||||
|
||||
class Block:
|
||||
"""A static block that can be pushed by the player."""
|
||||
character = "█"
|
||||
color = "green4"
|
||||
deadly = False
|
||||
|
||||
def __init__(self, position):
|
||||
self.position = position
|
||||
|
||||
def handle_push(self, vector, game):
|
||||
"""Responds to a push in the direction of vector.
|
||||
Returns True when the push succeeds in creating empty space.
|
||||
"""
|
||||
future_position = add(self.position, vector)
|
||||
on_board = game.on_board(future_position)
|
||||
obstacle = get_occupant(game, future_position)
|
||||
if obstacle:
|
||||
success = obstacle.handle_push(vector, game)
|
||||
else:
|
||||
success = on_board
|
||||
if success:
|
||||
self.position = future_position
|
||||
return success
|
||||
39
retro_gamer/examples/beast/agents/player.py
Normal file
39
retro_gamer/examples/beast/agents/player.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from retro_gamer.examples.beast.helpers import add, get_occupant
|
||||
|
||||
direction_vectors = {
|
||||
"KEY_RIGHT": (1, 0),
|
||||
"KEY_UP": (0, -1),
|
||||
"KEY_LEFT": (-1, 0),
|
||||
"KEY_DOWN": (0, 1),
|
||||
}
|
||||
|
||||
class Player:
|
||||
character = "*"
|
||||
color = "white"
|
||||
name = "player"
|
||||
deadly = False
|
||||
|
||||
def __init__(self, position):
|
||||
self.position = position
|
||||
|
||||
def handle_keystroke(self, keystroke, game):
|
||||
if keystroke.name in direction_vectors:
|
||||
vector = direction_vectors[keystroke.name]
|
||||
self.try_to_move(vector, game)
|
||||
|
||||
def try_to_move(self, vector, game):
|
||||
future_position = add(self.position, vector)
|
||||
on_board = game.on_board(future_position)
|
||||
obstacle = get_occupant(game, future_position)
|
||||
if obstacle:
|
||||
if obstacle.deadly:
|
||||
self.die(game)
|
||||
elif obstacle.handle_push(vector, game):
|
||||
self.position = future_position
|
||||
elif on_board:
|
||||
self.position = future_position
|
||||
|
||||
def die(self, game):
|
||||
self.color = "black_on_red"
|
||||
game.state["message"] = "The beasties win!"
|
||||
game.end()
|
||||
Reference in New Issue
Block a user