Compare commits
1 Commits
master
...
PYTHON_SKL
Author | SHA1 | Date | |
---|---|---|---|
|
4e69ca18ef |
367
DataModels/GC.py
367
DataModels/GC.py
@ -2,119 +2,294 @@ from DataModels.Cell import Cell
|
||||
from DataModels.Road import Road
|
||||
from DataModels.House import House
|
||||
from DataModels.Dump import Dump
|
||||
from DataModels.Grass import Grass
|
||||
from config import GRID_WIDTH, GRID_HEIGHT, DELAY
|
||||
from utilities import movement, check_moves, save_moveset
|
||||
from utilities import movement, check_moves, save_moveset, parse_coords
|
||||
from Traversal.DFS import DFS
|
||||
from Traversal.BestFS import BestFS
|
||||
from Traversal.BFS import BFS
|
||||
import pygame
|
||||
import numpy
|
||||
from sklearn import svm, tree
|
||||
import json
|
||||
import pickle
|
||||
|
||||
MAPS = []
|
||||
|
||||
def map2int( objector ):
|
||||
|
||||
ci = type(objector)
|
||||
|
||||
if ci == Grass:
|
||||
return 1
|
||||
if ci == Road:
|
||||
return 2
|
||||
if ci == Dump:
|
||||
return 3
|
||||
|
||||
if ci == House:
|
||||
if objector.unvisited == True:
|
||||
return 4
|
||||
else:
|
||||
return 1
|
||||
|
||||
def partial_map(grid, gc_pos, houseses):
|
||||
grid = numpy.transpose(grid)
|
||||
|
||||
x,y = gc_pos[0],gc_pos[1]
|
||||
map_part = []
|
||||
|
||||
#5x5
|
||||
#coords = [ [x-2,y-2],[x-1,y-2],[x+0,y-2],[x+1,y-2],[x+2,y-2],
|
||||
# [x-2,y-1],[x-1,y-1],[x+0,y-1],[x+1,y-1],[x+2,y-1],
|
||||
# [x-2,y+0],[x-1,y+0],[x+0,y+0],[x+1,y+0],[x+2,y+0],
|
||||
# [x-2,y+1],[x-1,y+1],[x+0,y+1],[x+1,y+1],[x+2,y+1],
|
||||
# [x-2,y+2],[x-1,y+2],[x+0,y+2],[x+1,y+2],[x+2,y+2]]
|
||||
|
||||
#7x7
|
||||
coords = [
|
||||
[x-3,y-3],[x-2,y-3],[x-1,y-3],[x+0,y-3],[x+1,y-3],[x+2,y-3],[x+3,y-3],
|
||||
[x-3,y-2],[x-2,y-2],[x-1,y-2],[x+0,y-2],[x+1,y-2],[x+2,y-2],[x+3,y-2],
|
||||
[x-3,y-1],[x-2,y-1],[x-1,y-1],[x+0,y-1],[x+1,y-1],[x+2,y-1],[x+3,y-1],
|
||||
[x-3,y+0],[x-2,y+0],[x-1,y+0],[x+0,y+0],[x+1,y+0],[x+2,y+0],[x+3,y+0],
|
||||
[x-3,y+1],[x-2,y+1],[x-1,y+1],[x+0,y+1],[x+1,y+1],[x+2,y+1],[x+3,y+1],
|
||||
[x-3,y+2],[x-2,y+2],[x-1,y+2],[x+0,y+2],[x+1,y+2],[x+2,y+2],[x+3,y+2],
|
||||
[x-3,y+3],[x-2,y+3],[x-1,y+3],[x+0,y+3],[x+1,y+3],[x+2,y+3],[x+3,y+3]
|
||||
]
|
||||
|
||||
for coord in coords:
|
||||
flag = 0
|
||||
|
||||
for item in houseses:
|
||||
if( coord == item ):
|
||||
map_part.append(1)
|
||||
flag = 1
|
||||
break
|
||||
|
||||
if( flag == 1 ):
|
||||
continue
|
||||
|
||||
if( 0 <= coord[1] < GRID_HEIGHT and 0 <= coord[0] < GRID_WIDTH ):
|
||||
map_part.append(map2int(grid[coord[1]][coord[0]]))
|
||||
else:
|
||||
map_part.append(1)
|
||||
|
||||
return map_part
|
||||
|
||||
class GC(Cell):
|
||||
moves_made = 0
|
||||
def __init__(self, x, y, max_rubbish, yellow=0, green=0, blue=0):
|
||||
Cell.__init__(self, x, y, max_rubbish, yellow, green, blue)
|
||||
self.moves = []
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
def move(self, direction, environment):
|
||||
self.x, self.y = movement(environment, self.x, self.y)[0][direction]
|
||||
self.update_rect(self.x, self.y)
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
moves_made = 0
|
||||
def __init__(self, x, y, max_rubbish, yellow=0, green=0, blue=0):
|
||||
Cell.__init__(self, x, y, max_rubbish, yellow, green, blue)
|
||||
self.moves = []
|
||||
self.housesC = []
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
self.initial_position = [[x, y]]
|
||||
self.run_training()
|
||||
|
||||
print(check_moves(environment, self.x, self.y,direction))
|
||||
def run_trained(self, grid):
|
||||
pos = [self.x,self.y]
|
||||
print(partial_map(grid,pos,self.housesC))
|
||||
direct = self.clf.predict([partial_map(grid,pos,self.housesC)])[0]
|
||||
return direct
|
||||
|
||||
def collect(self, enviromnent):
|
||||
x, y = [self.x, self.y]
|
||||
coordinates = [(x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y)]
|
||||
for coordinate in coordinates:
|
||||
if coordinate[0]<0 or coordinate[1]<0:
|
||||
continue
|
||||
try:
|
||||
item = enviromnent[coordinate[0]][coordinate[1]]
|
||||
except:
|
||||
continue
|
||||
def run_training(self):
|
||||
try:
|
||||
with open('clf.json','rb') as fc:
|
||||
self.clf = pickle.load(fc)
|
||||
return
|
||||
except:
|
||||
pass
|
||||
### SVM OR TREE
|
||||
self.clf = svm.SVC(gamma='scale')
|
||||
|
||||
if(type(item) == House or type(item) == Dump):
|
||||
item.return_trash(self)
|
||||
self.update_image()
|
||||
#self.clf = tree.DecisionTreeClassifier()
|
||||
f = open('moveset_data.json','r')
|
||||
datas = json.load(f)
|
||||
|
||||
def get_moves_count(self):
|
||||
return self.moves_made
|
||||
X = []
|
||||
y = []
|
||||
|
||||
def find_houses(self,enviromnent, house_count,dump_count, mode):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = []
|
||||
element_list=[]
|
||||
house_count_after_search=house_count
|
||||
for home in range(house_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
house,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
elif mode == "BFS":
|
||||
house,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
result = result[1::]
|
||||
self.moves.extend(result)
|
||||
element_list.append(house)
|
||||
for x in range(0,len(datas['moveset'])):
|
||||
X += (datas['moveset'][x]['maps'])
|
||||
|
||||
for dump in range(dump_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
dump,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
elif mode == "BFS":
|
||||
dump,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
self.moves.extend(result)
|
||||
element_list.append(dump)
|
||||
for x in element_list:
|
||||
x.unvisited = True
|
||||
self.moves.reverse()
|
||||
save_moveset(self.moves)
|
||||
for x in range(0,len(datas['moveset'])):
|
||||
y += (datas['moveset'][x]['moves'])
|
||||
|
||||
self.clf.fit(X,y)
|
||||
with open('clf.json','wb') as fc:
|
||||
pickle.dump(self.clf,fc)
|
||||
|
||||
def move(self, direction, environment):
|
||||
self.x, self.y = movement(environment, self.x, self.y)[0][direction]
|
||||
self.update_rect(self.x, self.y)
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
|
||||
def collect(self, enviromnent):
|
||||
x, y = [self.x, self.y]
|
||||
coordinates = [(x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y)]
|
||||
for coordinate in coordinates:
|
||||
if coordinate[0]<0 or coordinate[1]<0:
|
||||
continue
|
||||
try:
|
||||
item = enviromnent[coordinate[0]][coordinate[1]]
|
||||
except:
|
||||
continue
|
||||
|
||||
if(type(item) == House or type(item) == Dump):
|
||||
if(type(item) == House):
|
||||
self.housesC.append([item.x,item.y])
|
||||
item.return_trash(self)
|
||||
self.update_image()
|
||||
|
||||
def get_moves_count(self):
|
||||
return self.moves_made
|
||||
|
||||
def find_houses(self,enviromnent, house_count,dump_count, mode):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = []
|
||||
element_list=[]
|
||||
house_count_after_search=house_count
|
||||
for home in range(house_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
house,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
elif mode == "BFS":
|
||||
house,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
result = result[1::]
|
||||
self.moves.extend(result)
|
||||
element_list.append(house)
|
||||
|
||||
|
||||
def find_houses_BestFS(self, environment):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = [[x,y]]
|
||||
for dump in range(dump_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
dump,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
elif mode == "BFS":
|
||||
dump,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
self.moves.extend(result)
|
||||
element_list.append(dump)
|
||||
for x in element_list:
|
||||
x.unvisited = True
|
||||
self.moves.reverse()
|
||||
|
||||
houses_list = []
|
||||
dump_list = []
|
||||
a = 0
|
||||
for row in environment:
|
||||
b = 0
|
||||
for col in row:
|
||||
if (type(col) is House):
|
||||
houses_list.append([col,[a,b]])
|
||||
if (type(col) is Dump):
|
||||
dump_list.append([col,[a,b]])
|
||||
b += 1
|
||||
a += 1
|
||||
houseses = []
|
||||
moves_L = (self.initial_position + (self.moves[::-1]))
|
||||
last_pos = None
|
||||
for i in range(len(moves_L)):
|
||||
if( moves_L[i] == 'pick_garbage' ):
|
||||
xc,yc = last_pos[0],last_pos[1]
|
||||
|
||||
x, y = self.x, self.y
|
||||
possibl = []
|
||||
|
||||
for i in range(len(houses_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], houses_list)
|
||||
if(output != None):
|
||||
[x,y],result,houses_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
for i in range(len(dump_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], dump_list)
|
||||
if(output != None):
|
||||
[x,y],result,dump_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
self.moves.reverse()
|
||||
save_moveset(self.moves)
|
||||
if( xc-1 >= 0 ):
|
||||
possibl.append([xc-1,yc])
|
||||
if( xc+1 < GRID_WIDTH ):
|
||||
possibl.append([xc+1,yc])
|
||||
if( yc-1 >= 0 ):
|
||||
possibl.append([xc,yc-1])
|
||||
if( yc+1 < GRID_HEIGHT):
|
||||
possibl.append([xc,yc+1])
|
||||
#print("POSSIBL")
|
||||
#print(possibl)
|
||||
#print("##########")
|
||||
for posi in possibl:
|
||||
if( type(enviromnent[posi[0]][posi[1]]) == House ):
|
||||
houseses.append(posi)
|
||||
#MAPS.append(MAPS[-1])
|
||||
MAPS.append(partial_map(enviromnent,last_pos,houseses) )
|
||||
else:
|
||||
last_pos = moves_L[i]
|
||||
#print("HOUSES")
|
||||
#print(houseses)
|
||||
#print("##########")
|
||||
MAPS.append(partial_map(enviromnent,moves_L[i],houseses) )
|
||||
|
||||
moves_to_file = []
|
||||
maps_to_file = []
|
||||
|
||||
def make_actions_from_list(self,environment):
|
||||
now = pygame.time.get_ticks()
|
||||
if len(self.moves)==0 or now - self.old_time <= DELAY:
|
||||
return
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
if self.moves[-1] == "pick_garbage":
|
||||
self.collect(environment)
|
||||
self.moves.pop()
|
||||
return
|
||||
self.x, self.y = self.moves.pop()
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
self.update_rect(self.x,self.y)
|
||||
save_moveset(self.initial_position + (self.moves[::-1]), MAPS)
|
||||
|
||||
def find_houses_BestFS(self, environment):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = [[x,y]]
|
||||
|
||||
houses_list = []
|
||||
dump_list = []
|
||||
a = 0
|
||||
for row in environment:
|
||||
b = 0
|
||||
for col in row:
|
||||
if (type(col) is House):
|
||||
houses_list.append([col,[a,b]])
|
||||
if (type(col) is Dump):
|
||||
dump_list.append([col,[a,b]])
|
||||
b += 1
|
||||
a += 1
|
||||
|
||||
x, y = self.x, self.y
|
||||
|
||||
for i in range(len(houses_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], houses_list)
|
||||
if(output != None):
|
||||
[x,y],result,houses_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
for i in range(len(dump_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], dump_list)
|
||||
if(output != None):
|
||||
[x,y],result,dump_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
self.moves.reverse()
|
||||
|
||||
houseses = []
|
||||
moves_L = (self.initial_position + (self.moves[::-1]))
|
||||
last_pos = None
|
||||
for i in range(len(moves_L)):
|
||||
if( moves_L[i] == 'pick_garbage' ):
|
||||
xc,yc = last_pos[0],last_pos[1]
|
||||
|
||||
possibl = []
|
||||
|
||||
if( xc-1 >= 0 ):
|
||||
possibl.append([xc-1,yc])
|
||||
if( xc+1 < GRID_WIDTH ):
|
||||
possibl.append([xc+1,yc])
|
||||
if( yc-1 >= 0 ):
|
||||
possibl.append([xc,yc-1])
|
||||
if( yc+1 < GRID_HEIGHT):
|
||||
possibl.append([xc,yc+1])
|
||||
#print("POSSIBL")
|
||||
#print(possibl)
|
||||
#print("##########")
|
||||
for posi in possibl:
|
||||
if( type(environment[posi[0]][posi[1]]) == House ):
|
||||
houseses.append(posi)
|
||||
#MAPS.append(MAPS[-1])
|
||||
MAPS.append(partial_map(environment,last_pos,houseses) )
|
||||
else:
|
||||
last_pos = moves_L[i]
|
||||
#print("HOUSES")
|
||||
#print(houseses)
|
||||
#print("##########")
|
||||
MAPS.append(partial_map(environment,moves_L[i],houseses) )
|
||||
|
||||
moves_to_file = []
|
||||
maps_to_file = []
|
||||
|
||||
save_moveset(self.initial_position + (self.moves[::-1]), MAPS)
|
||||
|
||||
def make_actions_from_list(self,environment):
|
||||
now = pygame.time.get_ticks()
|
||||
if len(self.moves)==0 or now - self.old_time <= DELAY:
|
||||
return
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
if self.moves[-1] == "pick_garbage":
|
||||
self.collect(environment)
|
||||
self.moves.pop()
|
||||
return
|
||||
self.x, self.y = self.moves.pop()
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
self.update_rect(self.x,self.y)
|
||||
|
120
DataModels/GC.py.save
Normal file
120
DataModels/GC.py.save
Normal file
@ -0,0 +1,120 @@
|
||||
from DataModels.Cell import Cell
|
||||
from DataModels.Road import Road
|
||||
from DataModels.House import House
|
||||
from DataModels.Dump import Dump
|
||||
from config import GRID_WIDTH, GRID_HEIGHT, DELAY
|
||||
from utilities import movement, check_moves, save_moveset
|
||||
from Traversal.DFS import DFS
|
||||
from Traversal.BestFS import BestFS
|
||||
from Traversal.BFS import BFS
|
||||
import pygame
|
||||
|
||||
class GC(Cell):
|
||||
moves_made = 0
|
||||
def __init__(self, x, y, max_rubbish, yellow=0, green=0, blue=0):
|
||||
Cell.__init__(self, x, y, max_rubbish, yellow, green, blue)
|
||||
self.moves = []
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
def move(self, direction, environment):
|
||||
self.x, self.y = movement(environment, self.x, self.y)[0][direction]
|
||||
self.update_rect(self.x, self.y)
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
|
||||
print(check_moves(environment, self.x, self.y,direction))
|
||||
|
||||
def collect(self, enviromnent):
|
||||
x, y = [self.x, self.y]
|
||||
coordinates = [(x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y)]
|
||||
for coordinate in coordinates:
|
||||
if coordinate[0]<0 or coordinate[1]<0:
|
||||
continue
|
||||
try:
|
||||
item = enviromnent[coordinate[0]][coordinate[1]]
|
||||
except:
|
||||
continue
|
||||
|
||||
if(type(item) == House or type(item) == Dump):
|
||||
item.return_trash(self)
|
||||
self.update_image()
|
||||
|
||||
def get_moves_count(self):
|
||||
return self.moves_made
|
||||
|
||||
def find_houses(self,enviromnent, house_count,dump_count, mode):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = []
|
||||
element_list=[]
|
||||
house_count_after_search=house_count
|
||||
for home in range(house_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
house,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
elif mode == "BFS":
|
||||
house,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],House)
|
||||
result = result[1::]
|
||||
self.moves.extend(result)
|
||||
element_list.append(house)
|
||||
|
||||
for dump in range(dump_count):
|
||||
avalible_moves = check_moves(enviromnent, x,y)
|
||||
if mode == "DFS":
|
||||
dump,[x,y],result = DFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
elif mode == "BFS":
|
||||
dump,[x,y],result = BFS(enviromnent,avalible_moves,[[x,y]],Dump)
|
||||
self.moves.extend(result)
|
||||
element_list.append(dump)
|
||||
for x in element_list:
|
||||
x.unvisited = True
|
||||
self.moves.reverse()
|
||||
save_moveset(self.moves)
|
||||
|
||||
|
||||
def find_houses_BestFS(self, environment):
|
||||
x = self.x
|
||||
y = self.y
|
||||
result = [[x,y]]
|
||||
|
||||
houses_list = []
|
||||
dump_list = []
|
||||
a = 0
|
||||
for row in environment:
|
||||
b = 0
|
||||
for col in row:
|
||||
if (type(col) is House):
|
||||
houses_list.append([col,[a,b]])
|
||||
if (type(col) is Dump):
|
||||
dump_list.append([col,[a,b]])
|
||||
b += 1
|
||||
a += 1
|
||||
|
||||
x, y = self.x, self.y
|
||||
|
||||
for i in range(len(houses_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], houses_list)
|
||||
if(output != None):
|
||||
[x,y],result,houses_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
for i in range(len(dump_list)):
|
||||
available_movement = check_moves(environment, x, y)
|
||||
output = BestFS(environment, available_movement, [[x,y]], dump_list)
|
||||
if(output != None):
|
||||
[x,y],result,dump_list = output[0], output[1], output[2]
|
||||
self.moves.extend(result[1:])
|
||||
self.moves.reverse()
|
||||
save_moveset(self.moves)
|
||||
|
||||
|
||||
def make_actions_from_list(self,environment):
|
||||
now = pygame.time.get_ticks()
|
||||
if len(self.moves)==0 or now - self.old_time <= DELAY:
|
||||
return
|
||||
self.old_time = pygame.time.get_ticks()
|
||||
if self.moves[-1] == "pick_garbage":
|
||||
self.collect(environment)
|
||||
self.moves.pop()
|
||||
return
|
||||
self.x, self.y = self.moves.pop()
|
||||
self.moves_made = self.moves_made + 1 #moves counter
|
||||
self.update_rect(self.x,self.y)
|
@ -4,6 +4,8 @@ def GenerateMap():
|
||||
#generate random empty map
|
||||
width = random.randint(5,15) #up to 15
|
||||
height = random.randint(5,10) #up to 10
|
||||
width = 10
|
||||
height = 10
|
||||
grid = []
|
||||
|
||||
row = []
|
||||
|
@ -1,89 +0,0 @@
|
||||
---
|
||||
|
||||
# SVM raport
|
||||
|
||||
##### Konrad Pierzyński
|
||||
|
||||
###### Śmieciarz
|
||||
|
||||
12.06.2019
|
||||
|
||||
---
|
||||
|
||||
**SVM** - **S**upport-**V**ector **M**achine - zestaw metod uczenia stosowanych głównie do klasyfikacji, której nauka ma na celu wyznaczenie płaszczyzn rozdzielających dane wejściowe na klasy.
|
||||
|
||||
![5d00b5469956838867](https://i.loli.net/2019/06/12/5d00b5469956838867.png)
|
||||
|
||||
---
|
||||
|
||||
### Przygotowanie danych
|
||||
|
||||
Dane uczące zostały wygenerowane w następujący sposób:
|
||||
|
||||
+ Program generuje losową mapę o określonych wymiarach
|
||||
|
||||
+ Uruchamiany jest jeden z algorytmów (*BestFirstSearch*), który generuje listę ruchów.
|
||||
|
||||
+ Do zestawu uczącego dopisywana jest para składająca się na ruch i otoczenie gracza.
|
||||
|
||||
- Ruch odpowiada kierunkom: góra, prawo, dół, lewo i akcji zebrania/oddania śmieci - odpowienio liczbowo 1, 2, 3, 4, 99
|
||||
|
||||
- Otocznie to tablica dwuwymiarowa 7x7, gdzie element środkowy to pozycja gracza. Tablica ta następnie spłaszczana jest do tablicy jednowymiarowej
|
||||
|
||||
- Każdy 'domek', na którym została wykonana już akcja zebrania i jest opróżniony, widoczny jest na mapie tak samo jak element otoczenia, z którym gracz nie może wejść w żadną interakcję (stanąć, zebrać)
|
||||
|
||||
- Jeśli siatka 7x7 wykracza swoim zakresem za mapę, siatka uzupełniana jest przez trawę, czyli obiekt, z którym gracz nie wchodzi w interakcję
|
||||
|
||||
+ Po przejściu całej mapy algorytmem i zebraniu danych proces jest powtarzany tak długo, by zgromadzić około tysiąc rozwiązanych map
|
||||
|
||||
Pojedynczy zestaw danych jest zapisywany jako json postaci:
|
||||
|
||||
```json
|
||||
{
|
||||
"maps": [
|
||||
[Int, Int, ...],
|
||||
[Int, Int, ...],
|
||||
...
|
||||
],
|
||||
"moves":
|
||||
[
|
||||
Int, Int, ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
I dopisywany do głównej struktury:
|
||||
|
||||
```json
|
||||
{
|
||||
"moveset": [
|
||||
Zestaw, Zestaw, ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Uczenie
|
||||
|
||||
Do przeprowadzenia procesu uczenia dane uczące zostały podzielone na dwie listy:
|
||||
|
||||
- Pierwsza lista X zawiera wszystkie mapy częściowe (otoczenia)
|
||||
|
||||
```X = [ [Int, Int, ...], [Int, Int, ...], ... ]```
|
||||
|
||||
- Druga lista y zawiera odpowiadające mapom ruchy (1,2,3,4,99), które wykonał algorytm (*BestFirstSearch*) na danych otoczeniach.
|
||||
|
||||
```y = [ Int, Int, ... ]```
|
||||
|
||||
Wyżej wymienione dwie listy zostały podane jako argument metodzie ```fit(X,y)```, która odpowiada za uczenie się SVM. Natomiast utworzenie samego obiektu polega na zaimportowaniu biblioteki *scikit-learn*:
|
||||
```from sklearn import svm```
|
||||
a następnie już same utworzenia obiektu svm:
|
||||
```clf = svm.SVC(gamma='scale')```
|
||||
Wyuczony obiekt jest zapisywany do pliku, dzięki modułowi ```pickle```, aby nie przeprowadzać procesu uczenia za każdym uruchomieniem programu.
|
||||
|
||||
---
|
||||
|
||||
### Wykonywanie ruchów
|
||||
|
||||
Do przewidywania ruchów wystarczy użyć metody ```predict([ [otoczenie] ])``` , które przyjmuje mapę częściową, a jej wynik jest akcją, którą powinien wykonać gracz. Wynik metody przekazywany jest graczowi, który wykonuje ruch.
|
@ -1,92 +0,0 @@
|
||||
# Sztuczna Inteligencja 2019 - Raport Indywidualny
|
||||
|
||||
**Czas trwania opisywanych prac:** 09.05.2019 - 11.06.2019
|
||||
|
||||
**Autor:** Michał Starski
|
||||
|
||||
**Wybrany temat:** Inteligentna śmieciarka
|
||||
|
||||
**Link do repozytorium projektu:** https://git.wmi.amu.edu.pl/s440556/SZI2019SmieciarzWmi
|
||||
|
||||
## Wybrany algorytm uczenia - drzewa decyzyjne
|
||||
|
||||
### Przygotowane dane
|
||||
|
||||
Aby zapewnić smieciarce jak najlepszy wynik, do przygotowania danych do uczenia wybrałem algorytm szukania najkrótszej ścieżki, który dawał najlepsze wyniki podczas projektu grupowego - **BestFS**.
|
||||
|
||||
Podczas każdego jednorazowego przebiegu algorytmu BestFS patrzyłem na to jaki krok śmieciarka wykonuje w danej sytuacji, a następnie dane kroki zapisywałem do pliku w formacie json, tworząc próbki do późniejszej nauki.
|
||||
|
||||
Przykładowa próbka w formacie json:
|
||||
|
||||
```json
|
||||
{
|
||||
"moveset": [
|
||||
{
|
||||
"maps": [[1, 1, 3, 4, 2, 2, 2, 2, 1], [2, 1, 1, 3, 1, 4, 1, 1, 1]],
|
||||
"moves": [1, 2]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
`moveset` to tablica wszystkich próbek wykorzystywanych do nauki.
|
||||
Każdy element tablicy to obiekt posiadający dwa pola:
|
||||
`maps` - otoczenie śmieciarki w danym kroku,
|
||||
`moves` - ruch śmieciarki przy danym otoczeniu
|
||||
|
||||
W powyższym przykładzie dla czytelności, zostały przedstawione otoczenia 3x3 wokół śmieciarki. W implementacji obszar ten został powiększony do 7x7 w celu poprawienia dokładności algorytmu.
|
||||
|
||||
#### Maps
|
||||
|
||||
Spłaszczona tablicę dwuwymiarową przedstawiająca otoczenie śmieciarki w konkretnym momencie działania algorytmu. Każda z cyfr przedstawia inny obiekt na mapie:
|
||||
|
||||
- 1 - Trawa (Grass)
|
||||
- 2 - Droga (Road)
|
||||
- 3 - Wysypisko (Dump)
|
||||
- 4 - Dom (House)
|
||||
|
||||
Dla powyższego przykładu pierwsza sytuacja (`moveset[0].maps[0]`) przedstawia następujące otoczenie na mapie
|
||||
|
||||
```
|
||||
G G D
|
||||
H R R
|
||||
R R G
|
||||
```
|
||||
|
||||
#### Moves
|
||||
|
||||
Tablica ruchów śmieciarki. i-ty ruch w tablicy odpowiada i-temu otoczeniu. Wyróżnimay 5 różnych ruchów agenta:
|
||||
|
||||
- 1 - Lewo
|
||||
- 2 - Prawo
|
||||
- 3 - Dół
|
||||
- 4 - Góra
|
||||
- 99 - Zbierz śmieci
|
||||
|
||||
Tak więc dla powyższego otoczenia `1` będzie oznaczać, że agent ruszył się w lewo.
|
||||
|
||||
---
|
||||
|
||||
### Implementacja
|
||||
|
||||
Do implementacji uczenia poprzez drzewo decyzyjny wykorzystałem bibliotekę [scikit learn](https://scikit-learn.org) do języka **python**. Podając odpowiednie dane, biblioteka przygotuje nam model zdolny do samodzielnego poruszania się na mapie.
|
||||
|
||||
```python
|
||||
#Trenowanie modelu
|
||||
from sklearn import tree
|
||||
X = [Kolejne otoczenia 7x7 w danym kroku]
|
||||
Y = [Kolejne kroki odpowiednie dla danego otoczenia]
|
||||
clf = tree.DecisionTreeClassifier()
|
||||
clf = clf.fit(X, Y)
|
||||
|
||||
#Samodzielny ruch wytrenowanego modelu
|
||||
clf.predict([Otoczenie agenta])
|
||||
```
|
||||
|
||||
`clf.predict` zwróci nam 1 z 5 ruchów, które ma wykonać agent.
|
||||
|
||||
---
|
||||
|
||||
### Obserwacje
|
||||
|
||||
W idealnym przypadku wytrenowany model powinien odzwierciedlać algorytm BestFS, jako iż to na podstawie jego był trenowany i to jego decyzje starał się naśladować. W rzeczywistości jednak po przygotowaniu ok. 1000 próbek agent radził sobie różnorako. Na jednych mapach poruszał się dość sprawnie, jednak na wielu nie wiedział co ma robić. Przyczyny mogą być różne, jednak w mojej opinii, przygotowanych danych było jednak trochę za mało i gdyby dać o wiele więcej danych do wytrenowania modelu, rezultat byłby o wiele lepszy.
|
@ -1,39 +1,44 @@
|
||||
from utilities import movement,check_moves
|
||||
from DataModels.House import House
|
||||
from DataModels.Dump import Dump
|
||||
from DataModels.Grass import Grass
|
||||
from DataModels.Road import Road
|
||||
from DataModels.Container import Container
|
||||
from config import GRID_WIDTH, GRID_HEIGHT
|
||||
|
||||
def DFS(grid, available_movement, gc_moveset, mode,depth=0):
|
||||
|
||||
possible_goals = []
|
||||
a = gc_moveset[-1][0]
|
||||
b = gc_moveset[-1][1]
|
||||
possible_goals.append([a+1,b])
|
||||
possible_goals.append([a-1,b])
|
||||
possible_goals.append([a,b+1])
|
||||
possible_goals.append([a,b-1])
|
||||
object_in_area = False
|
||||
for location in possible_goals:
|
||||
if GRID_WIDTH>location[0]>=0 and GRID_HEIGHT>location[1]>=0:
|
||||
cell = grid[location[0]][location[1]]
|
||||
if(type(cell) == mode and cell.unvisited):
|
||||
cell.unvisited = False
|
||||
object_in_area = True
|
||||
break
|
||||
possible_goals = []
|
||||
a = gc_moveset[-1][0]
|
||||
b = gc_moveset[-1][1]
|
||||
possible_goals.append([a+1,b])
|
||||
possible_goals.append([a-1,b])
|
||||
possible_goals.append([a,b+1])
|
||||
possible_goals.append([a,b-1])
|
||||
object_in_area = False
|
||||
|
||||
x,y = gc_moveset[-1]
|
||||
if(object_in_area):
|
||||
gc_moveset.append("pick_garbage")
|
||||
return [cell,[x,y], gc_moveset]
|
||||
for location in possible_goals:
|
||||
if GRID_WIDTH>location[0]>=0 and GRID_HEIGHT>location[1]>=0:
|
||||
cell = grid[location[0]][location[1]]
|
||||
if(type(cell) == mode and cell.unvisited):
|
||||
cell.unvisited = False
|
||||
object_in_area = True
|
||||
break
|
||||
|
||||
if len(available_movement) == 0 or depth>30:
|
||||
return
|
||||
for direction in available_movement:
|
||||
x_next, y_next = movement(grid,x,y)[0][direction]
|
||||
available_movement_next = check_moves(grid, x_next,y_next,direction)
|
||||
gc_moveset_next = gc_moveset.copy()
|
||||
gc_moveset_next.append([x_next,y_next])
|
||||
result = DFS(grid, available_movement_next, gc_moveset_next,mode, depth+1)
|
||||
if result!= None:
|
||||
return result
|
||||
x,y = gc_moveset[-1]
|
||||
if(object_in_area):
|
||||
gc_moveset.append("pick_garbage")
|
||||
return [cell,[x,y], gc_moveset]
|
||||
|
||||
if len(available_movement) == 0 or depth>30:
|
||||
return
|
||||
|
||||
for direction in available_movement:
|
||||
x_next, y_next = movement(grid,x,y)[0][direction]
|
||||
available_movement_next = check_moves(grid, x_next,y_next,direction)
|
||||
gc_moveset_next = gc_moveset.copy()
|
||||
gc_moveset_next.append([x_next,y_next])
|
||||
|
||||
result = DFS(grid, available_movement_next, gc_moveset_next,mode, depth+1)
|
||||
if result!= None:
|
||||
return result
|
||||
|
@ -3,7 +3,7 @@ from MapGenerator import GenerateMap
|
||||
|
||||
CELL_SIZE = 64
|
||||
FPS = 60
|
||||
DELAY = 50
|
||||
DELAY = 250
|
||||
|
||||
try:
|
||||
MAP_NAME = sys.argv[1]
|
||||
|
153
main.py
153
main.py
@ -26,97 +26,110 @@ map.readline()
|
||||
map.readline()
|
||||
|
||||
map_objects = [[None for y in range(0, GRID_HEIGHT)]
|
||||
for x in range(0, GRID_WIDTH)]
|
||||
for x in range(0, GRID_WIDTH)]
|
||||
|
||||
|
||||
def generate(letter):
|
||||
key = 'D' if letter in ['B', 'G', 'Y'] else letter
|
||||
letter_mapping = {
|
||||
'E': lambda x, y: Grass(x, y),
|
||||
'H': lambda x, y, max_rubbish, yellow, green, blue: House(x, y, max_rubbish, yellow, green, blue),
|
||||
'D': lambda x, y, max_rubbish, dump_type: Dump(x, y, max_rubbish, dump_type),
|
||||
'R': lambda x, y: Road(x, y)
|
||||
}
|
||||
key = 'D' if letter in ['B', 'G', 'Y'] else letter
|
||||
letter_mapping = {
|
||||
'E': lambda x, y: Grass(x, y),
|
||||
'H': lambda x, y, max_rubbish, yellow, green, blue: House(x, y, max_rubbish, yellow, green, blue),
|
||||
'D': lambda x, y, max_rubbish, dump_type: Dump(x, y, max_rubbish, dump_type),
|
||||
'R': lambda x, y: Road(x, y)
|
||||
}
|
||||
|
||||
return letter_mapping[key]
|
||||
return letter_mapping[key]
|
||||
|
||||
|
||||
i = 0
|
||||
for y in map.readlines():
|
||||
for x in y.split():
|
||||
for x in y.split():
|
||||
|
||||
x_coord = i % GRID_WIDTH
|
||||
y_coord = (i-x_coord)//GRID_WIDTH
|
||||
x_coord = i % GRID_WIDTH
|
||||
y_coord = (i-x_coord)//GRID_WIDTH
|
||||
|
||||
yellow, green, blue = [randint(0, HOUSE_CAPACITY // 2), randint(
|
||||
0, HOUSE_CAPACITY // 2), randint(0, HOUSE_CAPACITY // 2)]
|
||||
if x is 'E':
|
||||
map_objects[x_coord][y_coord] = generate(x)(x_coord, y_coord)
|
||||
elif x is 'H':
|
||||
map_objects[x_coord][y_coord] = generate(x)(
|
||||
x_coord, y_coord, HOUSE_CAPACITY, yellow, green, blue)
|
||||
house_count+=1
|
||||
elif x is 'B':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Blue")
|
||||
dump_count+=1
|
||||
elif x is 'G':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Green")
|
||||
dump_count+=1
|
||||
elif x is 'Y':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Yellow")
|
||||
dump_count+=1
|
||||
elif x is 'R':
|
||||
map_objects[x_coord][y_coord] = generate(x)(x_coord, y_coord)
|
||||
i += 1
|
||||
yellow, green, blue = [randint(0, HOUSE_CAPACITY // 2), randint(
|
||||
0, HOUSE_CAPACITY // 2), randint(0, HOUSE_CAPACITY // 2)]
|
||||
if x is 'E':
|
||||
map_objects[x_coord][y_coord] = generate(x)(x_coord, y_coord)
|
||||
elif x is 'H':
|
||||
map_objects[x_coord][y_coord] = generate(x)(
|
||||
x_coord, y_coord, HOUSE_CAPACITY, yellow, green, blue)
|
||||
house_count+=1
|
||||
elif x is 'B':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Blue")
|
||||
dump_count+=1
|
||||
elif x is 'G':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Green")
|
||||
dump_count+=1
|
||||
elif x is 'Y':
|
||||
map_objects[x_coord][y_coord] = generate(
|
||||
x)(x_coord, y_coord, 100, "Dump_Yellow")
|
||||
dump_count+=1
|
||||
elif x is 'R':
|
||||
map_objects[x_coord][y_coord] = generate(x)(x_coord, y_coord)
|
||||
i += 1
|
||||
|
||||
|
||||
for line in map_objects:
|
||||
for item in line:
|
||||
pygame_sprites.add(item)
|
||||
for item in line:
|
||||
pygame_sprites.add(item)
|
||||
|
||||
gc = GC(GC_X, GC_Y, 200)
|
||||
print("GC: " + str(GC_X) + str(GC_Y))
|
||||
pygame_sprites.add(gc)
|
||||
|
||||
#gc.find_houses_BestFS(map_objects)
|
||||
#pygame.quit()
|
||||
#sys.exit()
|
||||
|
||||
svmmv = {1: "up", 2: "right", 3:"down",4:"left"}
|
||||
|
||||
while True:
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
elif event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_UP:
|
||||
gc.move("up", map_objects)
|
||||
elif event.key == pygame.K_DOWN:
|
||||
gc.move("down", map_objects)
|
||||
elif event.key == pygame.K_LEFT:
|
||||
gc.move("left", map_objects)
|
||||
elif event.key == pygame.K_RIGHT:
|
||||
gc.move("right", map_objects)
|
||||
elif event.key == pygame.K_SPACE:
|
||||
gc.collect(map_objects)
|
||||
elif event.key == pygame.K_0:
|
||||
gc.find_houses(map_objects,house_count,dump_count, "DFS")
|
||||
elif event.key == pygame.K_9:
|
||||
gc.find_houses_BestFS(map_objects)
|
||||
elif event.key == pygame.K_8:
|
||||
gc.find_houses(map_objects,house_count,dump_count, "BFS")
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
elif event.type == pygame.KEYUP:
|
||||
if event.key == pygame.K_UP:
|
||||
gc.move("up", map_objects)
|
||||
elif event.key == pygame.K_DOWN:
|
||||
gc.move("down", map_objects)
|
||||
elif event.key == pygame.K_LEFT:
|
||||
gc.move("left", map_objects)
|
||||
elif event.key == pygame.K_RIGHT:
|
||||
gc.move("right", map_objects)
|
||||
elif event.key == pygame.K_SPACE:
|
||||
gc.collect(map_objects)
|
||||
elif event.key == pygame.K_0:
|
||||
gc.find_houses(map_objects,house_count,dump_count, "DFS")
|
||||
elif event.key == pygame.K_9:
|
||||
gc.find_houses_BestFS(map_objects)
|
||||
elif event.key == pygame.K_8:
|
||||
gc.find_houses(map_objects,house_count,dump_count, "BFS")
|
||||
elif event.key == pygame.K_n:
|
||||
ppp = gc.run_trained(map_objects)
|
||||
print(ppp)
|
||||
if( ppp == 99 ):
|
||||
gc.collect(map_objects)
|
||||
else:
|
||||
gc.move(svmmv[ppp], map_objects)
|
||||
|
||||
gc.make_actions_from_list(map_objects)
|
||||
pygame_sprites.update()
|
||||
pygame_sprites.draw(GAME_WINDOW)
|
||||
gc.make_actions_from_list(map_objects)
|
||||
pygame_sprites.update()
|
||||
pygame_sprites.draw(GAME_WINDOW)
|
||||
|
||||
#draw GC moves
|
||||
bg_rect = pygame.Surface((105,30), pygame.SRCALPHA)
|
||||
bg_rect.fill((0,0,0,160))
|
||||
GAME_WINDOW.blit(bg_rect, (0, WINDOW_HEIGHT-30))
|
||||
#draw GC moves
|
||||
bg_rect = pygame.Surface((105,30), pygame.SRCALPHA)
|
||||
bg_rect.fill((0,0,0,160))
|
||||
GAME_WINDOW.blit(bg_rect, (0, WINDOW_HEIGHT-30))
|
||||
|
||||
font = pygame.font.SysFont("monospace", 15)
|
||||
gc_moves = font.render("Moves: " + str(gc.get_moves_count()), 1, (255,255,255))
|
||||
GAME_WINDOW.blit(gc_moves, (10, WINDOW_HEIGHT - 25))
|
||||
font = pygame.font.SysFont("monospace", 15)
|
||||
gc_moves = font.render("Moves: " + str(gc.get_moves_count()), 1, (255,255,255))
|
||||
GAME_WINDOW.blit(gc_moves, (10, WINDOW_HEIGHT - 25))
|
||||
|
||||
pygame.display.flip()
|
||||
FPS_CLOCK.tick(FPS)
|
||||
pygame.display.flip()
|
||||
FPS_CLOCK.tick(FPS)
|
||||
|
@ -1,2 +1,4 @@
|
||||
Pillow==5.4.1
|
||||
pygame==1.9.5
|
||||
numpy
|
||||
scikit-learn
|
7
run.bat
Normal file
7
run.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
:1
|
||||
start /W WENV\Scripts\python.exe main.py
|
||||
goto 1
|
||||
|
||||
pause
|
86
utilities.py
86
utilities.py
@ -3,28 +3,66 @@ from DataModels.Road import Road
|
||||
import json, os, platform
|
||||
|
||||
def movement(environment, x ,y):
|
||||
movement = {
|
||||
"right": (x + 1, y) if x + 1 < GRID_WIDTH and type(environment[x + 1][y]) == Road else (x, y),
|
||||
"left": (x - 1, y) if x - 1 >= 0 and type(environment[x - 1][y]) == Road else (x, y),
|
||||
"down": (x, y + 1) if y + 1 < GRID_HEIGHT and type(environment[x][y + 1]) == Road else (x, y),
|
||||
"up": (x, y - 1) if y - 1 >= 0 and type(environment[x][y - 1]) == Road else (x, y)
|
||||
}
|
||||
movement = {
|
||||
"right": (x + 1, y) if x + 1 < GRID_WIDTH and type(environment[x + 1][y]) == Road else (x, y),
|
||||
"left": (x - 1, y) if x - 1 >= 0 and type(environment[x - 1][y]) == Road else (x, y),
|
||||
"down": (x, y + 1) if y + 1 < GRID_HEIGHT and type(environment[x][y + 1]) == Road else (x, y),
|
||||
"up": (x, y - 1) if y - 1 >= 0 and type(environment[x][y - 1]) == Road else (x, y)
|
||||
}
|
||||
|
||||
forbidden_movement = {
|
||||
"right": "left",
|
||||
"left": "right",
|
||||
"up": "down",
|
||||
"down": "up"
|
||||
}
|
||||
forbidden_movement = {
|
||||
"right": "left",
|
||||
"left": "right",
|
||||
"up": "down",
|
||||
"down": "up"
|
||||
}
|
||||
|
||||
return (movement, forbidden_movement)
|
||||
return (movement, forbidden_movement)
|
||||
|
||||
def check_moves(environment, x,y,direction=None):
|
||||
if direction == None:
|
||||
return ([dir for dir in movement(environment, x, y)[0] if movement(environment, x,y)[0][dir] != (x,y)])
|
||||
return ([dir for dir in movement(environment, x, y)[0] if movement(environment, x,y)[0][dir] != (x,y) and dir != movement(environment,x,y)[1][direction]])
|
||||
if direction == None:
|
||||
return ([dir for dir in movement(environment, x, y)[0] if movement(environment, x,y)[0][dir] != (x,y)])
|
||||
return ([dir for dir in movement(environment, x, y)[0] if movement(environment, x,y)[0][dir] != (x,y) and dir != movement(environment,x,y)[1][direction]])
|
||||
|
||||
def define_dir(coord1, coord2):
|
||||
if( coord1[0]-coord2[0] > 0):
|
||||
return 4
|
||||
elif( coord1[0]-coord2[0] < 0 ):
|
||||
return 2
|
||||
elif( coord1[0]-coord2[0] == 0):
|
||||
if( coord1[1]-coord2[1] > 0):
|
||||
return 1
|
||||
elif( coord1[1]-coord2[1] < 0):
|
||||
return 3
|
||||
else:
|
||||
return -1
|
||||
|
||||
def parse_coords(coords):
|
||||
|
||||
#left = 4 right = 2 up = 1 down = 3 pick_garbage = 99
|
||||
crd = list(coords)
|
||||
output = []
|
||||
|
||||
#for i in range(0,len(crd)-1):
|
||||
# while( crd[i+1] == "pick_garbage" ):
|
||||
# crd.pop(i+1)
|
||||
# output.append(99)
|
||||
# output.append(define_dir(crd[i],crd[i+1]))
|
||||
|
||||
current = crd[0]
|
||||
for i in range (1, len(crd) - 1):
|
||||
if crd[i] == "pick_garbage":
|
||||
output.append(99)
|
||||
continue
|
||||
else:
|
||||
output.append(define_dir(current, crd[i]))
|
||||
current = crd[i]
|
||||
|
||||
|
||||
return output
|
||||
|
||||
def save_moveset(moveset, maps):
|
||||
|
||||
def save_moveset(moveset):
|
||||
if platform.system() == 'Windows':
|
||||
path = '\moveset_data.json'
|
||||
else:
|
||||
@ -38,7 +76,6 @@ def save_moveset(moveset):
|
||||
open(output_file, 'a').close()
|
||||
finally:
|
||||
f = open(output_file, 'r+')
|
||||
|
||||
try:
|
||||
results = json.load(f)
|
||||
except:
|
||||
@ -47,7 +84,18 @@ def save_moveset(moveset):
|
||||
if "moveset" not in results:
|
||||
results = { "moveset": [] }
|
||||
|
||||
results["moveset"].append(moveset)
|
||||
dirs = parse_coords(moveset)
|
||||
|
||||
while(True):
|
||||
try:
|
||||
ind = dirs.index(-1)
|
||||
dirs.pop(ind)
|
||||
maps.pop(ind)
|
||||
except:
|
||||
break
|
||||
|
||||
results["moveset"].append({'maps': maps[:-2], 'moves': dirs})
|
||||
f.seek(0)
|
||||
json.dump(results, f, indent=1)
|
||||
f.close()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user