296 lines
7.8 KiB
Python
296 lines
7.8 KiB
Python
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, 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.housesC = []
|
|
self.old_time = pygame.time.get_ticks()
|
|
self.initial_position = [[x, y]]
|
|
self.run_training()
|
|
|
|
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 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')
|
|
|
|
#self.clf = tree.DecisionTreeClassifier()
|
|
f = open('moveset_data.json','r')
|
|
datas = json.load(f)
|
|
|
|
X = []
|
|
y = []
|
|
|
|
for x in range(0,len(datas['moveset'])):
|
|
X += (datas['moveset'][x]['maps'])
|
|
|
|
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)
|
|
|
|
|
|
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()
|
|
|
|
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(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 = []
|
|
|
|
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)
|