Оновити 'main.py'

This commit is contained in:
Serhii Hromov 2020-05-11 14:21:53 +00:00
parent e7347a0062
commit 66040a6456

212
main.py
View File

@ -10,7 +10,7 @@ import numpy as np
pygame.init() pygame.init()
#ai settings # ai settings
S_IDLE = ("kitchen", "middle", "inplace") S_IDLE = ("kitchen", "middle", "inplace")
S_FIRST = ("order", "food") S_FIRST = ("order", "food")
@ -21,12 +21,11 @@ HEIGHT = 10
WIDTH = 10 WIDTH = 10
KITCHEN = (1, 1) KITCHEN = (1, 1)
MIDDLE = (floor(WIDTH/2), floor(HEIGHT/2)) MIDDLE = (floor(WIDTH / 2), floor(HEIGHT / 2))
display = pygame.display.set_mode((WIDTH * 32 + 200, HEIGHT * 32))
display = pygame.display.set_mode((WIDTH*32+200, HEIGHT*32)) # eating time
#eating time
EAT_TIME = 15 EAT_TIME = 15
#### Menu #### Menu
@ -38,6 +37,14 @@ menu = Context.fromstring(''' |meat|salad|meal|drink|cold|hot |
Pizza | | | X | | | X |''') Pizza | | | X | | | X |''')
#menu.lattice.graphviz()
#Digraph.render('Lattice.gv', view=True)
#print(menu.extension(['meal',]))
###
#genetic algos #genetic algos
gen_num = 20 #generations gen_num = 20 #generations
gen_sol = 6 #solutions gen_sol = 6 #solutions
@ -46,6 +53,7 @@ gen_par_mating = 2 #how many solutions we select
mut_per_gen = 10 mut_per_gen = 10
mut_num_gen = None mut_num_gen = None
par_selc_type = "tournament"
crossover = "two_points" crossover = "two_points"
muta_type = "scramble" muta_type = "scramble"
par_keep = 1 #keep only one parent par_keep = 1 #keep only one parent
@ -54,12 +62,12 @@ init_range_l = -2 #low
init_range_h = -5 #high init_range_h = -5 #high
func_input = ['meal'] func_input = ['meal']
func_output = [] right_output = []
for e in menu.extension(['meal',]): for e in menu.extension(['meal',]):
func_output.append(e) right_output.append(e)
def fittnes_f(sol): def fitness_f(sol):
output = 0 output = 0
if sol in menu.extension([sol],): if sol in menu.extension([sol],):
output = 0.5 output = 0.5
@ -67,7 +75,27 @@ def fittnes_f(sol):
fitness = 1.0 / np.abs(output - r_out) fitness = 1.0 / np.abs(output - r_out)
return fitness return fitness
#### ga_inst = pygad.GA(num_generations=gen_num,
sol_per_pop=gen_sol,
num_parents_mating=gen_par_mating,
num_genes=len(func_input),
fitness_func=fitness_f,
mutation_percent_genes=mut_per_gen,
mutation_num_genes=mut_num_gen,
init_range_low=init_range_l,
init_range_high=init_range_l,
parent_selection_type=par_selc_type,
crossover_type=crossover,
mutation_type=muta_type,
keep_parents=par_keep,
K_tournament=4)
#ga_inst.run()
#ga_inst.plot_result()
#print(func_output)
###
class Tile: class Tile:
def __init__(self, x, y, canwalk, table, kitchen): def __init__(self, x, y, canwalk, table, kitchen):
self.x = x self.x = x
@ -80,6 +108,8 @@ class Tile:
self.visited = False self.visited = False
self.path = False self.path = False
self.parent = (0, 0) self.parent = (0, 0)
class Restaurant: class Restaurant:
def __init__(self, tables, clients): def __init__(self, tables, clients):
self.h = HEIGHT self.h = HEIGHT
@ -92,32 +122,33 @@ class Restaurant:
for ih in range(HEIGHT): for ih in range(HEIGHT):
new = [] new = []
for iw in range(WIDTH): for iw in range(WIDTH):
if ih == 0 or ih == HEIGHT-1 or iw == 0 or iw == WIDTH-1: if ih == 0 or ih == HEIGHT - 1 or iw == 0 or iw == WIDTH - 1:
new.append(Tile(ih, iw, False, False, False)) new.append(Tile(ih, iw, False, False, False))
else: else:
new.append(Tile(ih, iw, True, False, False)) new.append(Tile(ih, iw, True, False, False))
self.tiles.append(new) self.tiles.append(new)
#random walls # random walls
for i in range(3): for i in range(3):
w = random.randint(1,2) w = random.randint(1, 2)
h = random.randint(4,HEIGHT-5) h = random.randint(4, HEIGHT - 5)
for j in range(random.randint(1,3)): for j in range(random.randint(1, 3)):
ad = self.adjacent(w, h) ad = self.adjacent(w, h)
t = random.choice(ad) t = random.choice(ad)
w = t.x w = t.x
h = t.y h = t.y
self.tiles[w][h].canwalk = False self.tiles[w][h].canwalk = False
#random tables # random tables
i = 0 i = 0
while i < tables: while i < tables:
w = random.randint(2,WIDTH-3) w = random.randint(2, WIDTH - 3)
h = random.randint(2,HEIGHT-3) h = random.randint(2, HEIGHT - 3)
if not self.tiles[h][w].table and self.tiles[h][w].canwalk: if not self.tiles[h][w].table and self.tiles[h][w].canwalk:
self.tiles[h][w].table = True self.tiles[h][w].table = True
i = i + 1 i = i + 1
self.tables.append((w, h)) self.tables.append((w, h))
self.tiles[1][1].kitchen = True self.tiles[1][1].kitchen = True
def putClient(self): def putClient(self):
for t in self.tables: for t in self.tables:
if not self.tiles[t[1]][t[0]].clientState: if not self.tiles[t[1]][t[0]].clientState:
@ -130,25 +161,26 @@ class Restaurant:
for ih in range(HEIGHT): for ih in range(HEIGHT):
for iw in range(WIDTH): for iw in range(WIDTH):
self.tiles[ih][iw].visited = False self.tiles[ih][iw].visited = False
self.tiles[ih][iw].parent = (0,0) self.tiles[ih][iw].parent = (0, 0)
def adjacent(self, x, y): def adjacent(self, x, y):
tiles = [] tiles = []
if x == 0 or y == 0 or x == WIDTH or y == HEIGHT: if x == 0 or y == 0 or x == WIDTH or y == HEIGHT:
tiles.append(self.tiles[y][x]) tiles.append(self.tiles[y][x])
return tiles return tiles
tiles.append(self.tiles[y][x-1]) tiles.append(self.tiles[y][x - 1])
tiles.append(self.tiles[y-1][x]) tiles.append(self.tiles[y - 1][x])
tiles.append(self.tiles[y+1][x]) tiles.append(self.tiles[y + 1][x])
tiles.append(self.tiles[y][x+1]) tiles.append(self.tiles[y][x + 1])
return tiles return tiles
def heuristic(a, b): def heuristic(a, b):
(x1, y1) = a (x1, y1) = a
(x2, y2) = b (x2, y2) = b
return abs(x1 - x2) + abs(y1 - y2) return abs(x1 - x2) + abs(y1 - y2)
class Agent: class Agent:
def __init__(self, x, y): def __init__(self, x, y):
self.x = x self.x = x
@ -157,12 +189,14 @@ class Agent:
self.idle = True self.idle = True
self.orders = [] self.orders = []
self.food = False self.food = False
def walk(self): def walk(self):
t = self.path.pop(0) t = self.path.pop(0)
self.x = t[0] self.x = t[0]
self.y = t[1] self.y = t[1]
if not self.path: if not self.path:
self.idle = True self.idle = True
def BFS(self, goal): def BFS(self, goal):
restaurant.flush() restaurant.flush()
queue = [(self.x, self.y)] queue = [(self.x, self.y)]
@ -179,10 +213,12 @@ class Agent:
x = item.x x = item.x
y = item.y y = item.y
if restaurant.tiles[y][x].canwalk and not restaurant.tiles[y][x].visited: if restaurant.tiles[y][x].canwalk and not restaurant.tiles[y][x].visited:
queue.append((x,y)) queue.append((x, y))
restaurant.tiles[y][x].parent = n restaurant.tiles[y][x].parent = n
def wait(self): def wait(self):
self.idle = True self.idle = True
def getTask(self): def getTask(self):
if waiter.orders: if waiter.orders:
self.BFS(KITCHEN) self.BFS(KITCHEN)
@ -214,91 +250,91 @@ class Agent:
return True return True
return False return False
def drawScreen(): def drawScreen():
pygame.draw.rect(display,(0,0,0), (0, 0, HEIGHT*32, WIDTH*32)) pygame.draw.rect(display, (0, 0, 0), (0, 0, HEIGHT * 32, WIDTH * 32))
for ih in range(HEIGHT): for ih in range(HEIGHT):
for iw in range(WIDTH): for iw in range(WIDTH):
tile = restaurant.tiles[ih][iw] tile = restaurant.tiles[ih][iw]
if tile.canwalk: if tile.canwalk:
pygame.draw.rect(display, (128,128,128), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (128, 128, 128), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
if tile.table: if tile.table:
if tile.clientState: if tile.clientState:
if tile.clientState == "decide": if tile.clientState == "decide":
pygame.draw.rect(display, (0,128,0), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (0, 128, 0), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
elif tile.clientState == "order": elif tile.clientState == "order":
pygame.draw.rect(display, (0,255,0), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (0, 255, 0), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
elif tile.clientState == "wait": elif tile.clientState == "wait":
pygame.draw.rect(display, (255,128,0), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (255, 128, 0), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
elif tile.clientState == "eat": elif tile.clientState == "eat":
pygame.draw.rect(display, (128,64,0), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (128, 64, 0), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
else: else:
pygame.draw.rect(display, (64,64,64), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (64, 64, 64), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
if tile.kitchen: if tile.kitchen:
pygame.draw.rect(display, (255,0,255), (iw * 32 + 1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (255, 0, 255), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
#if tile.visited: # if tile.visited:
# pygame.draw.rect(display, (64,0,64), (iw * 32 + 1, ih * 32+1, 14, 14)) # pygame.draw.rect(display, (64,0,64), (iw * 32 + 1, ih * 32+1, 14, 14))
else: else:
pygame.draw.rect(display, (128,0,128), (iw * 32+1, ih * 32+1, 32-1, 32-1)) pygame.draw.rect(display, (128, 0, 128), (iw * 32 + 1, ih * 32 + 1, 32 - 1, 32 - 1))
pygame.draw.circle(display, (255,255,255), (waiter.x*32+16, waiter.y*32+16), 16) pygame.draw.circle(display, (255, 255, 255), (waiter.x * 32 + 16, waiter.y * 32 + 16), 16)
textsurface = font.render(str(restaurant.clients), False, (255,255,255)) textsurface = font.render(str(restaurant.clients), False, (255, 255, 255))
display.blit(textsurface, (WIDTH*32 + 80, 300)) display.blit(textsurface, (WIDTH * 32 + 80, 300))
pygame.draw.rect(display,(0,0,0), (WIDTH*32+80, 332, HEIGHT*32, WIDTH*32)) pygame.draw.rect(display, (0, 0, 0), (WIDTH * 32 + 80, 332, HEIGHT * 32, WIDTH * 32))
textsurface = font.render(str(ticks), False, (255,255,255)) textsurface = font.render(str(ticks), False, (255, 255, 255))
display.blit(textsurface, (WIDTH*32 + 80, 332)) display.blit(textsurface, (WIDTH * 32 + 80, 332))
restaurant = Restaurant(3, 5) restaurant = Restaurant(3, 5)
waiter = Agent(2,2) waiter = Agent(2, 2)
clientTime = 10 clientTime = 10
totaltime = 0 totaltime = 0
clock = pygame.time.Clock() clock = pygame.time.Clock()
ticks = 0 ticks = 0
#draw info # draw info
help = True help = True
if help: if help:
font = pygame.font.SysFont('Arial', 18) font = pygame.font.SysFont('Arial', 18)
textsurface = font.render("kelner", False, (255,255,255)) textsurface = font.render("kelner", False, (255, 255, 255))
pygame.draw.circle(display, (255,255,255), (WIDTH*32 + 26, 16), 16) pygame.draw.circle(display, (255, 255, 255), (WIDTH * 32 + 26, 16), 16)
display.blit(textsurface, (WIDTH*32 + 50, 0)) display.blit(textsurface, (WIDTH * 32 + 50, 0))
textsurface = font.render("sciana", False, (255,255,255)) textsurface = font.render("sciana", False, (255, 255, 255))
pygame.draw.rect(display, (128,0,128), (WIDTH*32 + 10, 32, 32-1, 32-1)) pygame.draw.rect(display, (128, 0, 128), (WIDTH * 32 + 10, 32, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 32)) display.blit(textsurface, (WIDTH * 32 + 50, 32))
textsurface = font.render("stolik - pusty", False, (255,255,255)) textsurface = font.render("stolik - pusty", False, (255, 255, 255))
pygame.draw.rect(display, (64,64,64), (WIDTH*32 + 10, 64, 32-1, 32-1)) pygame.draw.rect(display, (64, 64, 64), (WIDTH * 32 + 10, 64, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 64)) display.blit(textsurface, (WIDTH * 32 + 50, 64))
textsurface = font.render("stolik - decyduje", False, (255,255,255)) textsurface = font.render("stolik - decyduje", False, (255, 255, 255))
pygame.draw.rect(display, (0,128,0), (WIDTH*32 + 10, 96, 32-1, 32-1)) pygame.draw.rect(display, (0, 128, 0), (WIDTH * 32 + 10, 96, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 96)) display.blit(textsurface, (WIDTH * 32 + 50, 96))
textsurface = font.render("stolik - zamawia", False, (255,255,255)) textsurface = font.render("stolik - zamawia", False, (255, 255, 255))
pygame.draw.rect(display, (0,255,0), (WIDTH*32 + 10, 128, 32-1, 32-1)) pygame.draw.rect(display, (0, 255, 0), (WIDTH * 32 + 10, 128, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 128)) display.blit(textsurface, (WIDTH * 32 + 50, 128))
textsurface = font.render("stolik - czeka", False, (255,255,255)) textsurface = font.render("stolik - czeka", False, (255, 255, 255))
pygame.draw.rect(display, (255,128,0), (WIDTH*32 + 10, 160, 32-1, 32-1)) pygame.draw.rect(display, (255, 128, 0), (WIDTH * 32 + 10, 160, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 160)) display.blit(textsurface, (WIDTH * 32 + 50, 160))
textsurface = font.render("stolik - je", False, (255,255,255)) textsurface = font.render("stolik - je", False, (255, 255, 255))
pygame.draw.rect(display, (128,64,0), (WIDTH*32 + 10, 192, 32-1, 32-1)) pygame.draw.rect(display, (128, 64, 0), (WIDTH * 32 + 10, 192, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 192)) display.blit(textsurface, (WIDTH * 32 + 50, 192))
textsurface = font.render("kuchnia", False, (255,255,255)) textsurface = font.render("kuchnia", False, (255, 255, 255))
pygame.draw.rect(display, (255,0,255), (WIDTH*32 + 10, 224, 32-1, 32-1)) pygame.draw.rect(display, (255, 0, 255), (WIDTH * 32 + 10, 224, 32 - 1, 32 - 1))
display.blit(textsurface, (WIDTH*32 + 50, 224)) display.blit(textsurface, (WIDTH * 32 + 50, 224))
textsurface = font.render("klienci:", False, (255,255,255)) textsurface = font.render("klienci:", False, (255, 255, 255))
display.blit(textsurface, (WIDTH*32 + 20, 300)) display.blit(textsurface, (WIDTH * 32 + 20, 300))
textsurface = font.render("czas:", False, (255,255,255)) textsurface = font.render("czas:", False, (255, 255, 255))
display.blit(textsurface, (WIDTH*32 + 20, 332)) display.blit(textsurface, (WIDTH * 32 + 20, 332))
while True: while True:
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.KEYDOWN: if event.type == pygame.KEYDOWN:
if event.key == pygame.K_F4: if event.key == pygame.K_F4:
pygame.quit() pygame.quit()
if event.key == pygame.K_F5: if event.key == pygame.K_F5:
restaurant = Restaurant(3, 5) restaurant = Restaurant(3, 5)
waiter = Agent(2,2) waiter = Agent(2, 2)
clientTime = 10 clientTime = 10
ticks = 0 ticks = 0
totaltime = 0 totaltime = 0
@ -307,28 +343,27 @@ while True:
waiter.BFS(t) waiter.BFS(t)
if event.key == pygame.K_w: if event.key == pygame.K_w:
waiter.walk() waiter.walk()
#update restaurant # update restaurant
if restaurant.clients > 0: if restaurant.clients > 0:
clientTime = clientTime - 1 clientTime = clientTime - 1
if clientTime == 0: if clientTime == 0:
clientTime = 10 clientTime = 10
restaurant.putClient() restaurant.putClient()
for t in restaurant.kitchen: for t in restaurant.kitchen:
if t[2]> 0: if t[2] > 0:
t[2] = t[2] - 1 t[2] = t[2] - 1
# update tables
#update tables
for table in restaurant.tables: for table in restaurant.tables:
if restaurant.tiles[table[1]][table[0]].clientState: if restaurant.tiles[table[1]][table[0]].clientState:
if restaurant.tiles[table[1]][table[0]].clientState == "decide": if restaurant.tiles[table[1]][table[0]].clientState == "decide":
restaurant.tiles[table[1]][table[0]].client = restaurant.tiles[table[1]][table[0]].client - 1 restaurant.tiles[table[1]][table[0]].client = restaurant.tiles[table[1]][table[0]].client - 1
if restaurant.tiles[table[1]][table[0]].client == 0: if restaurant.tiles[table[1]][table[0]].client == 0:
restaurant.tiles[table[1]][table[0]].clientState = "order" restaurant.tiles[table[1]][table[0]].clientState = "order"
elif restaurant.tiles[table[1]][table[0]].clientState == "eat": elif restaurant.tiles[table[1]][table[0]].clientState == "eat":
restaurant.tiles[table[1]][table[0]].client = restaurant.tiles[table[1]][table[0]].client - 1 restaurant.tiles[table[1]][table[0]].client = restaurant.tiles[table[1]][table[0]].client - 1
if restaurant.tiles[table[1]][table[0]].client == 0: if restaurant.tiles[table[1]][table[0]].client == 0:
restaurant.tiles[table[1]][table[0]].clientState = False restaurant.tiles[table[1]][table[0]].clientState = False
totaltime = totaltime + ticks totaltime = totaltime + ticks
restaurant.left = restaurant.left - 1 restaurant.left = restaurant.left - 1
if restaurant.left == 0: if restaurant.left == 0:
@ -345,15 +380,14 @@ while True:
file.write(str(1)) file.write(str(1))
file.close() file.close()
restaurant = Restaurant(3, 5) restaurant = Restaurant(3, 5)
waiter = Agent(2,2) waiter = Agent(2, 2)
clientTime = 10 clientTime = 10
ticks = 0 ticks = 0
totaltime = 0 totaltime = 0
IDLE = random.choice(S_IDLE) IDLE = random.choice(S_IDLE)
FIRST = random.choice(S_FIRST) FIRST = random.choice(S_FIRST)
#update waiter # update waiter
if waiter.idle: if waiter.idle:
if not waiter.getTask(): if not waiter.getTask():
if not waiter.path: if not waiter.path:
@ -386,10 +420,10 @@ while True:
restaurant.tiles[waiter.y][waiter.x].clientState = "eat" restaurant.tiles[waiter.y][waiter.x].clientState = "eat"
restaurant.tiles[waiter.y][waiter.x].client = 30 restaurant.tiles[waiter.y][waiter.x].client = 30
waiter.food = False waiter.food = False
if ticks > 1500: if ticks > 1500:
restaurant = Restaurant(3, 5) restaurant = Restaurant(3, 5)
waiter = Agent(2,2) waiter = Agent(2, 2)
clientTime = 10 clientTime = 10
ticks = 0 ticks = 0
totaltime = 0 totaltime = 0