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,54 +1,54 @@
from mesa import Agent, Model
import random
from agent2 import Weapon, Armor, Box, Creature, Player, dice
from hero import Weapon, Armor
WM1 = Weapon("Log","Melee",1)
WM2 = Weapon("Log","Melee",1)
WM3 = Weapon("Log","Melee",1)
WM4 = Weapon("Dagger","Melee",1)
WM5 = Weapon("Dagger","Melee",1)
WM6 = Weapon("Dagger","Melee",1)
WM7 = Weapon("Sword","Melee",2)
WM8 = Weapon("Sword","Melee",2)
WM9 = Weapon("Sword","Melee",2)
WM10 = Weapon("Axe","Melee",3)
WM11 = Weapon("Axe","Melee",3)
WM12 = Weapon("Battle axe","Melee",4)
WM1 = Weapon("Log", "Melee", 1)
WM2 = Weapon("Log", "Melee", 1)
WM3 = Weapon("Log", "Melee", 1)
WM4 = Weapon("Dagger", "Melee", 1)
WM5 = Weapon("Dagger", "Melee", 1)
WM6 = Weapon("Dagger", "Melee", 1)
WM7 = Weapon("Sword", "Melee", 2)
WM8 = Weapon("Sword", "Melee", 2)
WM9 = Weapon("Sword", "Melee", 2)
WM10 = Weapon("Axe", "Melee", 3)
WM11 = Weapon("Axe", "Melee", 3)
WM12 = Weapon("Battle axe", "Melee", 4)
WR1 = Weapon("Sling","Range",1)
WR2 = Weapon("Sling","Range",1)
WR3 = Weapon("Sling","Range",1)
WR4 = Weapon("Bow","Range",2)
WR5 = Weapon("Bow","Range",2)
WR6 = Weapon("Bow","Range",2)
WR7 = Weapon("Bow","Range",2)
WR8 = Weapon("Longbow","Range",3)
WR9 = Weapon("Longbow","Range",3)
WR10 = Weapon("Crossbow","Range",4)
WR1 = Weapon("Sling", "Range", 1)
WR2 = Weapon("Sling", "Range", 1)
WR3 = Weapon("Sling", "Range", 1)
WR4 = Weapon("Bow", "Range", 2)
WR5 = Weapon("Bow", "Range", 2)
WR6 = Weapon("Bow", "Range", 2)
WR7 = Weapon("Bow", "Range", 2)
WR8 = Weapon("Longbow", "Range", 3)
WR9 = Weapon("Longbow", "Range", 3)
WR10 = Weapon("Crossbow", "Range", 4)
S1 = Weapon("Push","Magic",2)
S2 = Weapon("Push","Magic",2)
S3 = Weapon("Punch","Magic",4)
S4 = Weapon("Punch","Magic",4)
S5 = Weapon("Fireball","Magic",6)
S6 = Weapon("Firestorm","Magic",10)
S1 = Weapon("Push", "Magic", 2)
S2 = Weapon("Push", "Magic", 2)
S3 = Weapon("Punch", "Magic", 4)
S4 = Weapon("Punch", "Magic", 4)
S5 = Weapon("Fireball", "Magic", 6)
S6 = Weapon("Firestorm", "Magic", 10)
A1 = Armor("None",0,0)
A2 = Armor("None",0,0)
A3 = Armor("None",0,0)
A4 = Armor("None",0,0)
A5 = Armor("None",0,0)
A6 = Armor("None",0,0)
A7 = Armor("None",0,0)
A8 = Armor("Leather Armor",1,0)
A9 = Armor("Leather Armor",1,0)
A10 = Armor("Leather Armor",1,0)
A11 = Armor("Chain Mail",2,0)
A12 = Armor("Chain Mail",2,0)
A13 = Armor("Plate Armor",3,0)
A14 = Armor("Robe",1,2)
A15 = Armor("Robe",1,2)
A16 = Armor("Magical Plate Armor",3,2)
A1 = Armor("None", 0, 0)
A2 = Armor("None", 0, 0)
A3 = Armor("None", 0, 0)
A4 = Armor("None", 0, 0)
A5 = Armor("None", 0, 0)
A6 = Armor("None", 0, 0)
A7 = Armor("None", 0, 0)
A8 = Armor("Leather Armor", 1, 0)
A9 = Armor("Leather Armor", 1, 0)
A10 = Armor("Leather Armor", 1, 0)
A11 = Armor("Chain Mail", 2, 0)
A12 = Armor("Chain Mail", 2, 0)
A13 = Armor("Plate Armor", 3, 0)
A14 = Armor("Robe", 1, 2)
A15 = Armor("Robe", 1, 2)
A16 = Armor("Magical Plate Armor", 3, 2)
# C1 = Box(WM6)
# C2 = Box(WR3)
@ -63,7 +63,7 @@ A16 = Armor("Magical Plate Armor",3,2)
# C11 = Box(A12)
# 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):
# M1 = Creature("Goblin",2,2,1,10,10,WM2,A2,dice(6))
# M2 = Creature("Goblin",2,2,1,10,10,WM3,A3,dice(6))

