From 0969564c3ffd704c022dae3c442031cccb5e96e0 Mon Sep 17 00:00:00 2001 From: tubks Date: Tue, 13 Apr 2021 23:08:57 +0200 Subject: [PATCH] integrating bfs search and player movement in progress --- agent.py | 168 -------------------------------------- armory.py | 92 ++++++++++----------- agent2.py => hero.py | 190 ++++++++++++++++++++++--------------------- model.py | 29 +++---- othercharacters.py | 86 ++++++++++++++++++++ server.py | 3 +- 6 files changed, 244 insertions(+), 324 deletions(-) delete mode 100644 agent.py rename agent2.py => hero.py (65%) create mode 100644 othercharacters.py diff --git a/agent.py b/agent.py deleted file mode 100644 index 3ebc689..0000000 --- a/agent.py +++ /dev/null @@ -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) - - diff --git a/armory.py b/armory.py index 1a6db27..d8a872e 100644 --- a/armory.py +++ b/armory.py @@ -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)) diff --git a/agent2.py b/hero.py similarity index 65% rename from agent2.py rename to hero.py index 1f58b39..9e064c8 100644 --- a/agent2.py +++ b/hero.py @@ -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): diff --git a/model.py b/model.py index 7c2d078..f2d8378 100644 --- a/model.py +++ b/model.py @@ -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 \ No newline at end of file + # self.datacollector.collect(self) #na razie niepotrzebne diff --git a/othercharacters.py b/othercharacters.py new file mode 100644 index 0000000..b558ec1 --- /dev/null +++ b/othercharacters.py @@ -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) + diff --git a/server.py b/server.py index 5e382d0..eeb22fa 100644 --- a/server.py +++ b/server.py @@ -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)