generated from mwc/project_game
Compare commits
2 Commits
95bb89f422
...
c3b2775a80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3b2775a80 | ||
|
|
12d0763a95 |
BIN
__pycache__/dungeon.cpython-310.pyc
Normal file
BIN
__pycache__/dungeon.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/enemies.cpython-310.pyc
Normal file
BIN
__pycache__/enemies.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/map.cpython-310.pyc
Normal file
BIN
__pycache__/map.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/monster_spawner.cpython-310.pyc
Normal file
BIN
__pycache__/monster_spawner.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/player.cpython-310.pyc
Normal file
BIN
__pycache__/player.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/projectile.cpython-310.pyc
Normal file
BIN
__pycache__/projectile.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/strategy.cpython-310.pyc
Normal file
BIN
__pycache__/strategy.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/wall.cpython-310.pyc
Normal file
BIN
__pycache__/wall.cpython-310.pyc
Normal file
Binary file not shown.
49
angband.py
Normal file
49
angband.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# angband.py
|
||||||
|
# ------------
|
||||||
|
# By Pat Wick
|
||||||
|
# This game is a redevelopment of the retro game "Angband". Named after
|
||||||
|
# the stronghold of Morgoth, the Sauron before Sauron in the Lord of the Rings,
|
||||||
|
# the game is a dungeon-crawler adventure game where the player is tasked with
|
||||||
|
# delving into Angband to confront Morgoth. Defeating monsters earns the player
|
||||||
|
# experience points (xp) which allow for more power as the player levels up.
|
||||||
|
# In this, v0.2, a general movement and combat system exists, but level
|
||||||
|
# generation, items, and monster spawning won't happen until future versions.
|
||||||
|
|
||||||
|
from retro.game import Game
|
||||||
|
from player import Player
|
||||||
|
from dungeon import Dungeon
|
||||||
|
from random import sample
|
||||||
|
from wall import Wall
|
||||||
|
from map import (
|
||||||
|
board_edges,
|
||||||
|
inner_board,
|
||||||
|
level_one,
|
||||||
|
random_empty_position
|
||||||
|
)
|
||||||
|
from monster_spawner import MonsterSpawner
|
||||||
|
|
||||||
|
print("Welcome to AngBAD (a poor representation of Angband)!\n")
|
||||||
|
|
||||||
|
race = input("Choose your race (Human, Elf, Dwarf): ").capitalize()
|
||||||
|
while race not in ["Human", "Elf", "Dwarf"]:
|
||||||
|
print("Invalid race. Please choose Human, Elf, or Dwarf.")
|
||||||
|
race = input("Choose your race (Human, Elf, Dwarf): ").capitalize()
|
||||||
|
|
||||||
|
class_ = input("Choose your class (Warrior, Mage, Rogue): ").capitalize()
|
||||||
|
while class_ not in ["Warrior", "Mage", "Rogue"]:
|
||||||
|
print("Invalid class. Please choose Warrior, Mage, or Rogue.")
|
||||||
|
class_ = input("Choose your class (Warrior, Mage, Rogue): ").capitalize()
|
||||||
|
|
||||||
|
print(f"\nYou've chosen to play as a {race} {class_}.")
|
||||||
|
input("Press Enter to continue. Good luck!")
|
||||||
|
|
||||||
|
board_size = (50,25)
|
||||||
|
x,y = board_size
|
||||||
|
|
||||||
|
walls = [Wall(position) for position in board_edges(board_size)]
|
||||||
|
level = [Wall(position) for position in level_one(board_size)]
|
||||||
|
game = Game(walls + level, {"Race":race, "Class":class_,"CharLevel":1,"Floor":1}, board_size = board_size)
|
||||||
|
game.add_agent(MonsterSpawner())
|
||||||
|
game.add_agent(Player((x//2,y//2),race,class_))
|
||||||
|
|
||||||
|
game.play()
|
||||||
27
dungeon.py
Normal file
27
dungeon.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# dungeon.py
|
||||||
|
# ------------
|
||||||
|
# By Pat Wick
|
||||||
|
# This module defines a dungeon generation algorithm. I
|
||||||
|
# still need to figure out what that might actually mean
|
||||||
|
|
||||||
|
class Dungeon:
|
||||||
|
board_size = (10,10)
|
||||||
|
board_width = 10
|
||||||
|
board_height = 10
|
||||||
|
position = (0,0)
|
||||||
|
dungeon_map = [["."] * board_width] * board_height
|
||||||
|
|
||||||
|
|
||||||
|
for row in range(board_height):
|
||||||
|
for col in range(board_width):
|
||||||
|
if row == 0 or row == board_height-1:
|
||||||
|
dungeon_map[row][col] = "#"
|
||||||
|
else:
|
||||||
|
if col == 0 or col == board_width-1:
|
||||||
|
dungeon_map[row][col] = "#"
|
||||||
|
else:
|
||||||
|
dungeon_map[row][col] = "."
|
||||||
|
|
||||||
|
def __init__(self, position):
|
||||||
|
self.position = position
|
||||||
|
self.name = "dungeon"
|
||||||
85
enemies.py
Normal file
85
enemies.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
from strategy import (
|
||||||
|
random_move,
|
||||||
|
move_toward_player,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Orc:
|
||||||
|
"""Scary.
|
||||||
|
"""
|
||||||
|
character = "O"
|
||||||
|
maxHp = 20
|
||||||
|
hp = maxHp
|
||||||
|
deadly = True
|
||||||
|
speed = 25
|
||||||
|
|
||||||
|
def __init__(self,position):
|
||||||
|
self.position = position
|
||||||
|
|
||||||
|
def play_turn(self, game):
|
||||||
|
if game.turn_number % self.speed == 0:
|
||||||
|
move = move_toward_player(self.position, game)
|
||||||
|
if move:
|
||||||
|
x, y = self.position
|
||||||
|
dx, dy = move
|
||||||
|
self.position = (x + dx, y + dy)
|
||||||
|
if self.position == game.get_agent_by_name("player").position:
|
||||||
|
game.state['message'] = "Yum."
|
||||||
|
game.end()
|
||||||
|
|
||||||
|
if self.hp <= 0:
|
||||||
|
game.remove_agent(self)
|
||||||
|
game.get_agent_by_name("player").xp += self.maxHp
|
||||||
|
|
||||||
|
class Rat:
|
||||||
|
"""Not so scary.
|
||||||
|
"""
|
||||||
|
character = "R"
|
||||||
|
maxHp = 2
|
||||||
|
hp = maxHp
|
||||||
|
deadly = True
|
||||||
|
speed = 15
|
||||||
|
|
||||||
|
def __init__(self, position):
|
||||||
|
self.position = position
|
||||||
|
|
||||||
|
def play_turn(self, game):
|
||||||
|
if game.turn_number % self.speed == 0:
|
||||||
|
move = random_move(self.position, game)
|
||||||
|
if move:
|
||||||
|
x, y = self.position
|
||||||
|
dx, dy = move
|
||||||
|
self.position = (x + dx, y + dy)
|
||||||
|
if self.position == game.get_agent_by_name("player").position:
|
||||||
|
game.state['message'] = "Eep."
|
||||||
|
game.end()
|
||||||
|
|
||||||
|
if self.hp <= 0:
|
||||||
|
game.remove_agent(self)
|
||||||
|
game.get_agent_by_name("player").xp += self.maxHp
|
||||||
|
|
||||||
|
class Spider:
|
||||||
|
"""Creepy-crawly.
|
||||||
|
"""
|
||||||
|
character = "S"
|
||||||
|
maxHp = 5
|
||||||
|
hp = maxHp
|
||||||
|
deadly = True
|
||||||
|
speed = 5
|
||||||
|
|
||||||
|
def __init__(self,position):
|
||||||
|
self.position = position
|
||||||
|
|
||||||
|
def play_turn(self, game):
|
||||||
|
if game.turn_number % self.speed == 0:
|
||||||
|
move = random_move(self.position, game)
|
||||||
|
if move:
|
||||||
|
x, y = self.position
|
||||||
|
dx, dy = move
|
||||||
|
self.position = (x + dx, y + dy)
|
||||||
|
if self.position == game.get_agent_by_name("player").position:
|
||||||
|
game.state['message'] = "Hsssss."
|
||||||
|
game.end()
|
||||||
|
|
||||||
|
if self.hp <= 0:
|
||||||
|
game.remove_agent(self)
|
||||||
|
game.get_agent_by_name("player").xp += self.maxHp
|
||||||
70
map.py
Normal file
70
map.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
from retro.game import Game
|
||||||
|
from random import sample
|
||||||
|
from player import Player
|
||||||
|
from wall import Wall
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
def board_edges(board_size):
|
||||||
|
"""The outline of the generated board. Used in angband to surround
|
||||||
|
the level with immovable objects to keep the enemies and player inside
|
||||||
|
"""
|
||||||
|
x,y = board_size
|
||||||
|
positions = []
|
||||||
|
top = [(i,0) for i in range(x)]
|
||||||
|
bottom = [(i,y-1) for i in range(x)]
|
||||||
|
left = [(0,j) for j in range(1,y-1)]
|
||||||
|
right = [(x-1,j) for j in range(1,y-1)]
|
||||||
|
return top + bottom + left + right
|
||||||
|
|
||||||
|
def inner_board(board_size):
|
||||||
|
x,y = board_size
|
||||||
|
positions = []
|
||||||
|
for i in range(1,x-1):
|
||||||
|
for j in range(1,y-1):
|
||||||
|
positions.append((i,j))
|
||||||
|
return positions
|
||||||
|
|
||||||
|
def random_empty_position(game):
|
||||||
|
"""Returns a random empty position.
|
||||||
|
"""
|
||||||
|
agents_by_position = game.get_agents_by_position()
|
||||||
|
while True:
|
||||||
|
x, y = game.board_size
|
||||||
|
i = randint(1, x-2)
|
||||||
|
j = randint(1, y-2)
|
||||||
|
if not agents_by_position[(i,j)]:
|
||||||
|
return (i,j)
|
||||||
|
|
||||||
|
def level_one(board_size):
|
||||||
|
x,y = board_size
|
||||||
|
positions = []
|
||||||
|
for i in range(1,x-1):
|
||||||
|
for j in range(1,y//4):
|
||||||
|
if i <= x // 4 or i >= x - (x // 4):
|
||||||
|
positions.append((i,j))
|
||||||
|
for i in range(1,x//4):
|
||||||
|
for j in range((y - (y // 4)), y-1):
|
||||||
|
positions.append((i,j))
|
||||||
|
|
||||||
|
# Introduce randomness within predefined pattern
|
||||||
|
for _ in range(10): # Example: Add 10 random obstacles
|
||||||
|
rand_i = randint(1, x - 2)
|
||||||
|
rand_j = randint(1, y - 2)
|
||||||
|
positions.append((rand_i, rand_j))
|
||||||
|
|
||||||
|
# for i in range(1,x-1):
|
||||||
|
# for j in range(1,y-1):
|
||||||
|
# if i >=4 and i <= 7 or i >= 13 and i <= 16:
|
||||||
|
# if j >= 4 and j <= 7 or j >= 13 and j <= 16:
|
||||||
|
# positions.append((i,j))
|
||||||
|
return positions
|
||||||
|
|
||||||
|
def level_two(board_size):
|
||||||
|
x,y = board_size
|
||||||
|
positions = []
|
||||||
|
for i in range(1,x-1):
|
||||||
|
for j in range(1,y-1):
|
||||||
|
if i >=4 and i <= 7 or i >= 13 and i <= 16:
|
||||||
|
if j >= 4 and j <= 7 or j >= 13 and j <= 16:
|
||||||
|
positions.append((i,j))
|
||||||
|
return positions
|
||||||
46
monster_spawner.py
Normal file
46
monster_spawner.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# asteroid_spawner.py
|
||||||
|
# -------------------
|
||||||
|
# By MWC Contributors
|
||||||
|
# This module defines an AsteroidSpawner agent class.
|
||||||
|
|
||||||
|
from random import (
|
||||||
|
randint,
|
||||||
|
choices,
|
||||||
|
)
|
||||||
|
from enemies import *
|
||||||
|
from map import random_empty_position
|
||||||
|
|
||||||
|
class MonsterSpawner:
|
||||||
|
display = False
|
||||||
|
floor = 0
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def play_turn(self, game):
|
||||||
|
"""Places each of the monsters on the board for that level.
|
||||||
|
"""
|
||||||
|
toSpawn = self.should_spawn_monsters(game.state["Floor"])
|
||||||
|
|
||||||
|
for i in range(toSpawn):
|
||||||
|
monster = self.choose_monster()(random_empty_position(game))
|
||||||
|
game.add_agent(monster)
|
||||||
|
|
||||||
|
|
||||||
|
def should_spawn_monsters(self, floor_number):
|
||||||
|
"""Returns the number of monsters to spawn, given the player
|
||||||
|
advanced a floor.
|
||||||
|
"""
|
||||||
|
numMonsters = 0
|
||||||
|
if floor_number != self.floor:
|
||||||
|
numMonsters = randint(1, floor_number // 10 + 3)
|
||||||
|
self.floor = floor_number
|
||||||
|
return numMonsters
|
||||||
|
|
||||||
|
def choose_monster(self):
|
||||||
|
"""Picks a random monster out of a weighted list of monsters.
|
||||||
|
"""
|
||||||
|
monsters = [Orc, Rat, Spider]
|
||||||
|
monster = choices(monsters, weights = (10, 30, 60))
|
||||||
|
monster = monster[0]
|
||||||
|
return monster
|
||||||
120
player.py
Normal file
120
player.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
# player.py
|
||||||
|
# ------------
|
||||||
|
# By Pat Wick
|
||||||
|
# This module defines a player agent class. This is intended
|
||||||
|
# to be used in an implementation of an adventure game but could
|
||||||
|
# generally be adapted for other player character uses.
|
||||||
|
|
||||||
|
from retro.agent import ArrowKeyAgent
|
||||||
|
from retro.game import Game
|
||||||
|
from projectile import Projectile
|
||||||
|
|
||||||
|
class Player:
|
||||||
|
name = "player"
|
||||||
|
level = 1
|
||||||
|
xp = 0
|
||||||
|
direction = (1,0)
|
||||||
|
class_ = ""
|
||||||
|
speed = 0
|
||||||
|
damage = 0
|
||||||
|
|
||||||
|
def __init__(self, position, race, class_):
|
||||||
|
"""Class and race will determine player stats and abilities.
|
||||||
|
"""
|
||||||
|
self.position = position
|
||||||
|
self.race = race
|
||||||
|
self.class_ = class_
|
||||||
|
if class_.capitalize() == "Warrior":
|
||||||
|
self.color = "red"
|
||||||
|
self.class_ == class_
|
||||||
|
elif class_.capitalize() == "Rogue":
|
||||||
|
self.color = "green"
|
||||||
|
self.class_ == class_
|
||||||
|
else:
|
||||||
|
self.color = "blue"
|
||||||
|
self.class_ == class_
|
||||||
|
|
||||||
|
if race.capitalize() == "Human":
|
||||||
|
self.character = "H"
|
||||||
|
self.speed = 3
|
||||||
|
self.damage = int(2 + (self.level / 3))
|
||||||
|
elif race.capitalize() == "Elf":
|
||||||
|
self.character = "E"
|
||||||
|
self.speed = 1
|
||||||
|
self.damage = int(1 + (self.level / 4))
|
||||||
|
else:
|
||||||
|
self.character = "D"
|
||||||
|
self.speed = 6
|
||||||
|
self.damage = int(3 + (self.level / 2))
|
||||||
|
|
||||||
|
def attack(self,game):
|
||||||
|
"""Warrior is a melee character, mage and rogue use ranged attacks.
|
||||||
|
"""
|
||||||
|
# if self.class_ == "Warrior":
|
||||||
|
# if game.turn_number % self.speed == 0:
|
||||||
|
# agent = self.get_agent_in_position((self.position[0] + self.direction[0],self.position[1] + self.direction[1]),game)
|
||||||
|
# if agent:
|
||||||
|
# if agent.deadly:
|
||||||
|
# agent.hp -= game.get_agent_by_name("player").damage * 2
|
||||||
|
# else:
|
||||||
|
projectile = Projectile((self.position[0] + self.direction[0],self.position[1] + self.direction[1]), self.direction, self.speed, game)
|
||||||
|
game.add_agent(projectile)
|
||||||
|
#print("pew pew pew")
|
||||||
|
|
||||||
|
def handle_keystroke(self, keystroke, game):
|
||||||
|
x, y = self.position
|
||||||
|
if keystroke.name in ("KEY_LEFT", "KEY_RIGHT"):
|
||||||
|
if keystroke.name == "KEY_LEFT":
|
||||||
|
new_position = (x - 1, y)
|
||||||
|
self.direction = (-1,0)
|
||||||
|
else:
|
||||||
|
new_position = (x + 1, y)
|
||||||
|
self.direction = (1,0)
|
||||||
|
if game.on_board(new_position):
|
||||||
|
self.try_to_move(new_position,game)
|
||||||
|
if game.is_empty(new_position):
|
||||||
|
self.position = new_position
|
||||||
|
|
||||||
|
if keystroke.name in ("KEY_DOWN", "KEY_UP"):
|
||||||
|
if keystroke.name == "KEY_DOWN":
|
||||||
|
new_position = (x, y + 1)
|
||||||
|
self.direction = (0,1)
|
||||||
|
else:
|
||||||
|
new_position = (x, y - 1)
|
||||||
|
self.direction = (0,-1)
|
||||||
|
if game.on_board(new_position):
|
||||||
|
self.try_to_move(new_position,game)
|
||||||
|
if game.is_empty(new_position):
|
||||||
|
self.position = new_position
|
||||||
|
|
||||||
|
if keystroke == " ":
|
||||||
|
self.attack(game)
|
||||||
|
|
||||||
|
def try_to_move(self, position, game):
|
||||||
|
"""Check if player moved into an enemy and loses.
|
||||||
|
"""
|
||||||
|
agent = self.get_agent_in_position(position,game)
|
||||||
|
if agent:
|
||||||
|
if agent.deadly:
|
||||||
|
game.state['message'] = "Monsters can be deadly..."
|
||||||
|
game.end()
|
||||||
|
|
||||||
|
|
||||||
|
def get_agent_in_position(self, position, game):
|
||||||
|
"""Checks a location for current agents.
|
||||||
|
"""
|
||||||
|
agents = game.get_agents_by_position()[position]
|
||||||
|
if agents:
|
||||||
|
return agents[0]
|
||||||
|
|
||||||
|
def level_up(self):
|
||||||
|
"""Player levelup is managed by an xp curve.
|
||||||
|
"""
|
||||||
|
xpToLevel = (self.level + self.level - 1) * 20
|
||||||
|
if self.xp >= xpToLevel:
|
||||||
|
self.xp -= xpToLevel
|
||||||
|
self.level += 1
|
||||||
|
|
||||||
|
def play_turn(self,game):
|
||||||
|
self.level_up()
|
||||||
|
game.state["Level"] = self.level
|
||||||
7
poetry.lock
generated
Normal file
7
poetry.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||||
|
package = []
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
lock-version = "2.0"
|
||||||
|
python-versions = "^3.10"
|
||||||
|
content-hash = "53f2eabc9c26446fbcc00d348c47878e118afc2054778c3c803a0a8028af27d9"
|
||||||
75
projectile.py
Normal file
75
projectile.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# projectile.py
|
||||||
|
# ------------
|
||||||
|
# By Pat Wick
|
||||||
|
# This module defines a "casted" projectile. This is the basis
|
||||||
|
# for ranged character types' attacks.
|
||||||
|
|
||||||
|
from retro.game import Game
|
||||||
|
|
||||||
|
class Projectile:
|
||||||
|
character = "*"
|
||||||
|
deadly = False
|
||||||
|
|
||||||
|
def __init__(self, position, direction, speed, game):
|
||||||
|
self.position = position
|
||||||
|
self.direction = direction
|
||||||
|
self.speed = speed
|
||||||
|
if game.get_agent_by_name("player").class_ == "Rogue":
|
||||||
|
if self.direction in [(1,0), (-1,0)]:
|
||||||
|
self.character = "-"
|
||||||
|
elif self.direction in [(0,1), (0,-1)]:
|
||||||
|
self.character = "|"
|
||||||
|
if game.get_agent_by_name("player").class_ == "Warrior":
|
||||||
|
if self.direction in [(0,1), (0,-1)]:
|
||||||
|
self.character = "|"
|
||||||
|
elif self.direction == (1,0):
|
||||||
|
self.character = "/"
|
||||||
|
else:
|
||||||
|
self.character = "\\"
|
||||||
|
|
||||||
|
def move(self, game):
|
||||||
|
"""Try to move in direction set by player when launched. If blocked,
|
||||||
|
disappear. If projectile hits an enemy, lower hp by damage.
|
||||||
|
"""
|
||||||
|
dx, dy = self.direction
|
||||||
|
new_position = (self.position[0] + dx, self.position[1] + dy)
|
||||||
|
if game.on_board(new_position):
|
||||||
|
if game.is_empty(new_position):
|
||||||
|
self.position = new_position
|
||||||
|
else:
|
||||||
|
agent = self.get_agent_in_position(new_position,game)
|
||||||
|
if agent:
|
||||||
|
if agent.deadly:
|
||||||
|
agent.hp -= game.get_agent_by_name("player").damage
|
||||||
|
game.remove_agent(self)
|
||||||
|
else:
|
||||||
|
game.remove_agent(self)
|
||||||
|
else:
|
||||||
|
game.remove_agent(self)
|
||||||
|
|
||||||
|
def play_turn(self,game):
|
||||||
|
"""Speed of projectiles depends on character race.
|
||||||
|
"""
|
||||||
|
if game.turn_number % self.speed == 0:
|
||||||
|
self.move(game)
|
||||||
|
try:
|
||||||
|
if game.get_agent_by_name("player").class_ == "Warrior":
|
||||||
|
game.remove_agent(self)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_agent_in_position(self, position, game):
|
||||||
|
"""Returns an agent at the position, or returns None.
|
||||||
|
game.get_agents_by_position always returns a list, which may
|
||||||
|
contain zero, one, or multiple agents at the given position.
|
||||||
|
In the Beast game, we never allow more than one agent to be in
|
||||||
|
a position.
|
||||||
|
"""
|
||||||
|
agents = game.get_agents_by_position()[position]
|
||||||
|
if agents:
|
||||||
|
return agents[0]
|
||||||
|
|
||||||
|
def handle_collision(self, game):
|
||||||
|
# need to fix this at some point
|
||||||
|
pass
|
||||||
57
strategy.py
Normal file
57
strategy.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
from random import choice
|
||||||
|
|
||||||
|
direction_vectors = [(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||||
|
|
||||||
|
def possible_moves(position, game):
|
||||||
|
"Returns a list of vectors to empty spaces"
|
||||||
|
agents_by_position = game.get_agents_by_position()
|
||||||
|
possible_moves = []
|
||||||
|
for vector in direction_vectors:
|
||||||
|
x, y = position
|
||||||
|
dx, dy = vector
|
||||||
|
new_position = (x + dx, y + dy)
|
||||||
|
if not agents_by_position[new_position]:
|
||||||
|
possible_moves.append(vector)
|
||||||
|
return possible_moves
|
||||||
|
|
||||||
|
def random_move(position, game):
|
||||||
|
"Returns a random vector representing a move to an empty space from position"
|
||||||
|
moves = possible_moves(position, game)
|
||||||
|
if moves:
|
||||||
|
return choice(moves)
|
||||||
|
|
||||||
|
def distance(p0, p1):
|
||||||
|
"""Returns the 'manhattan distance' from one position to another
|
||||||
|
The 'manhattan distance' describes the distance from one point to another
|
||||||
|
on a city grid, where you can only go horizontally and vertically, not
|
||||||
|
diagonally.
|
||||||
|
"""
|
||||||
|
x0, y0 = p0
|
||||||
|
x1, y1 = p1
|
||||||
|
return abs(x1 - x0) + abs(y1 - y0)
|
||||||
|
|
||||||
|
def move_toward_player(position, game):
|
||||||
|
"Returns a move which will come closest to the player"
|
||||||
|
player_position = game.get_agent_by_name("player").position
|
||||||
|
moves = possible_moves(position, game)
|
||||||
|
moves_with_distance = []
|
||||||
|
for vector in moves:
|
||||||
|
x, y = position
|
||||||
|
dx, dy = vector
|
||||||
|
new_position = (x + dx, y + dy)
|
||||||
|
distance_to_player = distance(new_position, player_position)
|
||||||
|
moves_with_distance.append((distance_to_player, vector))
|
||||||
|
if moves_with_distance:
|
||||||
|
shortest_distance, best_move = sorted(moves_with_distance)[0]
|
||||||
|
return best_move
|
||||||
|
|
||||||
|
def move_to_player(position, game):
|
||||||
|
player_position = game.get_agent_by_name("player").position
|
||||||
|
for vector in direction_vectors:
|
||||||
|
x, y = position
|
||||||
|
dx, dy = vector
|
||||||
|
new_position = (x + dx, y + dy)
|
||||||
|
if new_position == player_position:
|
||||||
|
return vector
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user