integrating bfs search and player movement in progress

This commit is contained in:
tubks 2021-04-13 23:08:57 +02:00
parent 20577797fb
commit 0969564c3f
6 changed files with 244 additions and 324 deletions

168
agent.py
View File

@ -1,168 +0,0 @@
from mesa import Agent
import random
def dice(number):
return random.randint(1, number)
class Box(Agent):
def __init__(self, unique_id, model):
super().__init__(unique_id, model)
self.gold=3*dice(6)
self.isBox=True
def step(self):
pass
class Creature(Agent):
def __init__(self, unique_id, model):
super().__init__(unique_id, model)
self.strength = 3
self.agility = 3
self.wisdom = 2
self.maxHealth = 10
self.health = 10
self.gold = dice(6)
self.attack_method = 1
def meleeAttack(self, opponent):
attackValue = self.strength + dice(6)
defenseValue = max(opponent.strength, opponent.agility)
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def rangeAttack(self, opponent):
attackValue = self.agility + dice(6)
defenseValue = opponent.agility
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def magicAttack(self, opponent):
attackValue = self.wisdom + dice(6)
defenseValue = opponent.wisdom
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def defaultAttack(self, opponent):
if self.attack_method == 1:
self.meleeAttack(opponent)
elif self.attack_method == 2:
self.rangeAttack(opponent)
else:
self.magicAttack(opponent)
class Player(Agent):
def __init__(self, unique_id, model):
super().__init__(unique_id, model)
self.strength = 3
self.agility = 3
self.wisdom = 3
self.maxHealth = 20
self.health = 20
self.gold = 0
self.isBox=False
def move(self):
possible_steps = self.model.grid.get_neighborhood(
self.pos,
moore=True,
include_center=False)
new_position = self.random.choice(possible_steps)
self.model.grid.move_agent(self, new_position)
def meleeAttack(self, opponent):
attackValue = self.strength + dice(6)
defenseValue = max(opponent.strength, opponent.agility)
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def rangeAttack(self, opponent):
attackValue = self.agility + dice(6)
defenseValue = opponent.agility
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def magicAttack(self, opponent):
attackValue = self.wisdom + dice(6)
defenseValue = opponent.wisdom
damage = attackValue - defenseValue
if damage > 0:
opponent.health = opponent.health - damage
def fightOrFlight(self, opponent):
combat = True
while combat:
choice = dice(4)
if choice == 1:
running_speed = self.agility + dice(6)
opponent_speed = opponent.agility + dice(6)
if running_speed > opponent_speed:
combat = False
self.step()
else:
opponent.defaultAttack(self)
if self.health <= 0:
combat = False
elif choice == 2:
self.meleeAttack(opponent)
if opponent.health > 0:
opponent.defaultAttack(self)
if self.health <= 0:
combat = False
else:
combat = False
self.gold = self.gold + opponent.gold
opponent.gold = 0
opponent.model.grid.remove_agent(opponent)
elif choice == 3:
self.rangeAttack(opponent)
if opponent.health > 0:
opponent.defaultAttack(self)
if self.health <= 0:
combat = False
else:
combat = False
self.gold = self.gold + opponent.gold
opponent.gold = 0
opponent.model.grid.remove_agent(opponent)
else:
self.magicAttackAttack(opponent)
if opponent.health > 0:
opponent.defaultAttack(self)
if self.health <= 0:
combat = False
else:
combat = False
self.gold = self.gold + opponent.gold
opponent.gold = 0
opponent.model.grid.remove_agent(opponent)
def step(self):
if self.health > 0:
self.move()
cellmates = self.model.grid.get_cell_list_contents([self.pos])
if len(cellmates) > 1:
if isinstance(cellmates[0], Box):
self.gold = self.gold + cellmates[0].gold
cellmates[1].gold = 0
else:
opponent = cellmates[1]
self.fightOrFlight(opponent)

View File

@ -1,6 +1,6 @@
from mesa import Agent, Model from mesa import Agent, Model
import random import random
from agent2 import Weapon, Armor, Box, Creature, Player, dice 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)

View File

