code refactor - change var names & dir structure
This commit is contained in:
parent
e0cd0a5d85
commit
42aec48676
47
actions.py
47
actions.py
@ -1,47 +0,0 @@
|
||||
# Funkcja konwertujaca wspolrzedne nastepnego pola do odwiedzenia
|
||||
|
||||
# pole to element wziety z kolejki path
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
|
||||
def actionsInterpreter(actionIndex, defaultState, directions):
|
||||
|
||||
if actionIndex == -1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().counterClockwise()
|
||||
)
|
||||
elif actionIndex == 0:
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if defaultState.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif defaultState.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif defaultState.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif defaultState.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
return AgentState(
|
||||
defaultState.get_x() + move_x, # directions[defaultState.get_direction()[0]], - is not subscriptable ???
|
||||
defaultState.get_y() + move_y, # directions[defaultState.get_direction()][1], - is not subscriptable ???
|
||||
defaultState.get_direction()
|
||||
)
|
||||
elif actionIndex == 1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().clockwise()
|
||||
)
|
||||
else:
|
||||
return defaultState
|
||||
|
||||
|
||||
actions = {
|
||||
"rotateLeft": -1,
|
||||
"moveForward": 0,
|
||||
"rotateRight": 1
|
||||
}
|
325
hero.py
325
hero.py
@ -1,325 +0,0 @@
|
||||
import random
|
||||
import heapq
|
||||
|
||||
from mesa import Agent
|
||||
|
||||
from othercharacters import dice, Box, Creature, Armor, Weapon
|
||||
from actions import actions, actionsInterpreter
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
from node import Node
|
||||
|
||||
|
||||
class Player(Creature):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3, listOfChests):
|
||||
super().__init__(unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
self.agility = a
|
||||
self.wisdom = w
|
||||
self.maxHealth = maxhp
|
||||
self.health = hp
|
||||
self.gold = g
|
||||
self.weapon1 = weap
|
||||
self.weapon2 = w2
|
||||
self.weapon3 = w3
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = False
|
||||
self.directions = {
|
||||
Direction.N : [0, 1],
|
||||
Direction.E : [1, 0],
|
||||
Direction.S : [0, -1],
|
||||
Direction.W : [-1, 0]
|
||||
}
|
||||
self.direction = Direction.N
|
||||
self.queue = []
|
||||
self.hasgoalchest = False
|
||||
self.openedchests = 0
|
||||
self.__listOfChests = listOfChests
|
||||
self.__actionsCollection = []
|
||||
|
||||
def meleeAttack(self, opponent):
|
||||
attackValue = self.strength + dice(6)
|
||||
defenseValue = opponent.strength + opponent.armor.defence
|
||||
damage = attackValue - defenseValue
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def rangeAttack(self, opponent):
|
||||
attackValue = self.agility + dice(6)
|
||||
defenseValue = opponent.agility
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon2.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon2.damage - opponent.armor.defence)
|
||||
|
||||
def magicAttack(self, opponent):
|
||||
attackValue = self.wisdom + dice(6)
|
||||
defenseValue = opponent.wisdom
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon3.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon3.damage - opponent.armor.mag_protection)
|
||||
|
||||
def fightOrFlight(self, opponent):
|
||||
combat = True
|
||||
while combat:
|
||||
choice = dice(4)
|
||||
print("dice rolled:", choice)
|
||||
if choice == 1:
|
||||
running_speed = self.agility + dice(6)
|
||||
opponent_speed = opponent.agility + dice(6)
|
||||
if running_speed > opponent_speed:
|
||||
combat = False
|
||||
print("Player ran away")
|
||||
self.step()
|
||||
else:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
elif choice == 2:
|
||||
self.meleeAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
elif choice == 3:
|
||||
self.rangeAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
else:
|
||||
self.magicAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
|
||||
def openChest(self, chest):
|
||||
self.gold = self.gold + chest.gold
|
||||
print("------Chest opened. Gold inside:", chest.gold,"-----")
|
||||
chest.gold = 0
|
||||
self.openedchests += 1
|
||||
self.hasgoalchest = False
|
||||
chest.model.grid.remove_agent(chest)
|
||||
#self.direction = 0 # po osiągnięciu jednego celu 'restartuje sie' na szukanie ścieżki do kolejnego -- NIE ZEROWAĆ OBROTU - to psuje goldState w bfs!!!
|
||||
# if isinstance(chest.loot,Armor):
|
||||
# buffer = self.armor
|
||||
# self.armor = chest.loot
|
||||
# chest.loot = buffer
|
||||
# if isinstance(chest.loot,Weapon):
|
||||
# if chest.loot.type == "Melee":
|
||||
# buffer = self.weapon1
|
||||
# self.weapon1 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.type == "Range":
|
||||
# buffer = self.weapon2
|
||||
# self.weapon2 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.type == "Magic":
|
||||
# buffer = self.weapon3
|
||||
# self.weapon3 = chest.loot
|
||||
# chest.loot = buffer
|
||||
|
||||
#- - - - bfs & successor - - - -#
|
||||
def successor(self, append):
|
||||
|
||||
rotateLeft = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().counterClockwise()
|
||||
)
|
||||
|
||||
rotateRight = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().clockwise()
|
||||
)
|
||||
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if append.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif append.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif append.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif append.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
if append.get_x() + move_x >= 0 and append.get_x() + move_x < 10 and append.get_y() + move_y >=0 and append.get_y() + move_y < 10:
|
||||
moveForward = AgentState(
|
||||
append.get_x() + move_x,
|
||||
append.get_y() + move_y,
|
||||
append.get_direction()
|
||||
)
|
||||
else:
|
||||
moveForward = None
|
||||
|
||||
return [
|
||||
[actions["rotateLeft"], rotateLeft],
|
||||
[actions["moveForward"], moveForward],
|
||||
[actions["rotateRight"], rotateRight]
|
||||
]
|
||||
|
||||
def heuristics(self, state, target_state):
|
||||
# cost is initially step distance in manhattan metric
|
||||
return abs(state.get_x() - target_state.get_x()) + abs(state.get_y() - target_state.get_y())
|
||||
|
||||
def graphsearch(self, fringe, explored, istate, succesorFunction, goalState):
|
||||
finalActionList = []
|
||||
init_state = [None, istate]
|
||||
root = Node(None, init_state, 0)
|
||||
heapq.heappush(fringe, (0, root)) # at beginning do nothing
|
||||
|
||||
while len(fringe) != 0:
|
||||
_flag = True
|
||||
|
||||
if len(fringe) == 0:
|
||||
return False
|
||||
|
||||
tmpNode = (heapq.heappop(fringe))[1] # node
|
||||
|
||||
# build dictionary
|
||||
# parent = tmpNode.get_predecessor() # fetch parent state
|
||||
# tmpNode.set_predecessor(None) # clear predecessor - don't build a tree chain
|
||||
# if parent is None:
|
||||
# finalActionList.append([parent, tmpNode])
|
||||
# else:
|
||||
# finalActionList.append(
|
||||
# [parent[1], tmpNode]) # pair(key, value) - key: parent state, value: current state + action
|
||||
|
||||
if tmpNode._state.get_x() == goalState.get_x() and tmpNode._state.get_y() == goalState.get_y():
|
||||
while tmpNode._parent is not None:
|
||||
finalActionList.append(tmpNode._action)
|
||||
tmpNode = tmpNode._parent
|
||||
finalActionList = list(reversed(finalActionList))
|
||||
return finalActionList # TODO change step!
|
||||
|
||||
explored.append(tmpNode)
|
||||
|
||||
tmpList = succesorFunction(tmpNode._state)
|
||||
for newState in tmpList:
|
||||
_flag = True
|
||||
_flagFringe = True
|
||||
_flagExplored = True
|
||||
|
||||
if newState[1] is None:
|
||||
continue
|
||||
|
||||
# calculating priority
|
||||
monster = 0
|
||||
if any([thing.isCreature for thing in self.model.grid.get_cell_list_contents([(newState[1].get_x(), newState[1].get_y())])]):
|
||||
if newState[0] == 0:
|
||||
monster = 10
|
||||
p = self.heuristics(newState[1], goalState) + tmpNode._cost + monster + 1
|
||||
|
||||
r = 0
|
||||
counter = 0
|
||||
pos = 0
|
||||
for fringeNode in fringe:
|
||||
if fringeNode[1]._state.get_x() == newState[1].get_x() and fringeNode[1]._state.get_y() == newState[1].get_y() and fringeNode[1]._state.get_direction() == newState[1].get_direction():
|
||||
_flagFringe = False
|
||||
_flag = False
|
||||
r = fringeNode[0]
|
||||
pos = counter
|
||||
counter = counter + 1
|
||||
|
||||
for exploredNode in explored:
|
||||
if exploredNode._state.get_x() == newState[1].get_x() and exploredNode._state.get_y() == newState[1].get_y() and exploredNode._state.get_direction() == newState[1].get_direction():
|
||||
_flagExplored = False
|
||||
_flag = False
|
||||
|
||||
# if _flag:
|
||||
# newState[1].set_predecessor(tmpNode)
|
||||
|
||||
if _flagFringe and _flagExplored:
|
||||
newNode = Node(tmpNode, newState, tmpNode._cost + 1 + monster)
|
||||
heapq.heappush(fringe, (p, newNode))
|
||||
elif not _flagFringe and (p < r):
|
||||
newNode = Node(tmpNode, newState, tmpNode._cost + 1 + monster)
|
||||
fringe[pos][0] = p
|
||||
fringe[pos][1] = newNode
|
||||
|
||||
return None
|
||||
|
||||
def step(self):
|
||||
if self.health > 0:
|
||||
print("position: ", self.pos)
|
||||
# print("direction: ", self.direction)
|
||||
if not self.hasgoalchest: # jeśli nie ma wyznaczonej skrzynki do której idzie to robi bfs żeby ją wyznaczyć
|
||||
# self.path=self.findShortestPathToTarget()
|
||||
if len(self.__listOfChests) != 0:
|
||||
# select and remove element from list
|
||||
randomChest = random.choice(self.__listOfChests)
|
||||
self.__listOfChests.remove(randomChest)
|
||||
self.hasgoalchest = True
|
||||
|
||||
currentState = AgentState(self.pos[0], self.pos[1], self.direction)
|
||||
|
||||
goalState = AgentState(randomChest[1][0], randomChest[1][1], self.direction)
|
||||
# find way to goal state
|
||||
self.__actionsCollection = self.graphsearch([],
|
||||
[],
|
||||
currentState,
|
||||
self.successor,
|
||||
goalState)
|
||||
|
||||
if self.__actionsCollection is None:
|
||||
raise Exception("CRITICAL ERROR - Algorithm error - Path doesn't exist!!! ://")
|
||||
|
||||
else:
|
||||
self.__actionsCollection = [action for action in self.__actionsCollection if action is not None] # remove first None action
|
||||
else:
|
||||
raise Exception("WIN!!! :D")
|
||||
|
||||
elif len(self.__actionsCollection) == 0: # jeśli jest wyznaczona skrzynka - cel & nie ma akcji do wykonania - cel osiągnięty
|
||||
self.hasgoalchest = False
|
||||
|
||||
elif len(self.__actionsCollection) != 0: # jeśli jest wyznaczona skrzynka - cel & są akcje do wykoannia to je realizuje
|
||||
|
||||
actionIndex = self.__actionsCollection[0] # ignore -1 because it's None
|
||||
self.__actionsCollection.remove(actionIndex)
|
||||
|
||||
newState = actionsInterpreter(actionIndex, AgentState(self.pos[0], self.pos[1], self.direction), self.directions)
|
||||
|
||||
self.model.grid.move_agent(self, (newState.get_x(), newState.get_y()))
|
||||
self.direction = newState.get_direction()
|
||||
|
||||
print("moved to - ", [newState.get_x(), newState.get_y()])
|
||||
|
||||
cellmates = self.model.grid.get_cell_list_contents([self.pos])
|
||||
if len(cellmates) > 1:
|
||||
if isinstance(cellmates[0], Box):
|
||||
self.openChest(cellmates[0])
|
||||
else:
|
||||
opponent = cellmates[0]
|
||||
print("Fighting")
|
||||
self.fightOrFlight(opponent)
|
||||
# print("HP: " + str(self.health) + " / " + str(self.maxHealth))
|
||||
print("Gold: " + str(self.gold))
|
||||
else:
|
||||
print("HP: 0 / " + str(self.maxHealth))
|
@ -1,86 +0,0 @@
|
||||
from mesa import Agent
|
||||
import random
|
||||
|
||||
|
||||
def dice(number):
|
||||
return random.randint(1, number)
|
||||
|
||||
|
||||
|
||||
class Wall(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
|
||||
def step(self):
|
||||
pass
|
||||
|
||||
|
||||
class Box(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
self.gold = 3 * dice(6)
|
||||
self.isBox = True
|
||||
self.isCreature = False
|
||||
|
||||
def step(self):
|
||||
pass
|
||||
|
||||
|
||||
class Weapon():
|
||||
def __init__(self, name, type, damage):
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.damage = damage
|
||||
|
||||
|
||||
class Armor():
|
||||
def __init__(self, name, defence, mp):
|
||||
self.name = name
|
||||
self.defence = defence
|
||||
self.mag_protection = mp
|
||||
|
||||
|
||||
class Creature(Agent):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g):
|
||||
super().__init__(unique_id, model)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
self.agility = a
|
||||
self.wisdom = w
|
||||
self.maxHealth = maxhp
|
||||
self.health = hp
|
||||
self.gold = g
|
||||
self.weapon1 = weap
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = True
|
||||
|
||||
def meleeAttack(self, opponent):
|
||||
attackValue = self.strength + dice(6)
|
||||
defenseValue = opponent.strength + opponent.armor.defence
|
||||
damage = attackValue - defenseValue
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def rangeAttack(self, opponent):
|
||||
attackValue = self.agility + dice(6)
|
||||
defenseValue = opponent.agility
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.defence)
|
||||
|
||||
def magicAttack(self, opponent):
|
||||
attackValue = self.wisdom + dice(6)
|
||||
defenseValue = opponent.wisdom
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.mag_protection)
|
||||
|
||||
def defaultAttack(self, opponent):
|
||||
if self.weapon1.type == "Meele":
|
||||
self.meleeAttack(opponent)
|
||||
elif self.weapon1.type == "Range":
|
||||
self.rangeAttack(opponent)
|
||||
else:
|
||||
self.magicAttack(opponent)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from model import GameMap
|
||||
from src.agent.map.gameMap import GameMap
|
||||
from mesa.visualization.modules import CanvasGrid
|
||||
from mesa.visualization.ModularVisualization import ModularServer
|
||||
|
||||
@ -10,13 +10,14 @@ def player_representation(agent):
|
||||
portrayal["Shape"] = "sprites/box.png"
|
||||
portrayal["Layer"] = 0
|
||||
elif agent.isCreature:
|
||||
portrayal["Shape"]='sprites/goblin.png'
|
||||
portrayal["Shape"] = 'sprites/goblin.png'
|
||||
return portrayal
|
||||
|
||||
|
||||
grid = CanvasGrid(player_representation, 10, 10, 500, 500)
|
||||
server = ModularServer(GameMap,
|
||||
[grid],
|
||||
"Map",
|
||||
{"x":10, "y":10})
|
||||
{"x": 10, "y": 10})
|
||||
server.port = 8081
|
||||
server.launch()
|
||||
server.launch()
|
||||
|
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
BIN
src/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
src/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/direction.cpython-39.pyc
Normal file
BIN
src/__pycache__/direction.cpython-39.pyc
Normal file
Binary file not shown.
4
src/agent/__init__.py
Normal file
4
src/agent/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
from .hero import Player
|
||||
from .map.gameMap import GameMap
|
||||
from .model import *
|
||||
from .state import AgentState
|
BIN
src/agent/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
src/agent/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/hero.cpython-39.pyc
Normal file
BIN
src/agent/__pycache__/hero.cpython-39.pyc
Normal file
Binary file not shown.
199
src/agent/hero.py
Normal file
199
src/agent/hero.py
Normal file
@ -0,0 +1,199 @@
|
||||
import random
|
||||
|
||||
from src.agent.model import *
|
||||
from src.agent.state import AgentState
|
||||
from src.direction import Direction
|
||||
from src.treesearch.actionsInterpreter import ActionInterpreter
|
||||
|
||||
from src.treesearch.bfs import BFS
|
||||
|
||||
|
||||
class Player(Creature):
|
||||
def __init__(self, unique_id, model, n, s, a, w, max_hp, hp, weapon, arm, g, w2, w3, list_of_chests):
|
||||
super().__init__(unique_id, model, n, s, a, w, max_hp, hp, weapon, arm, g)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
self.agility = a
|
||||
self.wisdom = w
|
||||
self.maxHealth = max_hp
|
||||
self.health = hp
|
||||
self.gold = g
|
||||
self.weapon1 = weapon
|
||||
self.weapon2 = w2
|
||||
self.weapon3 = w3
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = False
|
||||
self.direction = Direction.N
|
||||
self.queue = []
|
||||
self.has_goal_chest = False
|
||||
self.opened_chests = 0
|
||||
self.__listOfChests = list_of_chests
|
||||
self.__actionsCollection = []
|
||||
|
||||
def melee_attack(self, opponent):
|
||||
attack_value = self.strength + roll_the_dice(6)
|
||||
defense_value = opponent.strength + opponent.armor.defence
|
||||
damage = attack_value - defense_value
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def range_attack(self, opponent):
|
||||
attack_value = self.agility + roll_the_dice(6)
|
||||
defense_value = opponent.agility
|
||||
damage = attack_value - defense_value
|
||||
if (damage > 0) and (damage + self.weapon2.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon2.damage - opponent.armor.defence)
|
||||
|
||||
def magic_attack(self, opponent):
|
||||
attack_value = self.wisdom + roll_the_dice(6)
|
||||
defense_value = opponent.wisdom
|
||||
damage = attack_value - defense_value
|
||||
if (damage > 0) and (damage + self.weapon3.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon3.damage - opponent.armor.mag_protection)
|
||||
|
||||
def fight_or_flight(self, opponent):
|
||||
combat = True
|
||||
while combat:
|
||||
choice = roll_the_dice(4)
|
||||
print("roll_the_dice rolled:", choice)
|
||||
if choice == 1:
|
||||
running_speed = self.agility + roll_the_dice(6)
|
||||
opponent_speed = opponent.agility + roll_the_dice(6)
|
||||
if running_speed > opponent_speed:
|
||||
combat = False
|
||||
print("Player ran away")
|
||||
self.step()
|
||||
else:
|
||||
opponent.default_attack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
elif choice == 2:
|
||||
self.melee_attack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.default_attack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
elif choice == 3:
|
||||
self.range_attack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.default_attack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
else:
|
||||
self.magic_attack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.default_attack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
|
||||
def open_chest(self, chest):
|
||||
self.gold = self.gold + chest.gold
|
||||
print("------Chest opened. Gold inside:", chest.gold, "-----")
|
||||
chest.gold = 0
|
||||
self.opened_chests += 1
|
||||
self.has_goal_chest = False
|
||||
chest.model.grid.remove_agent(chest)
|
||||
# self.direction = 0 # po osiągnięciu jednego celu 'restartuje sie' na szukanie ścieżki do kolejnego -- NIE ZEROWAĆ OBROTU - to psuje goldState w bfs!!!
|
||||
# if isinstance(chest.loot,Armor):
|
||||
# buffer = self.armor
|
||||
# self.armor = chest.loot
|
||||
# chest.loot = buffer
|
||||
# if isinstance(chest.loot,Weapon):
|
||||
# if chest.loot.weapon_type == "Melee":
|
||||
# buffer = self.weapon1
|
||||
# self.weapon1 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.weapon_type == "Range":
|
||||
# buffer = self.weapon2
|
||||
# self.weapon2 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.weapon_type == "Magic":
|
||||
# buffer = self.weapon3
|
||||
# self.weapon3 = chest.loot
|
||||
# chest.loot = buffer
|
||||
|
||||
def step(self):
|
||||
if self.health > 0:
|
||||
print("position: ", self.pos)
|
||||
# print("direction: ", self.direction)
|
||||
if not self.has_goal_chest: # jeśli nie ma wyznaczonej skrzynki do której idzie to robi bfs żeby ją wyznaczyć
|
||||
# self.path=self.findShortestPathToTarget()
|
||||
if len(self.__listOfChests) != 0:
|
||||
# select and remove element from list
|
||||
random_chest = random.choice(self.__listOfChests)
|
||||
self.__listOfChests.remove(random_chest)
|
||||
self.has_goal_chest = True
|
||||
|
||||
current_state = AgentState(self.pos[0], self.pos[1], self.direction)
|
||||
|
||||
goal_state = AgentState(random_chest[1][0], random_chest[1][1], self.direction)
|
||||
# find way to goal state
|
||||
treesearch_module = BFS(self)
|
||||
self.__actionsCollection = treesearch_module.graphsearch([],
|
||||
[],
|
||||
current_state,
|
||||
BFS.successor,
|
||||
goal_state)
|
||||
|
||||
if self.__actionsCollection is None:
|
||||
raise Exception("CRITICAL ERROR - Algorithm error - Path doesn't exist!!! ://")
|
||||
|
||||
else:
|
||||
self.__actionsCollection = [action for action in self.__actionsCollection if
|
||||
action is not None] # remove first None action
|
||||
else:
|
||||
raise Exception("WIN!!! :D")
|
||||
|
||||
elif len(
|
||||
self.__actionsCollection) == 0: # jeśli jest wyznaczona skrzynka - cel & nie ma akcji do wykonania - cel osiągnięty
|
||||
self.has_goal_chest = False
|
||||
|
||||
elif len(
|
||||
self.__actionsCollection) != 0: # jeśli jest wyznaczona skrzynka - cel & są akcje do wykoannia to je realizuje
|
||||
|
||||
action_index = self.__actionsCollection[0] # ignore -1 because it's None
|
||||
self.__actionsCollection.remove(action_index)
|
||||
|
||||
new_state = ActionInterpreter.interpret(action_index,
|
||||
AgentState(self.pos[0], self.pos[1], self.direction))
|
||||
|
||||
self.model.grid.move_agent(self, (new_state.get_x(), new_state.get_y()))
|
||||
self.direction = new_state.get_direction()
|
||||
|
||||
print("moved to - ", [new_state.get_x(), new_state.get_y()])
|
||||
|
||||
cellmates = self.model.grid.get_cell_list_contents([self.pos])
|
||||
if len(cellmates) > 1:
|
||||
if isinstance(cellmates[0], Box):
|
||||
self.open_chest(cellmates[0])
|
||||
else:
|
||||
opponent = cellmates[0]
|
||||
print("Fighting")
|
||||
self.fight_or_flight(opponent)
|
||||
# print("HP: " + str(self.health) + " / " + str(self.maxHealth))
|
||||
print("Gold: " + str(self.gold))
|
||||
else:
|
||||
print("HP: 0 / " + str(self.maxHealth))
|
BIN
src/agent/map/__pycache__/gameMap.cpython-39.pyc
Normal file
BIN
src/agent/map/__pycache__/gameMap.cpython-39.pyc
Normal file
Binary file not shown.
@ -1,65 +1,69 @@
|
||||
from mesa import Model
|
||||
from hero import Player
|
||||
from othercharacters import Creature, Box, Wall, dice
|
||||
from armory import WM1, A1, WR1, S1, WM2, A2
|
||||
from mesa.time import RandomActivation
|
||||
from mesa.space import MultiGrid
|
||||
# from mesa.datacollection import DataCollector
|
||||
import random
|
||||
|
||||
x = 10
|
||||
y = 10
|
||||
step_counter = 0
|
||||
boxes_number = 4
|
||||
creatures_number = 5
|
||||
|
||||
|
||||
class GameMap(Model):
|
||||
def __init__(self, x, y):
|
||||
self.listOfChests = []
|
||||
self.grid = MultiGrid(x, y, False)
|
||||
self.schedule = RandomActivation(self) # agenci losowo po kolei wykonują swoje akcje
|
||||
# to jest potrzebne przy założeniu, że potwory chodzą?
|
||||
self.boxes_number = boxes_number
|
||||
self.creatures_number = creatures_number
|
||||
self.running = True
|
||||
# player = Player(1000, self)
|
||||
player = Player(1000, self, "Janusz", 3, 3, 3, 20, 20, WM1, A1, 0, WR1, S1, self.listOfChests)
|
||||
self.schedule.add(player)
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
self.grid.place_agent(player, (x, y))
|
||||
|
||||
|
||||
for i in range(self.boxes_number):
|
||||
box = Box(i, self)
|
||||
# self.schedule.add(box)
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
if self.grid.is_cell_empty((x, y)):
|
||||
self.grid.place_agent(box, (x, y))
|
||||
self.schedule.add(box)
|
||||
self.listOfChests.append([i, [x, y]]) #fetching chest position - [index, [OX, OY]]
|
||||
else:
|
||||
pass
|
||||
|
||||
for i in range(self.boxes_number,
|
||||
self.boxes_number + self.creatures_number): # taki range, żeby każdy agent miał poprawne unique_id
|
||||
# creature = Creature(i, self)
|
||||
creature = Creature(i, self, "Goblin", 1, 1, 1, 1, 1, WM2, A2, dice(6))
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
if self.grid.is_cell_empty((x, y)):
|
||||
self.grid.place_agent(creature, (x, y))
|
||||
self.schedule.add(creature)
|
||||
else:
|
||||
pass
|
||||
|
||||
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
|
||||
|
||||
def get_listOfChests(self):
|
||||
return self.listOfChests
|
||||
|
||||
def step(self):
|
||||
self.schedule.step()
|
||||
# self.datacollector.collect(self) #na razie niepotrzebne
|
||||
from mesa import Model
|
||||
from src.agent.hero import Player
|
||||
|
||||
from src.agent.model.dice.dice import roll_the_dice
|
||||
from src.agent.model.creature import Creature
|
||||
|
||||
from src.agent.model.box import Box
|
||||
|
||||
from src.items.armory import WM1, A1, WR1, S1, WM2, A2
|
||||
from mesa.time import RandomActivation
|
||||
from mesa.space import MultiGrid
|
||||
|
||||
# from mesa.datacollection import DataCollector
|
||||
|
||||
x = 10
|
||||
y = 10
|
||||
step_counter = 0
|
||||
boxes_number = 4
|
||||
creatures_number = 5
|
||||
|
||||
|
||||
class GameMap(Model):
|
||||
def __init__(self, x, y):
|
||||
self.listOfChests = []
|
||||
self.grid = MultiGrid(x, y, False)
|
||||
self.schedule = RandomActivation(self) # agenci losowo po kolei wykonują swoje akcje
|
||||
# to jest potrzebne przy założeniu, że potwory chodzą?
|
||||
self.boxes_number = boxes_number
|
||||
self.creatures_number = creatures_number
|
||||
self.running = True
|
||||
# player = Player(1000, self)
|
||||
player = Player(1000, self, "Janusz", 3, 3, 3, 20, 20, WM1, A1, 0, WR1, S1, self.listOfChests)
|
||||
self.schedule.add(player)
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
self.grid.place_agent(player, (x, y))
|
||||
|
||||
for i in range(self.boxes_number):
|
||||
box = Box(i, self)
|
||||
# self.schedule.add(box)
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
if self.grid.is_cell_empty((x, y)):
|
||||
self.grid.place_agent(box, (x, y))
|
||||
self.schedule.add(box)
|
||||
self.listOfChests.append([i, [x, y]]) # fetching chest position - [index, [OX, OY]]
|
||||
else:
|
||||
pass
|
||||
|
||||
for i in range(self.boxes_number,
|
||||
self.boxes_number + self.creatures_number): # taki range, żeby każdy agent miał poprawne unique_id
|
||||
# creature = Creature(i, self)
|
||||
creature = Creature(i, self, "Goblin", 1, 1, 1, 1, 1, WM2, A2, roll_the_dice(6))
|
||||
x = self.random.randrange(self.grid.width)
|
||||
y = self.random.randrange(self.grid.height)
|
||||
if self.grid.is_cell_empty((x, y)):
|
||||
self.grid.place_agent(creature, (x, y))
|
||||
self.schedule.add(creature)
|
||||
else:
|
||||
pass
|
||||
|
||||
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
|
||||
|
||||
def get_list_of_chests(self):
|
||||
return self.listOfChests
|
||||
|
||||
def step(self):
|
||||
self.schedule.step()
|
||||
# self.datacollector.collect(self) #na razie niepotrzebne
|
6
src/agent/model/__init__.py
Normal file
6
src/agent/model/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
from .dice import *
|
||||
from .armor import Armor
|
||||
from .box import Box
|
||||
from .creature import Creature
|
||||
from .wall import Wall
|
||||
from .weapon import Weapon
|
BIN
src/agent/model/__pycache__/armor.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/armor.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/box.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/box.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/creature.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/creature.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/wall.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/wall.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/weapon.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/weapon.cpython-39.pyc
Normal file
Binary file not shown.
21
src/agent/model/armor.py
Normal file
21
src/agent/model/armor.py
Normal file
@ -0,0 +1,21 @@
|
||||
class Armor:
|
||||
def __init__(self, name, defence, mp):
|
||||
self.__name = name
|
||||
self.__defence = defence
|
||||
self.__mag_protection = mp
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def get_defence(self):
|
||||
return self.__defence
|
||||
|
||||
def set_defence(self, new_defence):
|
||||
self.__defence = new_defence
|
||||
|
||||
def get_mag_protection(self):
|
||||
return self.__mag_protection
|
||||
|
||||
def set_mag_protection(self, new_mag_protection):
|
||||
self.__mag_protection = new_mag_protection
|
||||
|
13
src/agent/model/box.py
Normal file
13
src/agent/model/box.py
Normal file
@ -0,0 +1,13 @@
|
||||
from mesa import Agent
|
||||
from .dice.dice import roll_the_dice
|
||||
|
||||
|
||||
class Box(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
self.gold = 3 * roll_the_dice(6)
|
||||
self.isBox = True
|
||||
self.isCreature = False
|
||||
|
||||
def step(self):
|
||||
pass
|
47
src/agent/model/creature.py
Normal file
47
src/agent/model/creature.py
Normal file
@ -0,0 +1,47 @@
|
||||
from mesa import Agent
|
||||
from .dice.dice import roll_the_dice
|
||||
|
||||
|
||||
class Creature(Agent):
|
||||
def __init__(self, unique_id, model, name, strength, agility, wisdom, max_hp, hp, weapon, armor, gold):
|
||||
super().__init__(unique_id, model)
|
||||
self.name = name
|
||||
self.strength = strength
|
||||
self.agility = agility
|
||||
self.wisdom = wisdom
|
||||
self.maxHealth = max_hp
|
||||
self.health = hp
|
||||
self.gold = gold
|
||||
self.weapon1 = weapon
|
||||
self.armor = armor
|
||||
self.isBox = False
|
||||
self.isCreature = True
|
||||
|
||||
def melee_attack(self, opponent):
|
||||
attack_value = self.strength + roll_the_dice(6)
|
||||
defense_value = opponent.strength + opponent.armor.defence
|
||||
damage = attack_value - defense_value
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def range_attack(self, opponent):
|
||||
attack_value = self.agility + roll_the_dice(6)
|
||||
defense_value = opponent.agility
|
||||
damage = attack_value - defense_value
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.defence)
|
||||
|
||||
def magic_attack(self, opponent):
|
||||
attack_value = self.wisdom + roll_the_dice(6)
|
||||
defense_value = opponent.wisdom
|
||||
damage = attack_value - defense_value
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.mag_protection)
|
||||
|
||||
def default_attack(self, opponent):
|
||||
if self.weapon1.type == "Meele":
|
||||
self.melee_attack(opponent)
|
||||
elif self.weapon1.type == "Range":
|
||||
self.range_attack(opponent)
|
||||
else:
|
||||
self.magic_attack(opponent)
|
0
src/agent/model/dice/__init__.py
Normal file
0
src/agent/model/dice/__init__.py
Normal file
BIN
src/agent/model/dice/__pycache__/dice.cpython-39.pyc
Normal file
BIN
src/agent/model/dice/__pycache__/dice.cpython-39.pyc
Normal file
Binary file not shown.
5
src/agent/model/dice/dice.py
Normal file
5
src/agent/model/dice/dice.py
Normal file
@ -0,0 +1,5 @@
|
||||
import random
|
||||
|
||||
|
||||
def roll_the_dice(number):
|
||||
return random.randint(1, number)
|
9
src/agent/model/wall.py
Normal file
9
src/agent/model/wall.py
Normal file
@ -0,0 +1,9 @@
|
||||
from mesa import Agent
|
||||
|
||||
|
||||
class Wall(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
|
||||
def step(self):
|
||||
pass
|
14
src/agent/model/weapon.py
Normal file
14
src/agent/model/weapon.py
Normal file
@ -0,0 +1,14 @@
|
||||
class Weapon:
|
||||
def __init__(self, name, weapon_type, weapon_damage):
|
||||
self.__name = name
|
||||
self.__type = weapon_type
|
||||
self.__damage = weapon_damage
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def get_type(self):
|
||||
return self.__type
|
||||
|
||||
def get_damage(self):
|
||||
return self.__damage
|
BIN
src/dictionary/__pycache__/actions.cpython-39.pyc
Normal file
BIN
src/dictionary/__pycache__/actions.cpython-39.pyc
Normal file
Binary file not shown.
5
src/dictionary/actions.py
Normal file
5
src/dictionary/actions.py
Normal file
@ -0,0 +1,5 @@
|
||||
actions = {
|
||||
"rotate_left": -1,
|
||||
"move_forward": 0,
|
||||
"rotate_right": 1
|
||||
}
|
8
src/dictionary/directions.py
Normal file
8
src/dictionary/directions.py
Normal file
@ -0,0 +1,8 @@
|
||||
from src.direction import Direction
|
||||
|
||||
directions = {
|
||||
Direction.N: [0, 1],
|
||||
Direction.E: [1, 0],
|
||||
Direction.S: [0, -1],
|
||||
Direction.W: [-1, 0]
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
N = 0
|
||||
E = 1
|
||||
@ -7,9 +8,9 @@ class Direction(Enum):
|
||||
W = 3
|
||||
|
||||
def clockwise(self):
|
||||
v = (self.value+1)%4
|
||||
v = (self.value + 1) % 4
|
||||
return Direction(v)
|
||||
|
||||
def counterClockwise(self):
|
||||
v = (self.value-1)%4
|
||||
return Direction(v)
|
||||
def counter_clockwise(self):
|
||||
v = (self.value - 1) % 4
|
||||
return Direction(v)
|
BIN
src/items/__pycache__/armory.cpython-39.pyc
Normal file
BIN
src/items/__pycache__/armory.cpython-39.pyc
Normal file
Binary file not shown.
@ -1,6 +1,5 @@
|
||||
from mesa import Agent, Model
|
||||
import random
|
||||
from hero import Weapon, Armor
|
||||
from src.agent.model.weapon import Weapon
|
||||
from src.agent.model.armor import Armor
|
||||
|
||||
WM1 = Weapon("Log", "Melee", 1)
|
||||
WM2 = Weapon("Log", "Melee", 1)
|
||||
@ -64,7 +63,7 @@ A16 = Armor("Magical Plate Armor", 3, 2)
|
||||
# C12 = Box(A14)
|
||||
|
||||
# Gracz = Player(1000, self, "Janusz",3,3,3,20,20,WM1,A1,0,WR1,S1)
|
||||
# def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g):
|
||||
# def __init__(self, unique_id, model, n, s, a, w, max_hp, hp, weapon, arm, g):
|
||||
# M1 = Creature("Goblin",2,2,1,10,10,WM2,A2,dice(6))
|
||||
# M2 = Creature("Goblin",2,2,1,10,10,WM3,A3,dice(6))
|
||||
# M3 = Creature("Goblin",2,2,1,10,10,WR2,A4,dice(6))
|
BIN
src/tree/__pycache__/node.cpython-39.pyc
Normal file
BIN
src/tree/__pycache__/node.cpython-39.pyc
Normal file
Binary file not shown.
@ -5,6 +5,15 @@ class Node:
|
||||
self._state = state_tuple[1]
|
||||
self._parent = parent
|
||||
|
||||
def get_cost(self):
|
||||
return self._cost
|
||||
|
||||
def get_action(self):
|
||||
return self._action
|
||||
|
||||
def get_state(self):
|
||||
return self._state
|
||||
|
||||
def get_predecessor(self):
|
||||
return self._parent
|
||||
|
||||
@ -12,4 +21,4 @@ class Node:
|
||||
self._parent = predecessor
|
||||
|
||||
def __lt__(self, other):
|
||||
return self._cost < other._cost
|
||||
return self._cost < other.get_cost()
|
3
src/treesearch/__init__.py
Normal file
3
src/treesearch/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .bfs import BFS
|
||||
from .actionsInterpreter import ActionInterpreter
|
||||
from .heuristic import *
|
BIN
src/treesearch/__pycache__/actionsInterpreter.cpython-39.pyc
Normal file
BIN
src/treesearch/__pycache__/actionsInterpreter.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/treesearch/__pycache__/bfs.cpython-39.pyc
Normal file
BIN
src/treesearch/__pycache__/bfs.cpython-39.pyc
Normal file
Binary file not shown.
40
src/treesearch/actionsInterpreter.py
Normal file
40
src/treesearch/actionsInterpreter.py
Normal file
@ -0,0 +1,40 @@
|
||||
from src.agent.state import AgentState
|
||||
from src.direction import Direction
|
||||
|
||||
|
||||
class ActionInterpreter:
|
||||
|
||||
@staticmethod
|
||||
def interpret(action_index, default_state):
|
||||
if action_index == -1:
|
||||
return AgentState(
|
||||
default_state.get_x(),
|
||||
default_state.get_y(),
|
||||
default_state.get_direction().counter_clockwise()
|
||||
)
|
||||
elif action_index == 0:
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if default_state.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif default_state.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif default_state.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif default_state.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
return AgentState(
|
||||
default_state.get_x() + move_x,
|
||||
default_state.get_y() + move_y,
|
||||
default_state.get_direction()
|
||||
)
|
||||
elif action_index == 1:
|
||||
return AgentState(
|
||||
default_state.get_x(),
|
||||
default_state.get_y(),
|
||||
default_state.get_direction().clockwise()
|
||||
)
|
||||
else:
|
||||
return default_state
|
140
src/treesearch/bfs.py
Normal file
140
src/treesearch/bfs.py
Normal file
@ -0,0 +1,140 @@
|
||||
import heapq
|
||||
|
||||
from src.dictionary.actions import actions
|
||||
from src.agent.state import AgentState
|
||||
from src.direction import Direction
|
||||
from src.tree.node import Node
|
||||
from src.treesearch.heuristic.manhattan import manhattan
|
||||
|
||||
|
||||
class BFS:
|
||||
|
||||
def __init__(self, agent):
|
||||
self.__agent = agent
|
||||
|
||||
@staticmethod
|
||||
def successor(append):
|
||||
|
||||
rotate_left = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().counter_clockwise()
|
||||
)
|
||||
|
||||
rotate_right = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().clockwise()
|
||||
)
|
||||
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if append.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif append.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif append.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif append.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
if append.get_x() + move_x >= 0 and append.get_x() + move_x < 10 and append.get_y() + move_y >= 0 and append.get_y() + move_y < 10:
|
||||
move_forward = AgentState(
|
||||
append.get_x() + move_x,
|
||||
append.get_y() + move_y,
|
||||
append.get_direction()
|
||||
)
|
||||
else:
|
||||
move_forward = None
|
||||
|
||||
return [
|
||||
[actions["rotate_left"], rotate_left],
|
||||
[actions["move_forward"], move_forward],
|
||||
[actions["rotate_right"], rotate_right]
|
||||
]
|
||||
|
||||
def graphsearch(self, fringe, explored, istate, succesor_function, goal_state):
|
||||
final_action_list = []
|
||||
|
||||
init_state = [None, istate]
|
||||
root = Node(None, init_state, 0)
|
||||
|
||||
heapq.heappush(fringe, (0, root)) # at beginning do nothing
|
||||
|
||||
while len(fringe) != 0:
|
||||
_flag = True
|
||||
|
||||
if len(fringe) == 0:
|
||||
return False
|
||||
|
||||
tmp_node = (heapq.heappop(fringe))[1] # node
|
||||
|
||||
# build dictionary
|
||||
# parent = tmp_node.get_predecessor() # fetch parent state
|
||||
# tmp_node.set_predecessor(None) # clear predecessor - don't build a tree chain
|
||||
# if parent is None:
|
||||
# final_action_list.append([parent, tmp_node])
|
||||
# else:
|
||||
# final_action_list.append(
|
||||
# [parent[1], tmp_node]) # pair(key, value) - key: parent state, value: current state + action
|
||||
|
||||
if tmp_node.get_state().get_x() == goal_state.get_x() and tmp_node.get_state().get_y() == goal_state.get_y():
|
||||
while tmp_node.get_predecessor() is not None:
|
||||
final_action_list.append(tmp_node.get_action())
|
||||
tmp_node = tmp_node.get_predecessor()
|
||||
final_action_list = list(reversed(final_action_list))
|
||||
return final_action_list # TODO change step!
|
||||
|
||||
explored.append(tmp_node)
|
||||
|
||||
tmp_list = succesor_function(tmp_node.get_state())
|
||||
for new_state in tmp_list:
|
||||
_flag = True
|
||||
_flagFringe = True
|
||||
_flagExplored = True
|
||||
|
||||
if new_state[1] is None:
|
||||
continue
|
||||
|
||||
# calculating priority
|
||||
monster = 0
|
||||
if any([thing.isCreature for thing in
|
||||
self.__agent.model.grid.get_cell_list_contents(
|
||||
[(new_state[1].get_x(), new_state[1].get_y())])]):
|
||||
if new_state[0] == 0:
|
||||
monster = 10
|
||||
p = manhattan(new_state[1], goal_state) + tmp_node.get_cost() + monster + 1
|
||||
|
||||
r = 0
|
||||
counter = 0
|
||||
pos = 0
|
||||
for fringeNode in fringe:
|
||||
if fringeNode[1].get_state().get_x() == new_state[1].get_x() and fringeNode[
|
||||
1].get_state().get_y() == new_state[1].get_y() and fringeNode[1].get_state().get_direction() == \
|
||||
new_state[1].get_direction():
|
||||
_flagFringe = False
|
||||
_flag = False
|
||||
r = fringeNode[0]
|
||||
pos = counter
|
||||
counter = counter + 1
|
||||
|
||||
for exploredNode in explored:
|
||||
if exploredNode.get_state().get_x() == new_state[1].get_x() and exploredNode.get_state().get_y() == \
|
||||
new_state[1].get_y() and exploredNode.get_state().get_direction() == new_state[
|
||||
1].get_direction():
|
||||
_flagExplored = False
|
||||
_flag = False
|
||||
|
||||
# if _flag:
|
||||
# new_state[1].set_predecessor(tmp_node)
|
||||
|
||||
if _flagFringe and _flagExplored:
|
||||
new_node = Node(tmp_node, new_state, tmp_node.get_cost() + 1 + monster)
|
||||
heapq.heappush(fringe, (p, new_node))
|
||||
elif not _flagFringe and (p < r):
|
||||
new_node = Node(tmp_node, new_state, tmp_node.get_cost() + 1 + monster)
|
||||
fringe[pos][0] = p
|
||||
fringe[pos][1] = new_node
|
||||
|
||||
return None
|
1
src/treesearch/heuristic/__init__.py
Normal file
1
src/treesearch/heuristic/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .manhattan import manhattan
|
4
src/treesearch/heuristic/manhattan.py
Normal file
4
src/treesearch/heuristic/manhattan.py
Normal file
@ -0,0 +1,4 @@
|
||||
# cost is initially step distance in manhattan metric
|
||||
|
||||
def manhattan(state, target_state):
|
||||
return abs(state.get_x() - target_state.get_x()) + abs(state.get_y() - target_state.get_y())
|
Loading…
Reference in New Issue
Block a user