code refactor - change var names & dir structure

This commit is contained in:
kabix09 2021-05-03 00:23:18 +02:00
parent e0cd0a5d85
commit 42aec48676
43 changed files with 611 additions and 536 deletions

View File

@ -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
View File

@ -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))

View File

@ -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)

View File

@ -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
View File

Binary file not shown.

Binary file not shown.

4
src/agent/__init__.py Normal file
View File

@ -0,0 +1,4 @@
from .hero import Player
from .map.gameMap import GameMap
from .model import *
from .state import AgentState

Binary file not shown.

Binary file not shown.

199
src/agent/hero.py Normal file
View 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))

Binary file not shown.

View File

@ -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

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

21
src/agent/model/armor.py Normal file
View 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
View 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

View 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)

View File

Binary file not shown.

View 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
View 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
View 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

Binary file not shown.

View File

@ -0,0 +1,5 @@
actions = {
"rotate_left": -1,
"move_forward": 0,
"rotate_right": 1
}

View 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]
}

View File

@ -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)

Binary file not shown.

View File

@ -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))

Binary file not shown.

View File

@ -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()

View File

@ -0,0 +1,3 @@
from .bfs import BFS
from .actionsInterpreter import ActionInterpreter
from .heuristic import *

Binary file not shown.

View 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
View 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

View File

@ -0,0 +1 @@
from .manhattan import manhattan

View 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())