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.modules import CanvasGrid
|
||||||
from mesa.visualization.ModularVisualization import ModularServer
|
from mesa.visualization.ModularVisualization import ModularServer
|
||||||
|
|
||||||
@ -10,13 +10,14 @@ def player_representation(agent):
|
|||||||
portrayal["Shape"] = "sprites/box.png"
|
portrayal["Shape"] = "sprites/box.png"
|
||||||
portrayal["Layer"] = 0
|
portrayal["Layer"] = 0
|
||||||
elif agent.isCreature:
|
elif agent.isCreature:
|
||||||
portrayal["Shape"]='sprites/goblin.png'
|
portrayal["Shape"] = 'sprites/goblin.png'
|
||||||
return portrayal
|
return portrayal
|
||||||
|
|
||||||
|
|
||||||
grid = CanvasGrid(player_representation, 10, 10, 500, 500)
|
grid = CanvasGrid(player_representation, 10, 10, 500, 500)
|
||||||
server = ModularServer(GameMap,
|
server = ModularServer(GameMap,
|
||||||
[grid],
|
[grid],
|
||||||
"Map",
|
"Map",
|
||||||
{"x":10, "y":10})
|
{"x": 10, "y": 10})
|
||||||
server.port = 8081
|
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,11 +1,16 @@
|
|||||||
from mesa import Model
|
from mesa import Model
|
||||||
from hero import Player
|
from src.agent.hero import Player
|
||||||
from othercharacters import Creature, Box, Wall, dice
|
|
||||||
from armory import WM1, A1, WR1, S1, WM2, A2
|
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.time import RandomActivation
|
||||||
from mesa.space import MultiGrid
|
from mesa.space import MultiGrid
|
||||||
|
|
||||||
# from mesa.datacollection import DataCollector
|
# from mesa.datacollection import DataCollector
|
||||||
import random
|
|
||||||
|
|
||||||
x = 10
|
x = 10
|
||||||
y = 10
|
y = 10
|
||||||
@ -30,7 +35,6 @@ class GameMap(Model):
|
|||||||
y = self.random.randrange(self.grid.height)
|
y = self.random.randrange(self.grid.height)
|
||||||
self.grid.place_agent(player, (x, y))
|
self.grid.place_agent(player, (x, y))
|
||||||
|
|
||||||
|
|
||||||
for i in range(self.boxes_number):
|
for i in range(self.boxes_number):
|
||||||
box = Box(i, self)
|
box = Box(i, self)
|
||||||
# self.schedule.add(box)
|
# self.schedule.add(box)
|
||||||
@ -39,14 +43,14 @@ class GameMap(Model):
|
|||||||
if self.grid.is_cell_empty((x, y)):
|
if self.grid.is_cell_empty((x, y)):
|
||||||
self.grid.place_agent(box, (x, y))
|
self.grid.place_agent(box, (x, y))
|
||||||
self.schedule.add(box)
|
self.schedule.add(box)
|
||||||
self.listOfChests.append([i, [x, y]]) #fetching chest position - [index, [OX, OY]]
|
self.listOfChests.append([i, [x, y]]) # fetching chest position - [index, [OX, OY]]
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for i in range(self.boxes_number,
|
for i in range(self.boxes_number,
|
||||||
self.boxes_number + self.creatures_number): # taki range, żeby każdy agent miał poprawne unique_id
|
self.boxes_number + self.creatures_number): # taki range, żeby każdy agent miał poprawne unique_id
|
||||||
# creature = Creature(i, self)
|
# creature = Creature(i, self)
|
||||||
creature = Creature(i, self, "Goblin", 1, 1, 1, 1, 1, WM2, A2, dice(6))
|
creature = Creature(i, self, "Goblin", 1, 1, 1, 1, 1, WM2, A2, roll_the_dice(6))
|
||||||
x = self.random.randrange(self.grid.width)
|
x = self.random.randrange(self.grid.width)
|
||||||
y = self.random.randrange(self.grid.height)
|
y = self.random.randrange(self.grid.height)
|
||||||
if self.grid.is_cell_empty((x, y)):
|
if self.grid.is_cell_empty((x, y)):
|
||||||
@ -57,7 +61,7 @@ class GameMap(Model):
|
|||||||
|
|
||||||
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
|
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
|
||||||
|
|
||||||
def get_listOfChests(self):
|
def get_list_of_chests(self):
|
||||||
return self.listOfChests
|
return self.listOfChests
|
||||||
|
|
||||||
def step(self):
|
def step(self):
|
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
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
class Direction(Enum):
|
class Direction(Enum):
|
||||||
N = 0
|
N = 0
|
||||||
E = 1
|
E = 1
|
||||||
@ -7,9 +8,9 @@ class Direction(Enum):
|
|||||||
W = 3
|
W = 3
|
||||||
|
|
||||||
def clockwise(self):
|
def clockwise(self):
|
||||||
v = (self.value+1)%4
|
v = (self.value + 1) % 4
|
||||||
return Direction(v)
|
return Direction(v)
|
||||||
|
|
||||||
def counterClockwise(self):
|
def counter_clockwise(self):
|
||||||
v = (self.value-1)%4
|
v = (self.value - 1) % 4
|
||||||
return Direction(v)
|
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
|
from src.agent.model.weapon import Weapon
|
||||||
import random
|
from src.agent.model.armor import Armor
|
||||||
from hero import Weapon, Armor
|
|
||||||
|
|
||||||
WM1 = Weapon("Log", "Melee", 1)
|
WM1 = Weapon("Log", "Melee", 1)
|
||||||
WM2 = Weapon("Log", "Melee", 1)
|
WM2 = Weapon("Log", "Melee", 1)
|
||||||
@ -64,7 +63,7 @@ A16 = Armor("Magical Plate Armor", 3, 2)
|
|||||||
# C12 = Box(A14)
|
# C12 = Box(A14)
|
||||||
|
|
||||||
# Gracz = Player(1000, self, "Janusz",3,3,3,20,20,WM1,A1,0,WR1,S1)
|
# 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))
|
# M1 = Creature("Goblin",2,2,1,10,10,WM2,A2,dice(6))
|
||||||
# M2 = Creature("Goblin",2,2,1,10,10,WM3,A3,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))
|
# 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._state = state_tuple[1]
|
||||||
self._parent = parent
|
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):
|
def get_predecessor(self):
|
||||||
return self._parent
|
return self._parent
|
||||||
|
|
||||||
@ -12,4 +21,4 @@ class Node:
|
|||||||
self._parent = predecessor
|
self._parent = predecessor
|
||||||
|
|
||||||
def __lt__(self, other):
|
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