Compare commits
12 Commits
grzgap-fea
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
1494a717f6 | ||
|
daecac46b7 | ||
|
06fa35aa0f | ||
|
5b89648f69 | ||
fe3f9bf4fe | |||
|
63c9ebaf0d | ||
|
3af4d0e68f | ||
|
de2e2b7e00 | ||
26927b6a1d | |||
|
00356fde40 | ||
|
d5b132290c | ||
|
42aec48676 |
47
actions.py
47
actions.py
@ -1,47 +0,0 @@
|
||||
# Funkcja konwertujaca wspolrzedne nastepnego pola do odwiedzenia
|
||||
|
||||
# pole to element wziety z kolejki path
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
|
||||
def actionsInterpreter(actionIndex, defaultState, directions):
|
||||
|
||||
if actionIndex == -1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().counterClockwise()
|
||||
)
|
||||
elif actionIndex == 0:
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if defaultState.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif defaultState.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif defaultState.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif defaultState.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
return AgentState(
|
||||
defaultState.get_x() + move_x, # directions[defaultState.get_direction()[0]], - is not subscriptable ???
|
||||
defaultState.get_y() + move_y, # directions[defaultState.get_direction()][1], - is not subscriptable ???
|
||||
defaultState.get_direction()
|
||||
)
|
||||
elif actionIndex == 1:
|
||||
return AgentState(
|
||||
defaultState.get_x(),
|
||||
defaultState.get_y(),
|
||||
defaultState.get_direction().clockwise()
|
||||
)
|
||||
else:
|
||||
return defaultState
|
||||
|
||||
|
||||
actions = {
|
||||
"rotateLeft": -1,
|
||||
"moveForward": 0,
|
||||
"rotateRight": 1
|
||||
}
|
1000
data_dd2.csv
Normal file
1000
data_dd2.csv
Normal file
File diff suppressed because it is too large
Load Diff
5000
data_dd3.csv
Normal file
5000
data_dd3.csv
Normal file
File diff suppressed because it is too large
Load Diff
160
dt.py
Normal file
160
dt.py
Normal file
@ -0,0 +1,160 @@
|
||||
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
325
hero.py
@ -1,325 +0,0 @@
|
||||
import random
|
||||
import heapq
|
||||
|
||||
from mesa import Agent
|
||||
|
||||
from othercharacters import dice, Box, Creature, Armor, Weapon
|
||||
from actions import actions, actionsInterpreter
|
||||
from state import AgentState
|
||||
from direction import Direction
|
||||
from node import Node
|
||||
|
||||
|
||||
class Player(Creature):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3, listOfChests):
|
||||
super().__init__(unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
self.agility = a
|
||||
self.wisdom = w
|
||||
self.maxHealth = maxhp
|
||||
self.health = hp
|
||||
self.gold = g
|
||||
self.weapon1 = weap
|
||||
self.weapon2 = w2
|
||||
self.weapon3 = w3
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = False
|
||||
self.directions = {
|
||||
Direction.N : [0, 1],
|
||||
Direction.E : [1, 0],
|
||||
Direction.S : [0, -1],
|
||||
Direction.W : [-1, 0]
|
||||
}
|
||||
self.direction = Direction.N
|
||||
self.queue = []
|
||||
self.hasgoalchest = False
|
||||
self.openedchests = 0
|
||||
self.__listOfChests = listOfChests
|
||||
self.__actionsCollection = []
|
||||
|
||||
def meleeAttack(self, opponent):
|
||||
attackValue = self.strength + dice(6)
|
||||
defenseValue = opponent.strength + opponent.armor.defence
|
||||
damage = attackValue - defenseValue
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def rangeAttack(self, opponent):
|
||||
attackValue = self.agility + dice(6)
|
||||
defenseValue = opponent.agility
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon2.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon2.damage - opponent.armor.defence)
|
||||
|
||||
def magicAttack(self, opponent):
|
||||
attackValue = self.wisdom + dice(6)
|
||||
defenseValue = opponent.wisdom
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon3.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon3.damage - opponent.armor.mag_protection)
|
||||
|
||||
def fightOrFlight(self, opponent):
|
||||
combat = True
|
||||
while combat:
|
||||
choice = dice(4)
|
||||
print("dice rolled:", choice)
|
||||
if choice == 1:
|
||||
running_speed = self.agility + dice(6)
|
||||
opponent_speed = opponent.agility + dice(6)
|
||||
if running_speed > opponent_speed:
|
||||
combat = False
|
||||
print("Player ran away")
|
||||
self.step()
|
||||
else:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
elif choice == 2:
|
||||
self.meleeAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
elif choice == 3:
|
||||
self.rangeAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
else:
|
||||
self.magicAttack(opponent)
|
||||
if opponent.health > 0:
|
||||
opponent.defaultAttack(self)
|
||||
if self.health <= 0:
|
||||
combat = False
|
||||
print("Player died :/")
|
||||
else:
|
||||
combat = False
|
||||
self.gold = self.gold + opponent.gold
|
||||
opponent.gold = 0
|
||||
opponent.model.grid.remove_agent(opponent)
|
||||
print("Fight won")
|
||||
|
||||
def openChest(self, chest):
|
||||
self.gold = self.gold + chest.gold
|
||||
print("------Chest opened. Gold inside:", chest.gold,"-----")
|
||||
chest.gold = 0
|
||||
self.openedchests += 1
|
||||
self.hasgoalchest = False
|
||||
chest.model.grid.remove_agent(chest)
|
||||
#self.direction = 0 # po osiągnięciu jednego celu 'restartuje sie' na szukanie ścieżki do kolejnego -- NIE ZEROWAĆ OBROTU - to psuje goldState w bfs!!!
|
||||
# if isinstance(chest.loot,Armor):
|
||||
# buffer = self.armor
|
||||
# self.armor = chest.loot
|
||||
# chest.loot = buffer
|
||||
# if isinstance(chest.loot,Weapon):
|
||||
# if chest.loot.type == "Melee":
|
||||
# buffer = self.weapon1
|
||||
# self.weapon1 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.type == "Range":
|
||||
# buffer = self.weapon2
|
||||
# self.weapon2 = chest.loot
|
||||
# chest.loot = buffer
|
||||
# elif chest.loot.type == "Magic":
|
||||
# buffer = self.weapon3
|
||||
# self.weapon3 = chest.loot
|
||||
# chest.loot = buffer
|
||||
|
||||
#- - - - bfs & successor - - - -#
|
||||
def successor(self, append):
|
||||
|
||||
rotateLeft = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().counterClockwise()
|
||||
)
|
||||
|
||||
rotateRight = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().clockwise()
|
||||
)
|
||||
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if append.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif append.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif append.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif append.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
if append.get_x() + move_x >= 0 and append.get_x() + move_x < 10 and append.get_y() + move_y >=0 and append.get_y() + move_y < 10:
|
||||
moveForward = AgentState(
|
||||
append.get_x() + move_x,
|
||||
append.get_y() + move_y,
|
||||
append.get_direction()
|
||||
)
|
||||
else:
|
||||
moveForward = None
|
||||
|
||||
return [
|
||||
[actions["rotateLeft"], rotateLeft],
|
||||
[actions["moveForward"], moveForward],
|
||||
[actions["rotateRight"], rotateRight]
|
||||
]
|
||||
|
||||
def heuristics(self, state, target_state):
|
||||
# cost is initially step distance in manhattan metric
|
||||
return abs(state.get_x() - target_state.get_x()) + abs(state.get_y() - target_state.get_y())
|
||||
|
||||
def graphsearch(self, fringe, explored, istate, succesorFunction, goalState):
|
||||
finalActionList = []
|
||||
init_state = [None, istate]
|
||||
root = Node(None, init_state, 0)
|
||||
heapq.heappush(fringe, (0, root)) # at beginning do nothing
|
||||
|
||||
while len(fringe) != 0:
|
||||
_flag = True
|
||||
|
||||
if len(fringe) == 0:
|
||||
return False
|
||||
|
||||
tmpNode = (heapq.heappop(fringe))[1] # node
|
||||
|
||||
# build dictionary
|
||||
# parent = tmpNode.get_predecessor() # fetch parent state
|
||||
# tmpNode.set_predecessor(None) # clear predecessor - don't build a tree chain
|
||||
# if parent is None:
|
||||
# finalActionList.append([parent, tmpNode])
|
||||
# else:
|
||||
# finalActionList.append(
|
||||
# [parent[1], tmpNode]) # pair(key, value) - key: parent state, value: current state + action
|
||||
|
||||
if tmpNode._state.get_x() == goalState.get_x() and tmpNode._state.get_y() == goalState.get_y():
|
||||
while tmpNode._parent is not None:
|
||||
finalActionList.append(tmpNode._action)
|
||||
tmpNode = tmpNode._parent
|
||||
finalActionList = list(reversed(finalActionList))
|
||||
return finalActionList # TODO change step!
|
||||
|
||||
explored.append(tmpNode)
|
||||
|
||||
tmpList = succesorFunction(tmpNode._state)
|
||||
for newState in tmpList:
|
||||
_flag = True
|
||||
_flagFringe = True
|
||||
_flagExplored = True
|
||||
|
||||
if newState[1] is None:
|
||||
continue
|
||||
|
||||
# calculating priority
|
||||
monster = 0
|
||||
if any([thing.isCreature for thing in self.model.grid.get_cell_list_contents([(newState[1].get_x(), newState[1].get_y())])]):
|
||||
if newState[0] == 0:
|
||||
monster = 10
|
||||
p = self.heuristics(newState[1], goalState) + tmpNode._cost + monster + 1
|
||||
|
||||
r = 0
|
||||
counter = 0
|
||||
pos = 0
|
||||
for fringeNode in fringe:
|
||||
if fringeNode[1]._state.get_x() == newState[1].get_x() and fringeNode[1]._state.get_y() == newState[1].get_y() and fringeNode[1]._state.get_direction() == newState[1].get_direction():
|
||||
_flagFringe = False
|
||||
_flag = False
|
||||
r = fringeNode[0]
|
||||
pos = counter
|
||||
counter = counter + 1
|
||||
|
||||
for exploredNode in explored:
|
||||
if exploredNode._state.get_x() == newState[1].get_x() and exploredNode._state.get_y() == newState[1].get_y() and exploredNode._state.get_direction() == newState[1].get_direction():
|
||||
_flagExplored = False
|
||||
_flag = False
|
||||
|
||||
# if _flag:
|
||||
# newState[1].set_predecessor(tmpNode)
|
||||
|
||||
if _flagFringe and _flagExplored:
|
||||
newNode = Node(tmpNode, newState, tmpNode._cost + 1 + monster)
|
||||
heapq.heappush(fringe, (p, newNode))
|
||||
elif not _flagFringe and (p < r):
|
||||
newNode = Node(tmpNode, newState, tmpNode._cost + 1 + monster)
|
||||
fringe[pos][0] = p
|
||||
fringe[pos][1] = newNode
|
||||
|
||||
return None
|
||||
|
||||
def step(self):
|
||||
if self.health > 0:
|
||||
print("position: ", self.pos)
|
||||
# print("direction: ", self.direction)
|
||||
if not self.hasgoalchest: # jeśli nie ma wyznaczonej skrzynki do której idzie to robi bfs żeby ją wyznaczyć
|
||||
# self.path=self.findShortestPathToTarget()
|
||||
if len(self.__listOfChests) != 0:
|
||||
# select and remove element from list
|
||||
randomChest = random.choice(self.__listOfChests)
|
||||
self.__listOfChests.remove(randomChest)
|
||||
self.hasgoalchest = True
|
||||
|
||||
currentState = AgentState(self.pos[0], self.pos[1], self.direction)
|
||||
|
||||
goalState = AgentState(randomChest[1][0], randomChest[1][1], self.direction)
|
||||
# find way to goal state
|
||||
self.__actionsCollection = self.graphsearch([],
|
||||
[],
|
||||
currentState,
|
||||
self.successor,
|
||||
goalState)
|
||||
|
||||
if self.__actionsCollection is None:
|
||||
raise Exception("CRITICAL ERROR - Algorithm error - Path doesn't exist!!! ://")
|
||||
|
||||
else:
|
||||
self.__actionsCollection = [action for action in self.__actionsCollection if action is not None] # remove first None action
|
||||
else:
|
||||
raise Exception("WIN!!! :D")
|
||||
|
||||
elif len(self.__actionsCollection) == 0: # jeśli jest wyznaczona skrzynka - cel & nie ma akcji do wykonania - cel osiągnięty
|
||||
self.hasgoalchest = False
|
||||
|
||||
elif len(self.__actionsCollection) != 0: # jeśli jest wyznaczona skrzynka - cel & są akcje do wykoannia to je realizuje
|
||||
|
||||
actionIndex = self.__actionsCollection[0] # ignore -1 because it's None
|
||||
self.__actionsCollection.remove(actionIndex)
|
||||
|
||||
newState = actionsInterpreter(actionIndex, AgentState(self.pos[0], self.pos[1], self.direction), self.directions)
|
||||
|
||||
self.model.grid.move_agent(self, (newState.get_x(), newState.get_y()))
|
||||
self.direction = newState.get_direction()
|
||||
|
||||
print("moved to - ", [newState.get_x(), newState.get_y()])
|
||||
|
||||
cellmates = self.model.grid.get_cell_list_contents([self.pos])
|
||||
if len(cellmates) > 1:
|
||||
if isinstance(cellmates[0], Box):
|
||||
self.openChest(cellmates[0])
|
||||
else:
|
||||
opponent = cellmates[0]
|
||||
print("Fighting")
|
||||
self.fightOrFlight(opponent)
|
||||
# print("HP: " + str(self.health) + " / " + str(self.maxHealth))
|
||||
print("Gold: " + str(self.gold))
|
||||
else:
|
||||
print("HP: 0 / " + str(self.maxHealth))
|
65
model.py
65
model.py
@ -1,65 +0,0 @@
|
||||
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
Normal file
BIN
nn_model.h5
Normal file
Binary file not shown.
@ -1,86 +0,0 @@
|
||||
from mesa import Agent
|
||||
import random
|
||||
|
||||
|
||||
def dice(number):
|
||||
return random.randint(1, number)
|
||||
|
||||
|
||||
|
||||
class Wall(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
|
||||
def step(self):
|
||||
pass
|
||||
|
||||
|
||||
class Box(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
self.gold = 3 * dice(6)
|
||||
self.isBox = True
|
||||
self.isCreature = False
|
||||
|
||||
def step(self):
|
||||
pass
|
||||
|
||||
|
||||
class Weapon():
|
||||
def __init__(self, name, type, damage):
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.damage = damage
|
||||
|
||||
|
||||
class Armor():
|
||||
def __init__(self, name, defence, mp):
|
||||
self.name = name
|
||||
self.defence = defence
|
||||
self.mag_protection = mp
|
||||
|
||||
|
||||
class Creature(Agent):
|
||||
def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g):
|
||||
super().__init__(unique_id, model)
|
||||
self.name = n
|
||||
self.strength = s
|
||||
self.agility = a
|
||||
self.wisdom = w
|
||||
self.maxHealth = maxhp
|
||||
self.health = hp
|
||||
self.gold = g
|
||||
self.weapon1 = weap
|
||||
self.armor = arm
|
||||
self.isBox = False
|
||||
self.isCreature = True
|
||||
|
||||
def meleeAttack(self, opponent):
|
||||
attackValue = self.strength + dice(6)
|
||||
defenseValue = opponent.strength + opponent.armor.defence
|
||||
damage = attackValue - defenseValue
|
||||
if damage > 0:
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage)
|
||||
|
||||
def rangeAttack(self, opponent):
|
||||
attackValue = self.agility + dice(6)
|
||||
defenseValue = opponent.agility
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.defence > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.defence)
|
||||
|
||||
def magicAttack(self, opponent):
|
||||
attackValue = self.wisdom + dice(6)
|
||||
defenseValue = opponent.wisdom
|
||||
damage = attackValue - defenseValue
|
||||
if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.mag_protection > 0):
|
||||
opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.mag_protection)
|
||||
|
||||
def defaultAttack(self, opponent):
|
||||
if self.weapon1.type == "Meele":
|
||||
self.meleeAttack(opponent)
|
||||
elif self.weapon1.type == "Range":
|
||||
self.rangeAttack(opponent)
|
||||
else:
|
||||
self.magicAttack(opponent)
|
||||
|
60
server.py
60
server.py
@ -1,22 +1,64 @@
|
||||
from model import GameMap
|
||||
from src.agent.map.gameMap import GameMap
|
||||
from mesa.visualization.modules import CanvasGrid
|
||||
from mesa.visualization.modules.TextVisualization import TextElement
|
||||
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):
|
||||
portrayal = {"Shape": "sprites/hero.png",
|
||||
portrayal = {"Shape": "sprites/heroE.png",
|
||||
"Layer": 1}
|
||||
if agent.isBox:
|
||||
if agent.isPlayer and agent.direction==Direction.N:
|
||||
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["Layer"] = 0
|
||||
elif agent.isCreature:
|
||||
portrayal["Shape"]='sprites/goblin.png'
|
||||
if agent.name=='Goblin':
|
||||
portrayal["Shape"] = 'sprites/goblin.png'
|
||||
elif agent.name=='Skeleton':
|
||||
portrayal["Shape"] = 'sprites/skeletonArcher.png'
|
||||
return portrayal
|
||||
|
||||
grid = CanvasGrid(player_representation, 10, 10, 500, 500)
|
||||
def chest_content(agent):
|
||||
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,
|
||||
[grid],
|
||||
[grid,Stats()],
|
||||
"Map",
|
||||
{"x":10, "y":10})
|
||||
{"x": 10, "y": 10})
|
||||
server.port = 8081
|
||||
server.launch()
|
||||
server.launch()
|
||||
|
Before Width: | Height: | Size: 208 B After Width: | Height: | Size: 208 B |
BIN
sprites/heroN.png
Normal file
BIN
sprites/heroN.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 292 B |
BIN
sprites/heroS.png
Normal file
BIN
sprites/heroS.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 B |
BIN
sprites/heroW.png
Normal file
BIN
sprites/heroW.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 293 B |
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
BIN
src/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
src/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/direction.cpython-39.pyc
Normal file
BIN
src/__pycache__/direction.cpython-39.pyc
Normal file
Binary file not shown.
4
src/agent/__init__.py
Normal file
4
src/agent/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
from .hero import Player
|
||||
from .map.gameMap import GameMap
|
||||
from .model import *
|
||||
from .state import AgentState
|
BIN
src/agent/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
src/agent/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/hero.cpython-39.pyc
Normal file
BIN
src/agent/__pycache__/hero.cpython-39.pyc
Normal file
Binary file not shown.
215
src/agent/ga_chromosome.py
Normal file
215
src/agent/ga_chromosome.py
Normal file
@ -0,0 +1,215 @@
|
||||
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
|
350
src/agent/hero.py
Normal file
350
src/agent/hero.py
Normal file
@ -0,0 +1,350 @@
|
||||
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))
|
BIN
src/agent/map/__pycache__/gameMap.cpython-39.pyc
Normal file
BIN
src/agent/map/__pycache__/gameMap.cpython-39.pyc
Normal file
Binary file not shown.
97
src/agent/map/gameMap.py
Normal file
97
src/agent/map/gameMap.py
Normal file
@ -0,0 +1,97 @@
|
||||
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))
|
6
src/agent/model/__init__.py
Normal file
6
src/agent/model/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
from .dice import *
|
||||
from .armor import Armor
|
||||
from .box import Box
|
||||
from .creature import Creature
|
||||
from .wall import Wall
|
||||
from .weapon import Weapon
|
BIN
src/agent/model/__pycache__/armor.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/armor.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/box.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/box.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/creature.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/creature.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/wall.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/wall.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/agent/model/__pycache__/weapon.cpython-39.pyc
Normal file
BIN
src/agent/model/__pycache__/weapon.cpython-39.pyc
Normal file
Binary file not shown.
21
src/agent/model/armor.py
Normal file
21
src/agent/model/armor.py
Normal file
@ -0,0 +1,21 @@
|
||||
class Armor:
|
||||
def __init__(self, name, defence, mp):
|
||||
self.__name = name
|
||||
self.__defence = defence
|
||||
self.__mag_protection = mp
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def get_defence(self):
|
||||
return self.__defence
|
||||
|
||||
def set_defence(self, new_defence):
|
||||
self.__defence = new_defence
|
||||
|
||||
def get_mag_protection(self):
|
||||
return self.__mag_protection
|
||||
|
||||
def set_mag_protection(self, new_mag_protection):
|
||||
self.__mag_protection = new_mag_protection
|
||||
|
42
src/agent/model/box.py
Normal file
42
src/agent/model/box.py
Normal file
@ -0,0 +1,42 @@
|
||||
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
|
||||
|
80
src/agent/model/creature.py
Normal file
80
src/agent/model/creature.py
Normal file
@ -0,0 +1,80 @@
|
||||
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)
|
0
src/agent/model/dice/__init__.py
Normal file
0
src/agent/model/dice/__init__.py
Normal file
BIN
src/agent/model/dice/__pycache__/dice.cpython-39.pyc
Normal file
BIN
src/agent/model/dice/__pycache__/dice.cpython-39.pyc
Normal file
Binary file not shown.
4
src/agent/model/dice/dice.py
Normal file
4
src/agent/model/dice/dice.py
Normal file
@ -0,0 +1,4 @@
|
||||
import random
|
||||
|
||||
def roll_the_dice(number):
|
||||
return random.randint(1, number)
|
9
src/agent/model/wall.py
Normal file
9
src/agent/model/wall.py
Normal file
@ -0,0 +1,9 @@
|
||||
from mesa import Agent
|
||||
|
||||
|
||||
class Wall(Agent):
|
||||
def __init__(self, unique_id, model):
|
||||
super().__init__(unique_id, model)
|
||||
|
||||
def step(self):
|
||||
pass
|
14
src/agent/model/weapon.py
Normal file
14
src/agent/model/weapon.py
Normal file
@ -0,0 +1,14 @@
|
||||
class Weapon:
|
||||
def __init__(self, name, weapon_type, weapon_damage):
|
||||
self.__name = name
|
||||
self.__type = weapon_type
|
||||
self.__damage = weapon_damage
|
||||
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def get_type(self):
|
||||
return self.__type
|
||||
|
||||
def get_damage(self):
|
||||
return self.__damage
|
20
src/decisiontree.py
Normal file
20
src/decisiontree.py
Normal file
@ -0,0 +1,20 @@
|
||||
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
|
BIN
src/dictionary/__pycache__/actions.cpython-39.pyc
Normal file
BIN
src/dictionary/__pycache__/actions.cpython-39.pyc
Normal file
Binary file not shown.
5
src/dictionary/actions.py
Normal file
5
src/dictionary/actions.py
Normal file
@ -0,0 +1,5 @@
|
||||
actions = {
|
||||
"rotate_left": -1,
|
||||
"move_forward": 0,
|
||||
"rotate_right": 1
|
||||
}
|
8
src/dictionary/directions.py
Normal file
8
src/dictionary/directions.py
Normal file
@ -0,0 +1,8 @@
|
||||
from src.direction import Direction
|
||||
|
||||
directions = {
|
||||
Direction.N: [0, 1],
|
||||
Direction.E: [1, 0],
|
||||
Direction.S: [0, -1],
|
||||
Direction.W: [-1, 0]
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
N = 0
|
||||
E = 1
|
||||
@ -7,9 +8,9 @@ class Direction(Enum):
|
||||
W = 3
|
||||
|
||||
def clockwise(self):
|
||||
v = (self.value+1)%4
|
||||
v = (self.value + 1) % 4
|
||||
return Direction(v)
|
||||
|
||||
def counterClockwise(self):
|
||||
v = (self.value-1)%4
|
||||
return Direction(v)
|
||||
def counter_clockwise(self):
|
||||
v = (self.value - 1) % 4
|
||||
return Direction(v)
|
BIN
src/items/__pycache__/armory.cpython-39.pyc
Normal file
BIN
src/items/__pycache__/armory.cpython-39.pyc
Normal file
Binary file not shown.
@ -1,6 +1,5 @@
|
||||
from mesa import Agent, Model
|
||||
import random
|
||||
from hero import Weapon, Armor
|
||||
from src.agent.model.weapon import Weapon
|
||||
from src.agent.model.armor import Armor
|
||||
|
||||
WM1 = Weapon("Log", "Melee", 1)
|
||||
WM2 = Weapon("Log", "Melee", 1)
|
||||
@ -15,16 +14,16 @@ 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", "Ranged", 1)
|
||||
WR2 = Weapon("Sling", "Ranged", 1)
|
||||
WR3 = Weapon("Sling", "Ranged", 1)
|
||||
WR4 = Weapon("Bow", "Ranged", 2)
|
||||
WR5 = Weapon("Bow", "Ranged", 2)
|
||||
WR6 = Weapon("Bow", "Ranged", 2)
|
||||
WR7 = Weapon("Bow", "Ranged", 2)
|
||||
WR8 = Weapon("Longbow", "Ranged", 3)
|
||||
WR9 = Weapon("Longbow", "Ranged", 3)
|
||||
WR10 = Weapon("Crossbow", "Ranged", 4)
|
||||
|
||||
S1 = Weapon("Push", "Magic", 2)
|
||||
S2 = Weapon("Push", "Magic", 2)
|
||||
@ -62,9 +61,9 @@ A16 = Armor("Magical Plate Armor", 3, 2)
|
||||
# C10 = Box(A8)
|
||||
# C11 = Box(A12)
|
||||
# C12 = Box(A14)
|
||||
|
||||
#
|
||||
# Gracz = Player(1000, self, "Janusz",3,3,3,20,20,WM1,A1,0,WR1,S1)
|
||||
# def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g):
|
||||
# def __init__(self, unique_id, model, n, s, a, w, max_hp, hp, weapon, arm, g):
|
||||
# M1 = Creature("Goblin",2,2,1,10,10,WM2,A2,dice(6))
|
||||
# M2 = Creature("Goblin",2,2,1,10,10,WM3,A3,dice(6))
|
||||
# M3 = Creature("Goblin",2,2,1,10,10,WR2,A4,dice(6))
|
9
src/nominalize.py
Normal file
9
src/nominalize.py
Normal file
@ -0,0 +1,9 @@
|
||||
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
|
BIN
src/tree/__pycache__/node.cpython-39.pyc
Normal file
BIN
src/tree/__pycache__/node.cpython-39.pyc
Normal file
Binary file not shown.
@ -5,6 +5,15 @@ class Node:
|
||||
self._state = state_tuple[1]
|
||||
self._parent = parent
|
||||
|
||||
def get_cost(self):
|
||||
return self._cost
|
||||
|
||||
def get_action(self):
|
||||
return self._action
|
||||
|
||||
def get_state(self):
|
||||
return self._state
|
||||
|
||||
def get_predecessor(self):
|
||||
return self._parent
|
||||
|
||||
@ -12,4 +21,4 @@ class Node:
|
||||
self._parent = predecessor
|
||||
|
||||
def __lt__(self, other):
|
||||
return self._cost < other._cost
|
||||
return self._cost < other.get_cost()
|
3
src/treesearch/__init__.py
Normal file
3
src/treesearch/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .bfs import BFS
|
||||
from .actionsInterpreter import ActionInterpreter
|
||||
from .heuristic import *
|
BIN
src/treesearch/__pycache__/actionsInterpreter.cpython-39.pyc
Normal file
BIN
src/treesearch/__pycache__/actionsInterpreter.cpython-39.pyc
Normal file
Binary file not shown.
BIN
src/treesearch/__pycache__/bfs.cpython-39.pyc
Normal file
BIN
src/treesearch/__pycache__/bfs.cpython-39.pyc
Normal file
Binary file not shown.
40
src/treesearch/actionsInterpreter.py
Normal file
40
src/treesearch/actionsInterpreter.py
Normal file
@ -0,0 +1,40 @@
|
||||
from src.agent.state import AgentState
|
||||
from src.direction import Direction
|
||||
|
||||
|
||||
class ActionInterpreter:
|
||||
|
||||
@staticmethod
|
||||
def interpret(action_index, default_state):
|
||||
if action_index == -1:
|
||||
return AgentState(
|
||||
default_state.get_x(),
|
||||
default_state.get_y(),
|
||||
default_state.get_direction().counter_clockwise()
|
||||
)
|
||||
elif action_index == 0:
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if default_state.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif default_state.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif default_state.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif default_state.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
return AgentState(
|
||||
default_state.get_x() + move_x,
|
||||
default_state.get_y() + move_y,
|
||||
default_state.get_direction()
|
||||
)
|
||||
elif action_index == 1:
|
||||
return AgentState(
|
||||
default_state.get_x(),
|
||||
default_state.get_y(),
|
||||
default_state.get_direction().clockwise()
|
||||
)
|
||||
else:
|
||||
return default_state
|
140
src/treesearch/bfs.py
Normal file
140
src/treesearch/bfs.py
Normal file
@ -0,0 +1,140 @@
|
||||
import heapq
|
||||
|
||||
from src.dictionary.actions import actions
|
||||
from src.agent.state import AgentState
|
||||
from src.direction import Direction
|
||||
from src.tree.node import Node
|
||||
from src.treesearch.heuristic.manhattan import manhattan
|
||||
|
||||
|
||||
class BFS:
|
||||
|
||||
def __init__(self, agent):
|
||||
self.__agent = agent
|
||||
|
||||
@staticmethod
|
||||
def successor(append):
|
||||
|
||||
rotate_left = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().counter_clockwise()
|
||||
)
|
||||
|
||||
rotate_right = AgentState(
|
||||
append.get_x(),
|
||||
append.get_y(),
|
||||
append.get_direction().clockwise()
|
||||
)
|
||||
|
||||
move_x = 0
|
||||
move_y = 0
|
||||
|
||||
if append.get_direction() == Direction.N:
|
||||
move_y = 1
|
||||
elif append.get_direction() == Direction.E:
|
||||
move_x = 1
|
||||
elif append.get_direction() == Direction.S:
|
||||
move_y = -1
|
||||
elif append.get_direction() == Direction.W:
|
||||
move_x = -1
|
||||
|
||||
if append.get_x() + move_x >= 0 and append.get_x() + move_x < 10 and append.get_y() + move_y >= 0 and append.get_y() + move_y < 10:
|
||||
move_forward = AgentState(
|
||||
append.get_x() + move_x,
|
||||
append.get_y() + move_y,
|
||||
append.get_direction()
|
||||
)
|
||||
else:
|
||||
move_forward = None
|
||||
|
||||
return [
|
||||
[actions["rotate_left"], rotate_left],
|
||||
[actions["move_forward"], move_forward],
|
||||
[actions["rotate_right"], rotate_right]
|
||||
]
|
||||
|
||||
def graphsearch(self, fringe, explored, istate, succesor_function, goal_state):
|
||||
final_action_list = []
|
||||
|
||||
init_state = [None, istate]
|
||||
root = Node(None, init_state, 0)
|
||||
|
||||
heapq.heappush(fringe, (0, root)) # at beginning do nothing
|
||||
|
||||
while len(fringe) != 0:
|
||||
_flag = True
|
||||
|
||||
if len(fringe) == 0:
|
||||
return False
|
||||
|
||||
tmp_node = (heapq.heappop(fringe))[1] # node
|
||||
|
||||
# build dictionary
|
||||
# parent = tmp_node.get_predecessor() # fetch parent state
|
||||
# tmp_node.set_predecessor(None) # clear predecessor - don't build a tree chain
|
||||
# if parent is None:
|
||||
# final_action_list.append([parent, tmp_node])
|
||||
# else:
|
||||
# final_action_list.append(
|
||||
# [parent[1], tmp_node]) # pair(key, value) - key: parent state, value: current state + action
|
||||
|
||||
if tmp_node.get_state().get_x() == goal_state.get_x() and tmp_node.get_state().get_y() == goal_state.get_y():
|
||||
while tmp_node.get_predecessor() is not None:
|
||||
final_action_list.append(tmp_node.get_action())
|
||||
tmp_node = tmp_node.get_predecessor()
|
||||
final_action_list = list(reversed(final_action_list))
|
||||
return final_action_list # TODO change step!
|
||||
|
||||
explored.append(tmp_node)
|
||||
|
||||
tmp_list = succesor_function(tmp_node.get_state())
|
||||
for new_state in tmp_list:
|
||||
_flag = True
|
||||
_flagFringe = True
|
||||
_flagExplored = True
|
||||
|
||||
if new_state[1] is None:
|
||||
continue
|
||||
|
||||
# calculating priority
|
||||
monster = 0
|
||||
if any([thing.isCreature for thing in
|
||||
self.__agent.model.grid.get_cell_list_contents(
|
||||
[(new_state[1].get_x(), new_state[1].get_y())])]):
|
||||
if new_state[0] == 0:
|
||||
monster = 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
src/treesearch/heuristic/__init__.py
Normal file
1
src/treesearch/heuristic/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .manhattan import manhattan
|
4
src/treesearch/heuristic/manhattan.py
Normal file
4
src/treesearch/heuristic/manhattan.py
Normal file
@ -0,0 +1,4 @@
|
||||
# cost is initially step distance in manhattan metric
|
||||
|
||||
def manhattan(state, target_state):
|
||||
return abs(state.get_x() - target_state.get_x()) + abs(state.get_y() - target_state.get_y())
|
192
tree_data_gen.py
Normal file
192
tree_data_gen.py
Normal file
@ -0,0 +1,192 @@
|
||||
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