View File

@ -1,88 +1,5 @@
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)
from othercharacters import dice, Box, Creature, Armor, Weapon
class Player(Creature):
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.directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
self.direction = 0
self.queue=[]
self.goalchest=False
def rotate(self, clockwise=True):
if clockwise:
@ -119,13 +38,13 @@ class Player(Creature):
if new_position in possible_steps:
self.model.grid.move_agent(self, new_position)
def move(self): # OLD
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 move(self): # OLD
# 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)
@ -240,6 +159,7 @@ class Player(Creature):
cell_contents = self.model.grid.get_cell_list_contents([cur_pos])
if cell_contents and any([isinstance(thing, Box) for thing in cell_contents]):
found_target = cur_pos
self.goalchest=True
break
#enqueue safe unvisited neighbours
@ -266,12 +186,94 @@ class Player(Creature):
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):
if self.health > 0:
self.moveFwd()
self.rotate(False)
print(self.findShortestPathToTarget())
# 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)
elif self.action=="fwd":
self.moveFwd()
cellmates = self.model.grid.get_cell_list_contents([self.pos])
if len(cellmates) > 1:
if isinstance(cellmates[0], Box):

View File

@ -1,16 +1,17 @@
from mesa import Model, Agent
from agent2 import Player, Creature, Box, Wall, dice
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
# from mesa.datacollection import DataCollector
import random
x = 10
y = 10
step_counter = 0
boxes_number = 10
creatures_number = 10
boxes_number = 5
creatures_number = 5
class GameMap(Model):
@ -20,9 +21,9 @@ class GameMap(Model):
# 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.running = True
# player = Player(1000, self)
player = Player(1000, self, "Janusz", 3, 3, 3, 20, 20, WM1, A1, 0, WR1, S1)
self.schedule.add(player)
x = self.random.randrange(self.grid.width)
y = self.random.randrange(self.grid.height)
@ -30,7 +31,7 @@ class GameMap(Model):
for i in range(self.boxes_number):
box = Box(i, self)
#self.schedule.add(box)
# 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)):
@ -39,9 +40,10 @@ class GameMap(Model):
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))
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)):
@ -50,9 +52,8 @@ class GameMap(Model):
else:
pass
# self.datacollector=DataCollector #informacje o stanie planszy, pozycja agenta
def step(self):
self.schedule.step()
# self.datacollector.collect(self) #na razie niepotrzebne
# self.datacollector.collect(self) #na razie niepotrzebne

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):
portrayal = {"Shape": "sprites/hero.png",
"Layer": 2}
"Layer": 1}
if agent.isBox:
portrayal["Shape"] = "sprites/box.png"
portrayal["Layer"] = 0
elif agent.isCreature:
portrayal["Shape"]='sprites/goblin.png'
portrayal["Layer"] = 1
return portrayal
grid = CanvasGrid(player_representation, 10, 10, 500, 500)