Compare commits
No commits in common. "master" and "grzgap-feature-astar" have entirely different histories.
master
...
grzgap-fea
47
actions.py
Normal file
47
actions.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# 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
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
from src.agent.model.weapon import Weapon
|
from mesa import Agent, Model
|
||||||
from src.agent.model.armor import Armor
|
import random
|
||||||
|
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)
|
||||||
@ -14,16 +15,16 @@ WM10 = Weapon("Axe", "Melee", 3)
|
|||||||
WM11 = Weapon("Axe", "Melee", 3)
|
WM11 = Weapon("Axe", "Melee", 3)
|
||||||
WM12 = Weapon("Battle axe", "Melee", 4)
|
WM12 = Weapon("Battle axe", "Melee", 4)
|
||||||
|
|
||||||
WR1 = Weapon("Sling", "Ranged", 1)
|
WR1 = Weapon("Sling", "Range", 1)
|
||||||
WR2 = Weapon("Sling", "Ranged", 1)
|
WR2 = Weapon("Sling", "Range", 1)
|
||||||
WR3 = Weapon("Sling", "Ranged", 1)
|
WR3 = Weapon("Sling", "Range", 1)
|
||||||
WR4 = Weapon("Bow", "Ranged", 2)
|
WR4 = Weapon("Bow", "Range", 2)
|
||||||
WR5 = Weapon("Bow", "Ranged", 2)
|
WR5 = Weapon("Bow", "Range", 2)
|
||||||
WR6 = Weapon("Bow", "Ranged", 2)
|
WR6 = Weapon("Bow", "Range", 2)
|
||||||
WR7 = Weapon("Bow", "Ranged", 2)
|
WR7 = Weapon("Bow", "Range", 2)
|
||||||
WR8 = Weapon("Longbow", "Ranged", 3)
|
WR8 = Weapon("Longbow", "Range", 3)
|
||||||
WR9 = Weapon("Longbow", "Ranged", 3)
|
WR9 = Weapon("Longbow", "Range", 3)
|
||||||
WR10 = Weapon("Crossbow", "Ranged", 4)
|
WR10 = Weapon("Crossbow", "Range", 4)
|
||||||
|
|
||||||
S1 = Weapon("Push", "Magic", 2)
|
S1 = Weapon("Push", "Magic", 2)
|
||||||
S2 = Weapon("Push", "Magic", 2)
|
S2 = Weapon("Push", "Magic", 2)
|
||||||
@ -61,9 +62,9 @@ A16 = Armor("Magical Plate Armor", 3, 2)
|
|||||||
# C10 = Box(A8)
|
# C10 = Box(A8)
|
||||||
# C11 = Box(A12)
|
# C11 = Box(A12)
|
||||||
# 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, max_hp, hp, weapon, arm, g):
|
# 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))
|
# 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))
|
1000
data_dd2.csv
1000
data_dd2.csv
File diff suppressed because it is too large
Load Diff
5000
data_dd3.csv
5000
data_dd3.csv
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,5 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
class Direction(Enum):
|
class Direction(Enum):
|
||||||
N = 0
|
N = 0
|
||||||
E = 1
|
E = 1
|
||||||
@ -11,6 +10,6 @@ class Direction(Enum):
|
|||||||
v = (self.value+1)%4
|
v = (self.value+1)%4
|
||||||
return Direction(v)
|
return Direction(v)
|
||||||
|
|
||||||
def counter_clockwise(self):
|
def counterClockwise(self):
|
||||||
v = (self.value-1)%4
|
v = (self.value-1)%4
|
||||||
return Direction(v)
|
return Direction(v)
|
160
dt.py
160
dt.py
@ -1,160 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
import pandas as pd
|
|
||||||
from sklearn.model_selection import train_test_split
|
|
||||||
from sklearn.metrics import accuracy_score
|
|
||||||
|
|
||||||
class GadId3Classifier:
|
|
||||||
def fit(self, input, output):
|
|
||||||
data = input.copy()
|
|
||||||
data[output.name] = output
|
|
||||||
self.tree = self.decision_tree(data, data, input.columns, output.name)
|
|
||||||
|
|
||||||
def predict(self, input):
|
|
||||||
# convert input data into a dictionary of samples
|
|
||||||
samples = input.to_dict(orient='records')
|
|
||||||
predictions = []
|
|
||||||
|
|
||||||
# make a prediction for every sample
|
|
||||||
for sample in samples:
|
|
||||||
predictions.append(self.make_prediction(sample, self.tree, 1.0))
|
|
||||||
|
|
||||||
return predictions
|
|
||||||
|
|
||||||
def entropy(self, attribute_column):
|
|
||||||
# find unique values and their frequency counts for the given attribute
|
|
||||||
values, counts = np.unique(attribute_column, return_counts=True)
|
|
||||||
|
|
||||||
# calculate entropy for each unique value
|
|
||||||
entropy_list = []
|
|
||||||
|
|
||||||
for i in range(len(values)):
|
|
||||||
probability = counts[i]/np.sum(counts)
|
|
||||||
entropy_list.append(-probability*np.log2(probability))
|
|
||||||
|
|
||||||
# calculate sum of individual entropy values
|
|
||||||
total_entropy = np.sum(entropy_list)
|
|
||||||
|
|
||||||
return total_entropy
|
|
||||||
|
|
||||||
def information_gain(self, data, feature_attribute_name, target_attribute_name):
|
|
||||||
# find total entropy of given subset
|
|
||||||
total_entropy = self.entropy(data[target_attribute_name])
|
|
||||||
|
|
||||||
# find unique values and their frequency counts for the attribute to be split
|
|
||||||
values, counts = np.unique(data[feature_attribute_name], return_counts=True)
|
|
||||||
|
|
||||||
# calculate weighted entropy of subset
|
|
||||||
weighted_entropy_list = []
|
|
||||||
|
|
||||||
for i in range(len(values)):
|
|
||||||
subset_probability = counts[i]/np.sum(counts)
|
|
||||||
subset_entropy = self.entropy(data.where(data[feature_attribute_name]==values[i]).dropna()[target_attribute_name])
|
|
||||||
weighted_entropy_list.append(subset_probability*subset_entropy)
|
|
||||||
|
|
||||||
total_weighted_entropy = np.sum(weighted_entropy_list)
|
|
||||||
|
|
||||||
# calculate information gain
|
|
||||||
information_gain = total_entropy - total_weighted_entropy
|
|
||||||
|
|
||||||
return information_gain
|
|
||||||
|
|
||||||
def decision_tree(self, data, orginal_data, feature_attribute_names, target_attribute_name, parent_node_class=None):
|
|
||||||
# base cases:
|
|
||||||
# if data is pure, return the majority class of subset
|
|
||||||
unique_classes = np.unique(data[target_attribute_name])
|
|
||||||
if len(unique_classes) <= 1:
|
|
||||||
return unique_classes[0]
|
|
||||||
# if subset is empty, ie. no samples, return majority class of original data
|
|
||||||
elif len(data) == 0:
|
|
||||||
majority_class_index = np.argmax(np.unique(original_data[target_attribute_name], return_counts=True)[1])
|
|
||||||
return np.unique(original_data[target_attribute_name])[majority_class_index]
|
|
||||||
# if data set contains no features to train with, return parent node class
|
|
||||||
elif len(feature_attribute_names) == 0:
|
|
||||||
return parent_node_class
|
|
||||||
# if none of the above are true, construct a branch:
|
|
||||||
else:
|
|
||||||
# determine parent node class of current branch
|
|
||||||
majority_class_index = np.argmax(np.unique(data[target_attribute_name], return_counts=True)[1])
|
|
||||||
parent_node_class = unique_classes[majority_class_index]
|
|
||||||
|
|
||||||
# determine information gain values for each feature
|
|
||||||
# choose feature which best splits the data, ie. highest value
|
|
||||||
ig_values = [self.information_gain(data, feature, target_attribute_name) for feature in feature_attribute_names]
|
|
||||||
best_feature_index = np.argmax(ig_values)
|
|
||||||
best_feature = feature_attribute_names[best_feature_index]
|
|
||||||
|
|
||||||
# create tree structure, empty at first
|
|
||||||
tree = {best_feature: {}}
|
|
||||||
|
|
||||||
# remove best feature from available features, it will become the parent node
|
|
||||||
feature_attribute_names = [i for i in feature_attribute_names if i != best_feature]
|
|
||||||
|
|
||||||
# create nodes under parent node
|
|
||||||
parent_attribute_values = np.unique(data[best_feature])
|
|
||||||
for value in parent_attribute_values:
|
|
||||||
sub_data = data.where(data[best_feature] == value).dropna()
|
|
||||||
|
|
||||||
# call the algorithm recursively
|
|
||||||
subtree = self.decision_tree(sub_data, orginal_data, feature_attribute_names, target_attribute_name, parent_node_class)
|
|
||||||
|
|
||||||
# add subtree to original tree
|
|
||||||
tree[best_feature][value] = subtree
|
|
||||||
|
|
||||||
return tree
|
|
||||||
|
|
||||||
def make_prediction(self, sample, tree, default=1):
|
|
||||||
# map sample data to tree
|
|
||||||
for attribute in list(sample.keys()):
|
|
||||||
# check if feature exists in tree
|
|
||||||
if attribute in list(tree.keys()):
|
|
||||||
try:
|
|
||||||
result = tree[attribute][sample[attribute]]
|
|
||||||
except:
|
|
||||||
return default
|
|
||||||
|
|
||||||
result = tree[attribute][sample[attribute]]
|
|
||||||
|
|
||||||
# if more attributes exist within result, recursively find best result
|
|
||||||
if isinstance(result, dict):
|
|
||||||
return self.make_prediction(sample, result)
|
|
||||||
else:
|
|
||||||
return result
|
|
||||||
|
|
||||||
#data_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data"
|
|
||||||
#df = pd.read_csv(data_url, header=None)
|
|
||||||
df = pd.read_csv("data_dd3.csv", header=None)
|
|
||||||
|
|
||||||
# rename known columns
|
|
||||||
columns = ['p_strength','p_agility','p_wisdom','p_health','p_melee_damage','p_ranged_damage','p_magic_damage',
|
|
||||||
'p_armor_defence','p_armor_magic_protection','e_strength','e_agility','e_wisdom','e_health','e_melee_damage',
|
|
||||||
'e_ranged_damage','e_magic_damage','e_armor_defence','e_armor_magic_protection','e_attack_type','strategy']
|
|
||||||
#columns = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg',
|
|
||||||
#'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'thal', 'disease_present']
|
|
||||||
df.columns = columns
|
|
||||||
|
|
||||||
# convert disease_present feature to binary
|
|
||||||
# df['disease_present'] = df.disease_present.replace([1,2,3,4], 1)
|
|
||||||
|
|
||||||
# drop rows with missing values, missing = ?
|
|
||||||
df = df.replace("?", np.nan)
|
|
||||||
df = df.dropna()
|
|
||||||
|
|
||||||
# organize data into input and output
|
|
||||||
#X = df.drop(columns="disease_present")
|
|
||||||
#y = df["disease_present"]
|
|
||||||
X = df.drop(columns="strategy")
|
|
||||||
y = df["strategy"]
|
|
||||||
|
|
||||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
|
|
||||||
|
|
||||||
# initialize and fit model
|
|
||||||
model = GadId3Classifier()
|
|
||||||
model.fit(X_train, y_train)
|
|
||||||
|
|
||||||
# return accuracy score
|
|
||||||
y_pred = model.predict(X_test)
|
|
||||||
a = accuracy_score(y_test, y_pred)
|
|
||||||
|
|
||||||
print(a)
|
|
||||||
#print(y_pred)
|
|
||||||
#print(y_test)
|
|
325
hero.py
Normal file
325
hero.py
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
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))
|
65
model.py
Normal file
65
model.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
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
|
BIN
nn_model.h5
BIN
nn_model.h5
Binary file not shown.
@ -5,15 +5,6 @@ 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
|
||||||
|
|
||||||
@ -21,4 +12,4 @@ class Node:
|
|||||||
self._parent = predecessor
|
self._parent = predecessor
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return self._cost < other.get_cost()
|
return self._cost < other._cost
|
86
othercharacters.py
Normal file
86
othercharacters.py
Normal 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)
|
||||||
|
|
54
server.py
54
server.py
@ -1,63 +1,21 @@
|
|||||||
from src.agent.map.gameMap import GameMap
|
from model import GameMap
|
||||||
from mesa.visualization.modules import CanvasGrid
|
from mesa.visualization.modules import CanvasGrid
|
||||||
from mesa.visualization.modules.TextVisualization import TextElement
|
|
||||||
from mesa.visualization.ModularVisualization import ModularServer
|
from mesa.visualization.ModularVisualization import ModularServer
|
||||||
#from src.decisiontree import create_model
|
|
||||||
from src.direction import Direction
|
|
||||||
from collections import defaultdict
|
|
||||||
import src.agent.ga_chromosome as ga
|
|
||||||
|
|
||||||
def player_representation(agent):
|
def player_representation(agent):
|
||||||
portrayal = {"Shape": "sprites/heroE.png",
|
portrayal = {"Shape": "sprites/hero.png",
|
||||||
"Layer": 1}
|
"Layer": 1}
|
||||||
if agent.isPlayer and agent.direction==Direction.N:
|
if agent.isBox:
|
||||||
portrayal["Shape"] = "sprites/heroN.png"
|
|
||||||
elif agent.isPlayer and agent.direction == Direction.W:
|
|
||||||
portrayal["Shape"] = "sprites/heroW.png"
|
|
||||||
elif agent.isPlayer and agent.direction == Direction.S:
|
|
||||||
portrayal["Shape"] = "sprites/heroS.png"
|
|
||||||
elif agent.isBox:
|
|
||||||
portrayal["Shape"] = "sprites/box.png"
|
portrayal["Shape"] = "sprites/box.png"
|
||||||
portrayal["Layer"] = 0
|
portrayal["Layer"] = 0
|
||||||
elif agent.isCreature:
|
elif agent.isCreature:
|
||||||
if agent.name=='Goblin':
|
|
||||||
portrayal["Shape"]='sprites/goblin.png'
|
portrayal["Shape"]='sprites/goblin.png'
|
||||||
elif agent.name=='Skeleton':
|
|
||||||
portrayal["Shape"] = 'sprites/skeletonArcher.png'
|
|
||||||
return portrayal
|
return portrayal
|
||||||
|
|
||||||
def chest_content(agent):
|
grid = CanvasGrid(player_representation, 10, 10, 500, 500)
|
||||||
if agent.isBox:
|
|
||||||
portrayal = {"Shape": "sprites/coin.jpg",
|
|
||||||
"Layer": 1}
|
|
||||||
return portrayal
|
|
||||||
|
|
||||||
grid = CanvasGrid(player_representation, 10, 10, 700, 700)
|
|
||||||
image=CanvasGrid(chest_content, 1, 1, 200, 200)
|
|
||||||
class Stats(TextElement):
|
|
||||||
def render(self, model):
|
|
||||||
hp = str(model.get_hp())
|
|
||||||
position = str(model.get_position())
|
|
||||||
gold = str(model.get_gold())
|
|
||||||
return "Player hp: {}<br>Current position: {}<br>Player's gold: {}".format(
|
|
||||||
hp, position, gold)
|
|
||||||
# class ChestContent(CanvasGrid):
|
|
||||||
# def render(self,model):
|
|
||||||
# grid_state = defaultdict(list)
|
|
||||||
# portrayal = self.chest_content(agent)
|
|
||||||
# portrayal["x"] = 0
|
|
||||||
# portrayal["y"] = 0
|
|
||||||
# grid_state[portrayal["Layer"]].append(portrayal)
|
|
||||||
# return
|
|
||||||
# class FightStats(TextElement):
|
|
||||||
# def render(self, model):
|
|
||||||
# if model.player.combat:
|
|
||||||
# return model.player.describe_situation(model.player.opponent, model.player.strategy)
|
|
||||||
# else:
|
|
||||||
# return "Not fighting"
|
|
||||||
ga.create_model()
|
|
||||||
server = ModularServer(GameMap,
|
server = ModularServer(GameMap,
|
||||||
[grid,Stats()],
|
[grid],
|
||||||
"Map",
|
"Map",
|
||||||
{"x":10, "y":10})
|
{"x":10, "y":10})
|
||||||
server.port = 8081
|
server.port = 8081
|
||||||
|
Before Width: | Height: | Size: 208 B After Width: | Height: | Size: 208 B |
Binary file not shown.
Before Width: | Height: | Size: 292 B |
Binary file not shown.
Before Width: | Height: | Size: 286 B |
Binary file not shown.
Before Width: | Height: | Size: 293 B |
Binary file not shown.
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
from .hero import Player
|
|
||||||
from .map.gameMap import GameMap
|
|
||||||
from .model import *
|
|
||||||
from .state import AgentState
|
|
Binary file not shown.
Binary file not shown.
@ -1,215 +0,0 @@
|
|||||||
import numpy.random
|
|
||||||
import random
|
|
||||||
import pandas as pd
|
|
||||||
import os
|
|
||||||
import rpy2.robjects as robjects
|
|
||||||
from rpy2.robjects.packages import importr
|
|
||||||
from rpy2.robjects import pandas2ri
|
|
||||||
from rpy2.robjects.conversion import localconverter
|
|
||||||
from rpy2.robjects.packages import importr
|
|
||||||
from src.nominalize import nominalize
|
|
||||||
from src.decisiontree import create_model
|
|
||||||
MAX_COMBAT_TIME = 20
|
|
||||||
attack_types=["MELEE", "RANGED","MAGIC"]
|
|
||||||
class EnemyStats:
|
|
||||||
def __init__(self):
|
|
||||||
self.strength = random.randint(1, 7)
|
|
||||||
self.agility = random.randint(1, 7)
|
|
||||||
self.wisdom = random.randint(1, 7)
|
|
||||||
self.max_health = random.randint(5, 30)
|
|
||||||
self.health=self.max_health
|
|
||||||
self.melee_wep_damage = 1
|
|
||||||
self.ranged_wep_damage = 1
|
|
||||||
self.magic_wep_damage = 2
|
|
||||||
self.armor_defence = 0
|
|
||||||
self.armor_magic_protection = 1
|
|
||||||
self.attack_type=random.choice(attack_types)
|
|
||||||
|
|
||||||
def meleeAttack(self, opponent):
|
|
||||||
attackValue = self.strength + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.strength + opponent.armor_defence
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if damage > 0:
|
|
||||||
opponent.health -= (damage + self.melee_wep_damage)
|
|
||||||
|
|
||||||
def rangeAttack(self, opponent):
|
|
||||||
attackValue = self.agility + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.agility
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if (damage > 0) and (damage + self.ranged_wep_damage - opponent.armor_defence > 0):
|
|
||||||
opponent.health -= (damage + self.ranged_wep_damage - opponent.armor_defence)
|
|
||||||
|
|
||||||
def magicAttack(self, opponent):
|
|
||||||
attackValue = self.wisdom + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.wisdom
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if (damage > 0) and (damage + self.magic_wep_damage - opponent.armor_magic_protection > 0):
|
|
||||||
opponent.health -= (damage + self.magic_wep_damage - opponent.armor_magic_protection)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self.health = self.max_health
|
|
||||||
|
|
||||||
def try_combat(my_seed, p, e, player_att_type, enemy_att_type):
|
|
||||||
random.seed(my_seed)
|
|
||||||
current_iteration = 0
|
|
||||||
while True:
|
|
||||||
if player_att_type == 0:
|
|
||||||
p.meleeAttack(e)
|
|
||||||
elif player_att_type == 1:
|
|
||||||
p.rangeAttack(e)
|
|
||||||
else:
|
|
||||||
p.magicAttack(e)
|
|
||||||
|
|
||||||
if e.health<=0:
|
|
||||||
return p.health
|
|
||||||
|
|
||||||
if enemy_att_type == 0:
|
|
||||||
e.meleeAttack(p)
|
|
||||||
elif enemy_att_type == 1:
|
|
||||||
e.rangeAttack(p)
|
|
||||||
else:
|
|
||||||
e.magicAttack(p)
|
|
||||||
|
|
||||||
if p.health<=0:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
current_iteration += 1
|
|
||||||
if current_iteration >= MAX_COMBAT_TIME:
|
|
||||||
return 0
|
|
||||||
p.reset()
|
|
||||||
e.reset()
|
|
||||||
|
|
||||||
class PlayerStats(EnemyStats):
|
|
||||||
def __init__(self, s, a, w):
|
|
||||||
self.strength = 1+s
|
|
||||||
self.agility = 1+a
|
|
||||||
self.wisdom = 1+w
|
|
||||||
self.max_health = 50
|
|
||||||
self.health = 50
|
|
||||||
self.melee_wep_damage = 1
|
|
||||||
self.ranged_wep_damage = 1
|
|
||||||
self.magic_wep_damage = 2
|
|
||||||
self.armor_defence = 0
|
|
||||||
self.armor_magic_protection = 0
|
|
||||||
|
|
||||||
def predict_strategy(self, opponent):
|
|
||||||
testcase = pd.DataFrame({'p_strength': nominalize(self.strength,7),
|
|
||||||
'p_agility':nominalize(self.agility, 7),
|
|
||||||
'p_wisdom':nominalize(self.wisdom,7),
|
|
||||||
'p_health':nominalize(self.health,50),
|
|
||||||
'p_melee_damage':nominalize(self.melee_wep_damage, 10),
|
|
||||||
'p_ranged_damage':nominalize(self.ranged_wep_damage,10),
|
|
||||||
'p_magic_damage':nominalize(self.magic_wep_damage,10),
|
|
||||||
'p_armor_defence':nominalize(self.armor_defence,5),
|
|
||||||
'p_armor_magic_protection':nominalize(self.armor_magic_protection,5),
|
|
||||||
'e_strength':nominalize(opponent.strength, 10),
|
|
||||||
'e_agility':nominalize(opponent.agility, 10),
|
|
||||||
'e_wisdom':nominalize(opponent.wisdom,10),
|
|
||||||
'e_health':nominalize(opponent.health, 50),
|
|
||||||
'e_damage':nominalize(opponent.melee_wep_damage,10),
|
|
||||||
'e_armor_defence':nominalize(opponent.armor_defence, 5),
|
|
||||||
'e_armor_magic_protection':nominalize(opponent.armor_magic_protection, 5),
|
|
||||||
'e_attack_type':opponent.attack_type.upper(),
|
|
||||||
'strategy':"PASS"}, index=[1])
|
|
||||||
with localconverter(robjects.default_converter + pandas2ri.converter):
|
|
||||||
r_dataframe = robjects.conversion.py2rpy(testcase)
|
|
||||||
robjects.globalenv['r_dataframe']=r_dataframe
|
|
||||||
result=robjects.r('predict(fights.id3, r_dataframe)')
|
|
||||||
return result[0]
|
|
||||||
|
|
||||||
def fitness_function(chromosome):
|
|
||||||
s=chromosome.count(1)
|
|
||||||
a=chromosome.count(2)
|
|
||||||
w=chromosome.count(3)
|
|
||||||
p=PlayerStats(s, a, w)
|
|
||||||
# wins=[0,0,0]
|
|
||||||
# current_seed=os.urandom(16)
|
|
||||||
# for i in range(3):
|
|
||||||
# random.seed(current_seed)
|
|
||||||
# while p.health>0:
|
|
||||||
# e=EnemyStats()
|
|
||||||
# try_combat(current_seed, p, e, i, e.attack_type) #walka iles razy
|
|
||||||
# if p.health>0:
|
|
||||||
# wins[i]+=1
|
|
||||||
# p.reset()
|
|
||||||
# return max(wins)
|
|
||||||
wins=0
|
|
||||||
while p.health > 0:
|
|
||||||
e=EnemyStats()
|
|
||||||
player_attack=p.predict_strategy(e)
|
|
||||||
try_combat(os.urandom(16), p, e, attack_types.index(player_attack), attack_types.index(e.attack_type)) #walka iles razy
|
|
||||||
if p.health>0:
|
|
||||||
wins+=1
|
|
||||||
return wins
|
|
||||||
|
|
||||||
# tournament selection
|
|
||||||
def selection(pop, scores, k=3):
|
|
||||||
# first random selection
|
|
||||||
selection_ix = numpy.random.randint(len(pop))
|
|
||||||
for ix in numpy.random.randint(0, len(pop), k-1):
|
|
||||||
# check if better (e.g. perform a tournament)
|
|
||||||
if scores[ix] > scores[selection_ix]:
|
|
||||||
selection_ix = ix
|
|
||||||
return pop[selection_ix]
|
|
||||||
|
|
||||||
# crossover two parents to create two children
|
|
||||||
def crossover(p1, p2, r_cross):
|
|
||||||
# children are copies of parents by default
|
|
||||||
c1, c2 = p1.copy(), p2.copy()
|
|
||||||
# check for recombination
|
|
||||||
if numpy.random.rand() < r_cross:
|
|
||||||
# select crossover point that is not on the end of the string
|
|
||||||
pt = numpy.random.randint(1, len(p1)-2)
|
|
||||||
# perform crossover
|
|
||||||
c1 = p1[:pt] + p2[pt:]
|
|
||||||
c2 = p2[:pt] + p1[pt:]
|
|
||||||
return [c1, c2]
|
|
||||||
# mutation operator
|
|
||||||
def mutation(bitstring, r_mut):
|
|
||||||
for i in range(len(bitstring)):
|
|
||||||
# check for a mutation
|
|
||||||
if numpy.random.rand() < r_mut:
|
|
||||||
# flip the bit
|
|
||||||
bitstring[i] = random.randint(1,4)
|
|
||||||
# genetic algorithm
|
|
||||||
|
|
||||||
def genetic_algorithm(objective, n_bits, n_iter, n_pop, r_cross, r_mut):
|
|
||||||
# initial population of random bitstring
|
|
||||||
pop = [numpy.random.randint(1, 3, n_bits).tolist() for _ in range(n_pop)] # tworzy sie lista n_pop list szesciocyfrowych
|
|
||||||
# keep track of best solution
|
|
||||||
best, best_eval = 0, objective(pop[0])
|
|
||||||
# enumerate generations
|
|
||||||
for gen in range(n_iter):
|
|
||||||
# evaluate all candidates in the population
|
|
||||||
scores = [objective(c) for c in pop]
|
|
||||||
# check for new best solution
|
|
||||||
for i in range(n_pop):
|
|
||||||
if scores[i] > best_eval:
|
|
||||||
best, best_eval = pop[i], scores[i]
|
|
||||||
print(">%d, new best f(%s) = %d" % (gen, pop[i], scores[i]))
|
|
||||||
# select parents
|
|
||||||
selected = [selection(pop, scores) for _ in range(n_pop)]
|
|
||||||
# create the next generation
|
|
||||||
children = list()
|
|
||||||
for i in range(0, n_pop, 2):
|
|
||||||
# get selected parents in pairs
|
|
||||||
p1, p2 = selected[i], selected[i+1]
|
|
||||||
# crossover and mutation
|
|
||||||
for c in crossover(p1, p2, r_cross):
|
|
||||||
# mutation
|
|
||||||
mutation(c, r_mut)
|
|
||||||
# store for next generation
|
|
||||||
children.append(c)
|
|
||||||
# replace population
|
|
||||||
pop = children
|
|
||||||
return [best, best_eval]
|
|
||||||
# define the total iterations
|
|
||||||
n_iter = 10
|
|
||||||
# bits
|
|
||||||
n_bits = 6
|
|
||||||
# define the population size
|
|
||||||
n_pop = 20
|
|
||||||
# crossover rate
|
|
||||||
r_cross = 0.9
|
|
||||||
# mutation rate
|
|
||||||
r_mut = 0.05
|
|
@ -1,350 +0,0 @@
|
|||||||
import random
|
|
||||||
import pandas as pd
|
|
||||||
import rpy2.robjects as robjects
|
|
||||||
from rpy2.robjects.packages import importr
|
|
||||||
from rpy2.robjects import pandas2ri
|
|
||||||
from rpy2.robjects.conversion import localconverter
|
|
||||||
from rpy2.robjects.packages import importr
|
|
||||||
from src.agent.model import *
|
|
||||||
from src.agent.state import AgentState
|
|
||||||
from src.direction import Direction
|
|
||||||
from src.items.armory import WM9
|
|
||||||
from src.treesearch.actionsInterpreter import ActionInterpreter
|
|
||||||
from src.agent.model.dice.dice import roll_the_dice
|
|
||||||
from src.treesearch.bfs import BFS
|
|
||||||
from src.nominalize import nominalize
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import numpy as np
|
|
||||||
import os
|
|
||||||
import PIL
|
|
||||||
import tensorflow as tf
|
|
||||||
|
|
||||||
from tensorflow import keras
|
|
||||||
from tensorflow.keras import layers
|
|
||||||
from tensorflow.keras.models import Sequential
|
|
||||||
|
|
||||||
import pathlib
|
|
||||||
|
|
||||||
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.isPlayer=True
|
|
||||||
self.direction = Direction.N
|
|
||||||
self.queue = []
|
|
||||||
self.has_goal_chest = False
|
|
||||||
self.opened_chests = 0
|
|
||||||
self.__listOfChests = list_of_chests
|
|
||||||
self.__actionsCollection = []
|
|
||||||
self.combat=False
|
|
||||||
self.opponent=None
|
|
||||||
self.strategy="PASS"
|
|
||||||
|
|
||||||
def identify_content(self, chest):
|
|
||||||
dataset_url = "https://drive.google.com/uc?export=download&id=1b6w1FbupRmgVC-q9Lpdlg5OBK_gRKEUy"
|
|
||||||
data_dir = tf.keras.utils.get_file(fname='loot', origin=dataset_url, untar=True)
|
|
||||||
data_dir = pathlib.Path(data_dir)
|
|
||||||
|
|
||||||
#image_count = len(list(data_dir.glob('*/*.jpg')))
|
|
||||||
#print(image_count)
|
|
||||||
|
|
||||||
batch_size = 32
|
|
||||||
img_height = 180
|
|
||||||
img_width = 180
|
|
||||||
|
|
||||||
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
|
|
||||||
data_dir,
|
|
||||||
validation_split=0.2,
|
|
||||||
subset="training",
|
|
||||||
seed=123,
|
|
||||||
image_size=(img_height, img_width),
|
|
||||||
batch_size=batch_size)
|
|
||||||
|
|
||||||
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
|
|
||||||
data_dir,
|
|
||||||
validation_split=0.2,
|
|
||||||
subset="validation",
|
|
||||||
seed=123,
|
|
||||||
image_size=(img_height, img_width),
|
|
||||||
batch_size=batch_size)
|
|
||||||
|
|
||||||
class_names = train_ds.class_names
|
|
||||||
#print(class_names)
|
|
||||||
|
|
||||||
normalization_layer = layers.experimental.preprocessing.Rescaling(1. / 255)
|
|
||||||
|
|
||||||
normalized_ds = train_ds.map(lambda x, y: (normalization_layer(x), y))
|
|
||||||
image_batch, labels_batch = next(iter(normalized_ds))
|
|
||||||
first_image = image_batch[0]
|
|
||||||
# Notice the pixels values are now in `[0,1]`.
|
|
||||||
#print(np.min(first_image), np.max(first_image))
|
|
||||||
|
|
||||||
#num_classes = 3
|
|
||||||
|
|
||||||
# Recreate the exact same model, including its weights and the optimizer
|
|
||||||
new_model = tf.keras.models.load_model('nn_model.h5')
|
|
||||||
|
|
||||||
# Show the model architecture
|
|
||||||
#new_model.summary()
|
|
||||||
|
|
||||||
# loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)
|
|
||||||
# print('Restored model, accuracy: {:5.2f}%'.format(100 * acc))
|
|
||||||
|
|
||||||
object_url = chest.type
|
|
||||||
object_path = tf.keras.utils.get_file(chest.file_name, origin=object_url)
|
|
||||||
|
|
||||||
img = keras.preprocessing.image.load_img(
|
|
||||||
object_path, target_size=(img_height, img_width)
|
|
||||||
)
|
|
||||||
img_array = keras.preprocessing.image.img_to_array(img)
|
|
||||||
img_array = tf.expand_dims(img_array, 0) # Create a batch
|
|
||||||
|
|
||||||
predictions = new_model.predict(img_array)
|
|
||||||
score = tf.nn.softmax(predictions[0])
|
|
||||||
|
|
||||||
print(
|
|
||||||
"This image most likely belongs to {} with a {:.2f} percent confidence."
|
|
||||||
.format(class_names[np.argmax(score)], 100 * np.max(score))
|
|
||||||
)
|
|
||||||
|
|
||||||
return class_names[np.argmax(score)]
|
|
||||||
|
|
||||||
def predict_strategy(self, opponent):
|
|
||||||
testcase = pd.DataFrame({'p_strength': nominalize(self.get_strength(),10),
|
|
||||||
'p_agility':nominalize(self.get_agility(), 10),
|
|
||||||
'p_wisdom':nominalize(self.get_wisdom(),10),
|
|
||||||
'p_health':nominalize(self.get_health(),50),
|
|
||||||
'p_melee_damage':nominalize(self.get_melee_damage(), 10),
|
|
||||||
'p_ranged_damage':nominalize(self.get_ranged_damage(),10),
|
|
||||||
'p_magic_damage':nominalize(self.get_magic_damage(),10),
|
|
||||||
'p_armor_defence':nominalize(self.get_armor_defence(),5),
|
|
||||||
'p_armor_magic_protection':nominalize(self.get_armor_magic_protection(),5),
|
|
||||||
'e_strength':nominalize(opponent.get_strength(), 10),
|
|
||||||
'e_agility':nominalize(opponent.get_agility(), 10),
|
|
||||||
'e_wisdom':nominalize(opponent.get_wisdom(),10),
|
|
||||||
'e_health':nominalize(opponent.get_health(), 50),
|
|
||||||
'e_damage':nominalize(opponent.get_damage(),10),
|
|
||||||
'e_armor_defence':nominalize(opponent.get_armor_defence(), 5),
|
|
||||||
'e_armor_magic_protection':nominalize(opponent.get_armor_magic_protection(), 5),
|
|
||||||
'e_attack_type':opponent.get_attack_type().upper(),
|
|
||||||
'strategy':"PASS"}, index=[1])
|
|
||||||
with localconverter(robjects.default_converter + pandas2ri.converter):
|
|
||||||
r_dataframe = robjects.conversion.py2rpy(testcase)
|
|
||||||
robjects.globalenv['r_dataframe']=r_dataframe
|
|
||||||
print(r_dataframe)
|
|
||||||
result=robjects.r('predict(fights.id3, r_dataframe)')
|
|
||||||
print(result)
|
|
||||||
return result[0]
|
|
||||||
def describe_situation(self, opponent):
|
|
||||||
situation = {# 'p_strength': self.get_strength(),
|
|
||||||
# 'p_agility': self.get_agility(),
|
|
||||||
# 'p_wisdom': self.get_wisdom(),
|
|
||||||
# 'p_health': self.get_health(),
|
|
||||||
# 'p_melee_damage': self.get_melee_damage(),
|
|
||||||
# 'p_ranged_damage': self.get_ranged_damage(),
|
|
||||||
# 'p_magic_damage': self.get_magic_damage(),
|
|
||||||
# 'p_armor_defence': self.get_armor_defence(),
|
|
||||||
# 'p_armor_magic_protection': self.get_armor_magic_protection(),
|
|
||||||
'e_strength': opponent.get_strength(),
|
|
||||||
'e_agility': opponent.get_agility(),
|
|
||||||
'e_wisdom': opponent.get_wisdom(),
|
|
||||||
'e_health': opponent.get_health(),
|
|
||||||
'e_damage': opponent.get_damage(),
|
|
||||||
'e_armor_defence': opponent.get_armor_defence(),
|
|
||||||
'e_armor_magic_protection': opponent.get_armor_magic_protection(),
|
|
||||||
'e_attack_type': opponent.get_attack_type().upper()}
|
|
||||||
return situation
|
|
||||||
|
|
||||||
def melee_attack(self, opponent):
|
|
||||||
attack_value = self.strength + roll_the_dice(6)
|
|
||||||
defense_value = opponent.strength + opponent.armor.get_defence()
|
|
||||||
damage = attack_value - defense_value
|
|
||||||
if damage > 0:
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon1.get_damage())
|
|
||||||
print("damage done by the player: ", 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.get_damage() - opponent.armor.get_defence() > 0):
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon2.get_damage() - opponent.armor.get_defence())
|
|
||||||
print("damage done by the player: ", damage)
|
|
||||||
|
|
||||||
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.get_damage() - opponent.armor.get_mag_protection() > 0):
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon3.get_damage() - opponent.armor.get_mag_protection())
|
|
||||||
print("damage done by the player: ", damage)
|
|
||||||
|
|
||||||
def fight_or_flight(self, opponent, strategy):
|
|
||||||
self.combat = True
|
|
||||||
while self.combat:
|
|
||||||
if strategy=="MELEE":
|
|
||||||
self.melee_attack(opponent)
|
|
||||||
if opponent.health > 0:
|
|
||||||
opponent.default_attack(self)
|
|
||||||
if self.health <= 0:
|
|
||||||
self.combat = False
|
|
||||||
print("Player died :/")
|
|
||||||
else:
|
|
||||||
self.combat = False
|
|
||||||
self.gold = self.gold + opponent.gold
|
|
||||||
opponent.gold = 0
|
|
||||||
opponent.model.grid.remove_agent(opponent)
|
|
||||||
print("Fight won")
|
|
||||||
elif strategy=="RANGED":
|
|
||||||
self.range_attack(opponent)
|
|
||||||
if opponent.health > 0:
|
|
||||||
opponent.default_attack(self)
|
|
||||||
if self.health <= 0:
|
|
||||||
self.combat = False
|
|
||||||
print("Player died :/")
|
|
||||||
else:
|
|
||||||
self.combat = False
|
|
||||||
self.gold = self.gold + opponent.gold
|
|
||||||
opponent.gold = 0
|
|
||||||
opponent.model.grid.remove_agent(opponent)
|
|
||||||
print("Fight won")
|
|
||||||
elif strategy=='MAGIC':
|
|
||||||
self.magic_attack(opponent)
|
|
||||||
if opponent.health > 0:
|
|
||||||
opponent.default_attack(self)
|
|
||||||
if self.health <= 0:
|
|
||||||
self.combat = False
|
|
||||||
print("Player died :/")
|
|
||||||
else:
|
|
||||||
self.combat = False
|
|
||||||
self.gold = self.gold + opponent.gold
|
|
||||||
opponent.gold = 0
|
|
||||||
opponent.model.grid.remove_agent(opponent)
|
|
||||||
print("Fight won")
|
|
||||||
else:
|
|
||||||
running_speed = self.agility + roll_the_dice(6)
|
|
||||||
opponent_speed = opponent.agility + roll_the_dice(6)
|
|
||||||
if running_speed > opponent_speed:
|
|
||||||
self.combat = False
|
|
||||||
print("Player ran away")
|
|
||||||
self.step()
|
|
||||||
else:
|
|
||||||
print("Player was too slow to run away")
|
|
||||||
opponent.default_attack(self)
|
|
||||||
if self.health <= 0:
|
|
||||||
self.combat = False
|
|
||||||
print("Player died :/")
|
|
||||||
|
|
||||||
def open_chest(self, chest):
|
|
||||||
if chest.type == 1:
|
|
||||||
ch_gold = 3 * roll_the_dice(6)
|
|
||||||
self.gold = self.gold + ch_gold
|
|
||||||
print("------Chest opened. Gold inside:", ch_gold, "-----")
|
|
||||||
elif chest.type == 2:
|
|
||||||
self.weapon1 = WM9
|
|
||||||
else:
|
|
||||||
self.health = 0
|
|
||||||
# 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):
|
|
||||||
decision = self.identify_content(cellmates[0])
|
|
||||||
print("Content of chest: "+cellmates[0].address)
|
|
||||||
if (decision == 'coins') or (decision == 'weapons'):
|
|
||||||
print("I will open this chest!")
|
|
||||||
self.open_chest(cellmates[0])
|
|
||||||
print("Type of opened chest: ", cellmates[0].type)
|
|
||||||
else:
|
|
||||||
print("Probably a trap - chest skipped!")
|
|
||||||
print("Type of skipped chest: ", cellmates[0].type)
|
|
||||||
self.opened_chests += 1
|
|
||||||
self.has_goal_chest = False
|
|
||||||
cellmates[0].model.grid.remove_agent(cellmates[0])
|
|
||||||
else:
|
|
||||||
self.opponent = cellmates[0]
|
|
||||||
self.strategy=self.predict_strategy(self.opponent)
|
|
||||||
print("Current enemy stats:\n", self.describe_situation(self.opponent))
|
|
||||||
print("Strategy returned from the tree: ", self.strategy)
|
|
||||||
self.fight_or_flight(self.opponent, self.strategy)
|
|
||||||
else:
|
|
||||||
print("HP: 0 / " + str(self.maxHealth))
|
|
Binary file not shown.
@ -1,97 +0,0 @@
|
|||||||
from mesa import Model
|
|
||||||
from mesa.datacollection import DataCollector
|
|
||||||
import src.agent.ga_chromosome as ga
|
|
||||||
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
|
|
||||||
|
|
||||||
import random
|
|
||||||
|
|
||||||
# from mesa.datacollection import DataCollector
|
|
||||||
|
|
||||||
x = 10
|
|
||||||
y = 10
|
|
||||||
step_counter = 0
|
|
||||||
boxes_number = 6
|
|
||||||
creatures_number = 35
|
|
||||||
|
|
||||||
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
|
|
||||||
self.boxes_number = boxes_number
|
|
||||||
self.creatures_number = creatures_number
|
|
||||||
self.running = True
|
|
||||||
best, score = ga.genetic_algorithm(ga.fitness_function, ga.n_bits, ga.n_iter, ga.n_pop, ga.r_cross, ga.r_mut)
|
|
||||||
s=1+best.count(1)
|
|
||||||
a=1+best.count(2)
|
|
||||||
w=1+best.count(3)
|
|
||||||
print("player optimised stats:", s, a, w)
|
|
||||||
self.player = Player(1000, self, "Janusz", s, a, w, 50, 50, WM1, A1, 0, WR1, S1, self.listOfChests)
|
|
||||||
print('Player stats:',self.player.strength, self.player.agility, self.player.wisdom)
|
|
||||||
self.schedule.add(self.player)
|
|
||||||
x = self.random.randrange(self.grid.width)
|
|
||||||
y = self.random.randrange(self.grid.height)
|
|
||||||
self.grid.place_agent(self.player, (x, y))
|
|
||||||
for i in range(self.boxes_number):
|
|
||||||
r_type = random.randrange(1, 4)
|
|
||||||
box = Box(i, self, r_type)
|
|
||||||
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-20): # taki range, żeby każdy agent miał poprawne unique_id
|
|
||||||
# creature = Creature(i, self)
|
|
||||||
creature = Creature(i, self, "Goblin",
|
|
||||||
roll_the_dice(3), roll_the_dice(3), roll_the_dice(3), 15, roll_the_dice(3),
|
|
||||||
WM2, A2, roll_the_dice(5))
|
|
||||||
|
|
||||||
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
|
|
||||||
for i in range(self.boxes_number + self.creatures_number-20, self.creatures_number): # taki range, żeby każdy agent miał poprawne unique_id
|
|
||||||
creature = Creature(i, self, "Skeleton",
|
|
||||||
roll_the_dice(7), roll_the_dice(7), roll_the_dice(7), 15, roll_the_dice(7),
|
|
||||||
WR4, A8, roll_the_dice(10))
|
|
||||||
|
|
||||||
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(model_reporters={"HP":self.player.health, "Gold":self.player.gold, "Position (x, y)":self.player.pos}) #informacje o stanie planszy, pozycja agenta
|
|
||||||
#other data: position, strength & other parameters
|
|
||||||
def get_list_of_chests(self):
|
|
||||||
return self.listOfChests
|
|
||||||
|
|
||||||
def get_hp(self):
|
|
||||||
return self.player.health
|
|
||||||
def get_gold(self):
|
|
||||||
return self.player.gold
|
|
||||||
def get_position(self):
|
|
||||||
return str(self.player.pos)+str(self.player.direction.name)
|
|
||||||
|
|
||||||
def step(self):
|
|
||||||
self.schedule.step()
|
|
||||||
#self.datacollector.collect(self)
|
|
||||||
#print(str(self.datacollector.model_reporters))
|
|
@ -1,6 +0,0 @@
|
|||||||
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.
@ -1,21 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
from mesa import Agent
|
|
||||||
import random
|
|
||||||
#from .dice.dice import roll_the_dice
|
|
||||||
|
|
||||||
golds = [("https://drive.google.com/uc?export=download&id=1fWeew0jXZ1lZBmv6CG5viLGloJAex6ao",'moneta'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1UrXbbfJhfCuDZSnxund7sVk40QMS3R2Q", 'moneta2'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1qH0OP4X1NQqpHtUkwD8SryJtKCKcZzVe", 'moneta3'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1b9tZf639mEWgiWq_EYyqjeKYPEMi7dX9", 'moneta4'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1z9jt-j3aS1fRUgVA_t1zR7TS5QzuXW5b", 'moneta5')]
|
|
||||||
weapons = [("https://drive.google.com/uc?export=download&id=1TA-ObC33FaiHmgQ6i71Kcb32VrHsKUd1", 'miecz'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1oyv15FSPJ84xx1tQLJW8Wlbb1JUx2xCy", 'miecz2'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1Ha0eeLRLcidrMAN1P59V9zB8uSQq3GM5", 'miecz3'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1GetUWnglUtqWqcK4sd5HsdVuaUpU5Ec_", 'miecz4'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1RImo84OykYICvwfLycDEb5tr4tPbGVy1", 'miecz5')]
|
|
||||||
traps = [("https://drive.google.com/uc?export=download&id=1G-AxY712V-eT2ylW0VXn4o2V_4pvy7lz", 'kwiat'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1i7MwzJRPBZ-KrCDqhT5RCXLstLlWCsx9", 'kwiat2'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1zF7wQuG1gtQ796m6TM08FOUOVK8s_qhT", 'kwiat3'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1qwrIThsoKg44b57JXvbXe--TIplacd-i", 'kwiat4'),
|
|
||||||
("https://drive.google.com/uc?export=download&id=1YsqdQaLyD8Es4w09p4Zdw2CufNkl_avN", 'kwiat5')]
|
|
||||||
|
|
||||||
class Box(Agent):
|
|
||||||
def __init__(self, unique_id, model, type):
|
|
||||||
super().__init__(unique_id, model)
|
|
||||||
#self.gold = 3 * roll_the_dice(6)
|
|
||||||
self.isBox = True
|
|
||||||
self.isCreature = False
|
|
||||||
self.isPlayer = False
|
|
||||||
self.type = type
|
|
||||||
r_img = random.randrange(0,4)
|
|
||||||
if type == 1:
|
|
||||||
self.address = golds[r_img][0]
|
|
||||||
self.file_name = golds[r_img][1]
|
|
||||||
elif type == 2:
|
|
||||||
self.address = weapons[r_img][0]
|
|
||||||
self.file_name = weapons[r_img][1]
|
|
||||||
else:
|
|
||||||
self.address = traps[r_img][0]
|
|
||||||
self.file_name = traps[r_img][1]
|
|
||||||
|
|
||||||
def step(self):
|
|
||||||
pass
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
|||||||
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
|
|
||||||
self.isPlayer = False
|
|
||||||
|
|
||||||
def get_strength(self):
|
|
||||||
return self.strength
|
|
||||||
|
|
||||||
def get_agility(self):
|
|
||||||
return self.agility
|
|
||||||
|
|
||||||
def get_wisdom(self):
|
|
||||||
return self.wisdom
|
|
||||||
|
|
||||||
def get_health(self):
|
|
||||||
return self.health
|
|
||||||
|
|
||||||
def get_damage(self):
|
|
||||||
return self.weapon1.get_damage()
|
|
||||||
|
|
||||||
def get_melee_damage(self):
|
|
||||||
return self.weapon1.get_damage()
|
|
||||||
|
|
||||||
def get_ranged_damage(self):
|
|
||||||
return self.weapon2.get_damage()
|
|
||||||
|
|
||||||
def get_magic_damage(self):
|
|
||||||
return self.weapon3.get_damage()
|
|
||||||
|
|
||||||
def get_armor_defence(self):
|
|
||||||
return self.armor.get_defence()
|
|
||||||
|
|
||||||
def get_armor_magic_protection(self):
|
|
||||||
return self.armor.get_mag_protection()
|
|
||||||
|
|
||||||
def get_attack_type(self):
|
|
||||||
return self.weapon1.get_type()
|
|
||||||
def melee_attack(self, opponent):
|
|
||||||
attack_value = self.strength + roll_the_dice(6)
|
|
||||||
defense_value = opponent.strength + opponent.armor.get_defence()
|
|
||||||
damage = attack_value - defense_value
|
|
||||||
if damage > 0:
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon1.get_damage())
|
|
||||||
print("damage done by the monster: ", 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.get_damage() - opponent.armor.get_defence() > 0):
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon1.get_damage() - opponent.armor.get_defence())
|
|
||||||
print("damage done by the monster: ", damage)
|
|
||||||
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.get_damage() - opponent.armor.get_mag_protection() > 0):
|
|
||||||
opponent.health = opponent.health - (damage + self.weapon1.get_damage() - opponent.armor.get_mag_protection())
|
|
||||||
print("damage done by the monster: ", damage)
|
|
||||||
def default_attack(self, opponent):
|
|
||||||
if self.weapon1.get_type() == "Meele":
|
|
||||||
self.melee_attack(opponent)
|
|
||||||
elif self.weapon1.get_type() == "Ranged":
|
|
||||||
self.range_attack(opponent)
|
|
||||||
else:
|
|
||||||
self.magic_attack(opponent)
|
|
Binary file not shown.
@ -1,4 +0,0 @@
|
|||||||
import random
|
|
||||||
|
|
||||||
def roll_the_dice(number):
|
|
||||||
return random.randint(1, number)
|
|
@ -1,9 +0,0 @@
|
|||||||
from mesa import Agent
|
|
||||||
|
|
||||||
|
|
||||||
class Wall(Agent):
|
|
||||||
def __init__(self, unique_id, model):
|
|
||||||
super().__init__(unique_id, model)
|
|
||||||
|
|
||||||
def step(self):
|
|
||||||
pass
|
|
@ -1,14 +0,0 @@
|
|||||||
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
|
|
@ -1,20 +0,0 @@
|
|||||||
import rpy2.robjects as robjects
|
|
||||||
from rpy2.robjects.packages import importr
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
def create_model():
|
|
||||||
RWeka = importr('RWeka')
|
|
||||||
robjects.r('WPM("refresh-cache")')
|
|
||||||
robjects.r('WPM("install-package", "simpleEducationalLearningSchemes")')
|
|
||||||
robjects.r('WPM("load-package", "simpleEducationalLearningSchemes")')
|
|
||||||
robjects.r('ID3<-make_Weka_classifier("weka/classifiers/trees/Id3")')
|
|
||||||
robjects.r('fights<-read.arff("C:/Users/X260/Downloads/currentdata.arff")')
|
|
||||||
robjects.r('fights.id3 <- ID3(strategy ~ p_strength + p_agility + p_wisdom+ p_health + '
|
|
||||||
'p_melee_damage + p_ranged_damage + p_magic_damage + p_armor_defence + p_armor_magic_protection + '
|
|
||||||
'e_strength+ e_agility + e_wisdom + e_health + e_damage + e_armor_defence + e_armor_magic_protection + '
|
|
||||||
'e_attack_type, data = fights)')
|
|
||||||
# robjects.r('.jcache(fights.id3)')
|
|
||||||
#robjects.r('save(fights.id3, file="tree.rda)')
|
|
||||||
# with open('tree.rda','wb') as f:
|
|
||||||
# pickle.dump(robjects.r('fights.id3'), f)
|
|
||||||
#todo: zapisać w rpythonie do pliku, raz zrobić i nie odpalać za każdym razem w serverze
|
|
Binary file not shown.
@ -1,5 +0,0 @@
|
|||||||
actions = {
|
|
||||||
"rotate_left": -1,
|
|
||||||
"move_forward": 0,
|
|
||||||
"rotate_right": 1
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
from src.direction import Direction
|
|
||||||
|
|
||||||
directions = {
|
|
||||||
Direction.N: [0, 1],
|
|
||||||
Direction.E: [1, 0],
|
|
||||||
Direction.S: [0, -1],
|
|
||||||
Direction.W: [-1, 0]
|
|
||||||
}
|
|
Binary file not shown.
@ -1,9 +0,0 @@
|
|||||||
def nominalize(val, max_val):
|
|
||||||
return_value = "NONE"
|
|
||||||
if val > 0.66 * max_val:
|
|
||||||
return_value = "HIGH"
|
|
||||||
elif val > 0.33 * max_val:
|
|
||||||
return_value = "MEDIUM"
|
|
||||||
elif val > 0:
|
|
||||||
return_value = "LOW"
|
|
||||||
return return_value
|
|
Binary file not shown.
@ -1,3 +0,0 @@
|
|||||||
from .bfs import BFS
|
|
||||||
from .actionsInterpreter import ActionInterpreter
|
|
||||||
from .heuristic import *
|
|
Binary file not shown.
Binary file not shown.
@ -1,40 +0,0 @@
|
|||||||
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
|
|
@ -1,140 +0,0 @@
|
|||||||
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 = 0
|
|
||||||
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 +0,0 @@
|
|||||||
from .manhattan import manhattan
|
|
@ -1,4 +0,0 @@
|
|||||||
# 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())
|
|
192
tree_data_gen.py
192
tree_data_gen.py
@ -1,192 +0,0 @@
|
|||||||
import random
|
|
||||||
from os import urandom
|
|
||||||
import statistics
|
|
||||||
import csv
|
|
||||||
|
|
||||||
|
|
||||||
def nominalizeOld(val, max_val):
|
|
||||||
return_value = "NONE"
|
|
||||||
if val > 0.8 * max_val:
|
|
||||||
return_value = "VERY_HIGH"
|
|
||||||
elif val > 0.6 * max_val:
|
|
||||||
return_value = "HIGH"
|
|
||||||
elif val > 0.4 * max_val:
|
|
||||||
return_value = "MEDIUM"
|
|
||||||
elif val > 0.2 * max_val:
|
|
||||||
return_value = "LOW"
|
|
||||||
elif val > 0:
|
|
||||||
return_value = "VERY_LOW"
|
|
||||||
return return_value
|
|
||||||
|
|
||||||
def nominalize(val, max_val):
|
|
||||||
return_value = "NONE"
|
|
||||||
if val > 0.66 * max_val:
|
|
||||||
return_value = "HIGH"
|
|
||||||
elif val > 0.33 * max_val:
|
|
||||||
return_value = "MEDIUM"
|
|
||||||
elif val > 0:
|
|
||||||
return_value = "LOW"
|
|
||||||
return return_value
|
|
||||||
|
|
||||||
|
|
||||||
class Stats:
|
|
||||||
def __init__(self):
|
|
||||||
self.strength = random.randint(1, 10)
|
|
||||||
self.agility = random.randint(1, 10)
|
|
||||||
self.wisdom = random.randint(1, 10)
|
|
||||||
self.health = random.randint(1, 50)
|
|
||||||
self.melee_wep_damage = random.randint(1, 10)
|
|
||||||
self.ranged_wep_damage = random.randint(1, 10)
|
|
||||||
self.magic_wep_damage = random.randint(1, 10)
|
|
||||||
self.armor_defence = random.randint(0, 5)
|
|
||||||
self.armor_magic_protection = random.randint(0, 5)
|
|
||||||
|
|
||||||
self.damage = 0
|
|
||||||
|
|
||||||
|
|
||||||
def meleeAttack(self, opponent):
|
|
||||||
attackValue = self.strength + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.strength + opponent.armor_defence
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if damage > 0:
|
|
||||||
opponent.damage += (damage + self.melee_wep_damage)
|
|
||||||
|
|
||||||
def rangeAttack(self, opponent):
|
|
||||||
attackValue = self.agility + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.agility
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if (damage > 0) and (damage + self.ranged_wep_damage - opponent.armor_defence > 0):
|
|
||||||
opponent.damage += (damage + self.ranged_wep_damage - opponent.armor_defence)
|
|
||||||
|
|
||||||
def magicAttack(self, opponent):
|
|
||||||
attackValue = self.wisdom + random.randint(1, 6)
|
|
||||||
defenseValue = opponent.wisdom
|
|
||||||
damage = attackValue - defenseValue
|
|
||||||
if (damage > 0) and (damage + self.magic_wep_damage - opponent.armor_magic_protection > 0):
|
|
||||||
opponent.damage += (damage + self.magic_wep_damage - opponent.armor_magic_protection)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self.damage = 0
|
|
||||||
|
|
||||||
|
|
||||||
FIELDNAMES = ["p_strength",
|
|
||||||
"p_agility",
|
|
||||||
"p_wisdom",
|
|
||||||
"p_health",
|
|
||||||
"p_melee_damage",
|
|
||||||
"p_ranged_damage",
|
|
||||||
"p_magic_damage",
|
|
||||||
"p_armor_defence",
|
|
||||||
"p_armor_magic_protection",
|
|
||||||
"e_strength",
|
|
||||||
"e_agility",
|
|
||||||
"e_wisdom",
|
|
||||||
"e_health",
|
|
||||||
"e_damage",
|
|
||||||
"e_armor_defence",
|
|
||||||
"e_armor_magic_protection",
|
|
||||||
"e_attack_type",
|
|
||||||
"strategy"]
|
|
||||||
RESULT_FILE = open('data.csv', 'w', newline='')
|
|
||||||
FILE_WRITER = csv.writer(RESULT_FILE, dialect='excel', delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
|
|
||||||
FILE_WRITER.writerow(FIELDNAMES)
|
|
||||||
|
|
||||||
|
|
||||||
SETUP_RESULTS = [[], [], []]
|
|
||||||
|
|
||||||
MAX_COMBAT_TIME = 20
|
|
||||||
|
|
||||||
def try_combat(my_seed, p, e, player_att_type, enemy_att_type):
|
|
||||||
random.seed(my_seed)
|
|
||||||
current_iteration = 0
|
|
||||||
while True:
|
|
||||||
if player_att_type == 0:
|
|
||||||
p.meleeAttack(e)
|
|
||||||
elif player_att_type == 1:
|
|
||||||
p.rangeAttack(e)
|
|
||||||
else:
|
|
||||||
p.magicAttack(e)
|
|
||||||
|
|
||||||
if e.damage >= e.health:
|
|
||||||
SETUP_RESULTS[player_att_type].append(p.health - p.damage)
|
|
||||||
break
|
|
||||||
|
|
||||||
if enemy_att_type == 0:
|
|
||||||
e.meleeAttack(p)
|
|
||||||
elif enemy_att_type == 1:
|
|
||||||
e.rangeAttack(p)
|
|
||||||
else:
|
|
||||||
e.magicAttack(p)
|
|
||||||
|
|
||||||
if p.damage >= p.health:
|
|
||||||
SETUP_RESULTS[player_att_type].append(0)
|
|
||||||
break
|
|
||||||
|
|
||||||
current_iteration += 1
|
|
||||||
if current_iteration >= MAX_COMBAT_TIME:
|
|
||||||
SETUP_RESULTS[player_att_type].append(0)
|
|
||||||
break
|
|
||||||
|
|
||||||
p.reset()
|
|
||||||
e.reset()
|
|
||||||
|
|
||||||
for trial in range(10000):
|
|
||||||
stat_seed = urandom(16)
|
|
||||||
random.seed(stat_seed)
|
|
||||||
|
|
||||||
player = Stats()
|
|
||||||
enemy = Stats()
|
|
||||||
enemy_attack_type = random.randint(0, 2) # Enemy weapon choice
|
|
||||||
|
|
||||||
for i in range(30):
|
|
||||||
combat_seed = urandom(16)
|
|
||||||
try_combat(combat_seed, player, enemy, 0, enemy_attack_type)
|
|
||||||
try_combat(combat_seed, player, enemy, 1, enemy_attack_type)
|
|
||||||
try_combat(combat_seed, player, enemy, 2, enemy_attack_type)
|
|
||||||
|
|
||||||
for i, series in enumerate(SETUP_RESULTS):
|
|
||||||
SETUP_RESULTS[i] = statistics.mean(series)
|
|
||||||
|
|
||||||
strategy = "PASS"
|
|
||||||
if any(SETUP_RESULTS):
|
|
||||||
max_index = SETUP_RESULTS.index(max(SETUP_RESULTS))
|
|
||||||
if max_index == 0:
|
|
||||||
strategy = "MELEE"
|
|
||||||
elif max_index == 1:
|
|
||||||
strategy = "RANGED"
|
|
||||||
elif max_index == 2:
|
|
||||||
strategy = "MAGIC"
|
|
||||||
|
|
||||||
enemy_damage = 0
|
|
||||||
if enemy_attack_type == 0:
|
|
||||||
enemy_attack_type = "MELEE"
|
|
||||||
enemy_damage = enemy.melee_wep_damage
|
|
||||||
elif enemy_attack_type == 1:
|
|
||||||
enemy_attack_type = "RANGED"
|
|
||||||
enemy_damage = enemy.ranged_wep_damage
|
|
||||||
elif enemy_attack_type == 2:
|
|
||||||
enemy_attack_type = "MAGIC"
|
|
||||||
enemy_damage = enemy.magic_wep_damage
|
|
||||||
|
|
||||||
FILE_WRITER.writerow([nominalize(player.strength, 10),
|
|
||||||
nominalize(player.agility, 10),
|
|
||||||
nominalize(player.wisdom, 10),
|
|
||||||
nominalize(player.health, 50),
|
|
||||||
nominalize(player.melee_wep_damage, 10),
|
|
||||||
nominalize(player.ranged_wep_damage, 10),
|
|
||||||
nominalize(player.magic_wep_damage, 10),
|
|
||||||
nominalize(player.armor_defence, 5),
|
|
||||||
nominalize(player.armor_magic_protection, 5),
|
|
||||||
nominalize(enemy.strength, 10),
|
|
||||||
nominalize(enemy.agility, 10),
|
|
||||||
nominalize(enemy.wisdom, 10),
|
|
||||||
nominalize(enemy.health, 50),
|
|
||||||
nominalize(enemy_damage, 10),
|
|
||||||
nominalize(enemy.armor_defence, 5),
|
|
||||||
nominalize(enemy.armor_magic_protection, 5),
|
|
||||||
enemy_attack_type,
|
|
||||||
strategy])
|
|
||||||
SETUP_RESULTS = [[], [], []]
|
|
||||||
if trial%100 == 0:
|
|
||||||
print("Trials done: " + str(trial))
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user