@ -1,88 +1,5 @@
from mesa import Agent from mesa import Agent
import random from othercharacters import dice, Box, Creature, Armor, Weapon
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)
class Player(Creature): class Player(Creature):
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3): def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3):
@ -102,6 +19,8 @@ class Player(Creature):
self.isCreature = False self.isCreature = False
self.directions = [[0, 1], [1, 0], [0, -1], [-1, 0]] self.directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
self.direction = 0 self.direction = 0
self.queue=[]
self.goalchest=False
def rotate(self, clockwise=True): def rotate(self, clockwise=True):
if clockwise: if clockwise:
@ -119,13 +38,13 @@ class Player(Creature):
if new_position in possible_steps: if new_position in possible_steps:
self.model.grid.move_agent(self, new_position) self.model.grid.move_agent(self, new_position)
def move(self): # OLD # def move(self): # OLD
possible_steps = self.model.grid.get_neighborhood( # possible_steps = self.model.grid.get_neighborhood(
self.pos, # self.pos,
moore=True, # moore=True,
include_center=False) # include_center=False)
new_position = self.random.choice(possible_steps) # new_position = self.random.choice(possible_steps)
self.model.grid.move_agent(self, new_position) # self.model.grid.move_agent(self, new_position)
def meleeAttack(self, opponent): def meleeAttack(self, opponent):
attackValue = self.strength + dice(6) attackValue = self.strength + dice(6)
@ -240,6 +159,7 @@ class Player(Creature):
cell_contents = self.model.grid.get_cell_list_contents([cur_pos]) cell_contents = self.model.grid.get_cell_list_contents([cur_pos])
if cell_contents and any([isinstance(thing, Box) for thing in cell_contents]): if cell_contents and any([isinstance(thing, Box) for thing in cell_contents]):
found_target = cur_pos found_target = cur_pos
self.goalchest=True
break break
#enqueue safe unvisited neighbours #enqueue safe unvisited neighbours
@ -266,12 +186,94 @@ class Player(Creature):
return False return False
# Funkcja konwertujaca wspolrzedne nastepnego pola do odwiedzenia
# na kolejke akcji do wykonania
# tl - turn left, tr - turn right, fwd - forward, op - open
# queue - kolejka akcji do zrobienia, pole klasy Player
# path - kolejka pol do odwiedzenia, pole klasy Player
# pole to element wziety z kolejki path
def actionPlanner(self, cell):
x0 = self.pos[0]
y0 = self.pos[1]
x = cell[0]
y = cell[1]
if (x > x0):
if (self.direction == 1):
self.queue.append("fwd")
elif (self.direction == 0):
self.queue.append("tr")
self.queue.append("fwd")
elif (self.direction == 2):
self.queue.append("tl")
self.queue.append("fwd")
else:
self.queue.append("tr")
self.queue.append("tr")
self.queue.insert("fwd")
elif (x < x0):
if (self.direction == 3):
self.queue.append("fwd")
elif (self.direction == 0):
self.queue.append("tl")
self.queue.append("fwd")
elif (self.direction == 2):
self.queue.append("tr")
self.queue.append("fwd")
else:
self.queue.append("tr")
self.queue.append("tr")
self.queue.append("fwd")
else:
if (y > y0):
if (self.direction == 0):
self.queue.append("fwd")
elif (self.direction == 1):
self.queue.append("tl")
self.queue.append("fwd")
elif (self.direction == 3):
self.queue.append("tr")
self.queue.append("fwd")
else:
self.queue.append("tr")
self.queue.append("tr")
self.queue.append("fwd")
else:
if (self.direction == 2):
self.queue.append("fwd")
elif (self.direction == 3):
self.queue.append("tl")
self.queue.append("fwd")
elif (self.direction == 1):
self.queue.append("tr")
self.queue.append("fwd")
else:
self.queue.append("tr")
self.queue.append("tr")
self.queue.append("fwd")
# if (len(self.path)==0):
# self.queue.append("op")
def step(self): def step(self):
if self.health > 0: if self.health > 0:
self.moveFwd() # self.moveFwd()
# self.rotate(False)
if not self.goalchest: #jeśli nie ma wyznaczonej skrzynki do której idzie to robi bfs żeby ją wyznaczyć
self.path=self.findShortestPathToTarget()
print("the player should follow this path:",self.path)
for cell in self.path: #iteruje po kolejnych krotkach ze współrzędnymi pól
self.actionPlanner(cell) #dla każdego pola dodaje do kolejki kilka akcji potrzebnych żeby do niego dojść
print(self.queue)
if len(self.queue)!=0:
self.action=self.queue.pop(0)
if self.action=="tr":
self.rotate(True)
elif self.action=="tl":
self.rotate(False) self.rotate(False)
print(self.findShortestPathToTarget()) elif self.action=="fwd":
self.moveFwd()
cellmates = self.model.grid.get_cell_list_contents([self.pos]) cellmates = self.model.grid.get_cell_list_contents([self.pos])
if len(cellmates) > 1: if len(cellmates) > 1:
if isinstance(cellmates[0], Box): if isinstance(cellmates[0], Box):

View File

@ -1,5 +1,6 @@
from mesa import Model, Agent from mesa import Model
from agent2 import Player, Creature, Box, Wall, dice from hero import Player
from othercharacters import Creature, Box, Wall, dice
from armory import WM1, A1, WR1, S1, WM2, A2 from 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
@ -9,8 +10,8 @@ import random
x = 10 x = 10
y = 10 y = 10
step_counter = 0 step_counter = 0
boxes_number = 10 boxes_number = 5
creatures_number = 10 creatures_number = 5
class GameMap(Model): class GameMap(Model):
@ -39,7 +40,8 @@ class GameMap(Model):
else: else:
pass pass
for i in range(self.boxes_number, self.boxes_number+self.creatures_number): #taki range, żeby każdy agent miał poprawne unique_id 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)
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, dice(6))
x = self.random.randrange(self.grid.width) x = self.random.randrange(self.grid.width)
@ -50,7 +52,6 @@ class GameMap(Model):
else: else:
pass pass
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta # self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
def step(self): def step(self):

86
othercharacters.py Normal file
View File

@ -0,0 +1,86 @@
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

@ -5,13 +5,12 @@ from mesa.visualization.ModularVisualization import ModularServer
def player_representation(agent): def player_representation(agent):
portrayal = {"Shape": "sprites/hero.png", portrayal = {"Shape": "sprites/hero.png",
"Layer": 2} "Layer": 1}
if agent.isBox: if agent.isBox:
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'
portrayal["Layer"] = 1
return portrayal return portrayal
grid = CanvasGrid(player_representation, 10, 10, 500, 500) grid = CanvasGrid(player_representation, 10, 10, 500, 500)