Compare commits
No commits in common. "e910041c95a16562923c81c2bf70197a2fb39c1e" and "ca8e5aac9b75bc362ad17c6ba2ba36bdfe39f51b" have entirely different histories.
e910041c95
...
ca8e5aac9b
|
@ -1,15 +1,12 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import random
|
||||||
import pygame
|
import pygame
|
||||||
import os
|
import os
|
||||||
import threading
|
|
||||||
|
|
||||||
from webapp import app
|
|
||||||
|
|
||||||
from event_server_comm import move_grid
|
from event_server_comm import move_grid
|
||||||
|
|
||||||
BLACK = np.array([0, 0, 0], dtype=np.uint8)
|
BLACK = np.array([0, 0, 0], dtype=np.uint8)
|
||||||
WHITE = np.array([255, 255, 255], dtype=np.uint8)
|
WHITE = np.array([255, 255, 255], dtype=np.uint8)
|
||||||
GRAY = np.array([200, 200, 200], dtype=np.uint8)
|
|
||||||
RED = np.array([255, 0, 0], dtype=np.uint8)
|
RED = np.array([255, 0, 0], dtype=np.uint8)
|
||||||
BLUE = np.array([0, 0, 255], dtype=np.uint8)
|
BLUE = np.array([0, 0, 255], dtype=np.uint8)
|
||||||
YELLOW = np.array([255, 255, 0], dtype=np.uint8)
|
YELLOW = np.array([255, 255, 0], dtype=np.uint8)
|
||||||
|
@ -24,28 +21,18 @@ myfont_small = pygame.font.SysFont('Comic Sans MS', 45)
|
||||||
|
|
||||||
P0_text = myfont.render('P0', False, tuple(BLACK))
|
P0_text = myfont.render('P0', False, tuple(BLACK))
|
||||||
|
|
||||||
tiledt = np.dtype([('color', np.uint8, 3), ('star', np.bool)])
|
tiledt = np.dtype([('x', np.uint8), ('y', np.uint8), ('color', np.uint8, 3), ('star', np.bool)])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
valid_colors = [GRAY, RED, BLUE]
|
valid_colors = [WHITE, RED, BLUE]
|
||||||
|
|
||||||
def __init__(self, dim_x, dim_y, n_coins=2, file=None):
|
def __init__(self, dim_x, dim_y):
|
||||||
if file is None:
|
self.tiles = np.zeros((dim_y, dim_x), dtype=tiledt)
|
||||||
self.tiles = np.zeros((dim_y, dim_x), dtype=tiledt)
|
for x in range(dim_x):
|
||||||
for x in range(dim_x):
|
for y in range(dim_y):
|
||||||
for y in range(dim_y):
|
self.tiles[y, x]['color'] = random.choice(Board.valid_colors)
|
||||||
self.tiles[y, x]['color'] = Board.valid_colors[np.random.randint(len(Board.valid_colors))]
|
|
||||||
|
|
||||||
coins_distributed = n_coins == 0
|
|
||||||
while not coins_distributed:
|
|
||||||
coinx = np.random.randint(0, dim_x)
|
|
||||||
coiny = np.random.randint(0, dim_y)
|
|
||||||
self.tiles[coiny,coinx]['star'] = True
|
|
||||||
coins_distributed = sum([t['star'] for t in self.tiles.flatten()]) == n_coins
|
|
||||||
else:
|
|
||||||
self.tiles = np.load(file)
|
|
||||||
|
|
||||||
def render(self, scale_fac):
|
def render(self, scale_fac):
|
||||||
dimy, dimx = self.tiles.shape
|
dimy, dimx = self.tiles.shape
|
||||||
|
@ -93,12 +80,11 @@ class Robot:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, x, y, orientation, use_real_robot=False):
|
def __init__(self, x, y, orientation):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.orientation = orientation
|
self.orientation = orientation
|
||||||
self.position_changed = False
|
self.position_changed = False
|
||||||
self.use_real_robot = use_real_robot
|
|
||||||
|
|
||||||
def get_forward_coordinates(self):
|
def get_forward_coordinates(self):
|
||||||
# get the coordinates of the neighboring tile in the given direction
|
# get the coordinates of the neighboring tile in the given direction
|
||||||
|
@ -126,8 +112,7 @@ class Robot:
|
||||||
return robot_surf
|
return robot_surf
|
||||||
|
|
||||||
def update_pos(self, dimx, dimy):
|
def update_pos(self, dimx, dimy):
|
||||||
if self.use_real_robot:
|
move_grid(self.x, self.y, self.orientation, dimx, dimy)
|
||||||
move_grid(self.x, self.y, self.orientation, dimx, dimy)
|
|
||||||
self.position_changed = False
|
self.position_changed = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -137,7 +122,7 @@ class Robot:
|
||||||
class Command:
|
class Command:
|
||||||
valid_actions = {'forward', 'left', 'right', 'P0', '-'}
|
valid_actions = {'forward', 'left', 'right', 'P0', '-'}
|
||||||
|
|
||||||
def __init__(self, action=None, color=GRAY):
|
def __init__(self, action=None, color=WHITE):
|
||||||
if not (action in Command.valid_actions and any([np.all(color == c) for c in Board.valid_colors])):
|
if not (action in Command.valid_actions and any([np.all(color == c) for c in Board.valid_colors])):
|
||||||
raise ValueError("invalid values for command")
|
raise ValueError("invalid values for command")
|
||||||
self.action = action
|
self.action = action
|
||||||
|
@ -172,7 +157,7 @@ class Programmer:
|
||||||
def __init__(self, prg):
|
def __init__(self, prg):
|
||||||
self.prg = prg
|
self.prg = prg
|
||||||
self.available_inputs = [Command('forward'), Command('left'), Command('right'), Command('P0'),
|
self.available_inputs = [Command('forward'), Command('left'), Command('right'), Command('P0'),
|
||||||
Command('-', color=RED), Command('-', color=BLUE), Command('-', color=GRAY)]
|
Command('-', color=RED), Command('-', color=BLUE), Command('-', color=WHITE)]
|
||||||
self.command_to_edit = 0
|
self.command_to_edit = 0
|
||||||
self.screen_rect = None
|
self.screen_rect = None
|
||||||
|
|
||||||
|
@ -210,9 +195,7 @@ class Program:
|
||||||
self.prg_counter = 0
|
self.prg_counter = 0
|
||||||
self.screen_rect = None
|
self.screen_rect = None
|
||||||
|
|
||||||
def step(self, state='running', check_victory=True):
|
def step(self, state='running'):
|
||||||
if self.prg_counter >= len(self.cmds):
|
|
||||||
return 'game_over'
|
|
||||||
cmd = self.cmds[self.prg_counter]
|
cmd = self.cmds[self.prg_counter]
|
||||||
self.prg_counter += 1
|
self.prg_counter += 1
|
||||||
|
|
||||||
|
@ -224,7 +207,7 @@ class Program:
|
||||||
tile = self.board.tiles[y, x]
|
tile = self.board.tiles[y, x]
|
||||||
|
|
||||||
# apply next instruction of the program
|
# apply next instruction of the program
|
||||||
if np.all(cmd.color == GRAY) or np.all(cmd.color == tile['color']):
|
if np.all(cmd.color == WHITE) or np.all(cmd.color == tile['color']):
|
||||||
# matching color -> execute command
|
# matching color -> execute command
|
||||||
if cmd.action == 'forward':
|
if cmd.action == 'forward':
|
||||||
ynew, xnew = self.robot.get_forward_coordinates()
|
ynew, xnew = self.robot.get_forward_coordinates()
|
||||||
|
@ -239,8 +222,7 @@ class Program:
|
||||||
elif cmd.action == 'P0':
|
elif cmd.action == 'P0':
|
||||||
self.prg_counter = 0
|
self.prg_counter = 0
|
||||||
else:
|
else:
|
||||||
#print("color not matching -> skipping command")
|
print("color not matching -> skipping command")
|
||||||
pass
|
|
||||||
|
|
||||||
# update state for new robot position
|
# update state for new robot position
|
||||||
if (not (0 <= self.robot.x < self.board.tiles.shape[1])) or not (0 <= self.robot.y < self.board.tiles.shape[0]):
|
if (not (0 <= self.robot.x < self.board.tiles.shape[1])) or not (0 <= self.robot.y < self.board.tiles.shape[0]):
|
||||||
|
@ -254,8 +236,7 @@ class Program:
|
||||||
if tile['star']:
|
if tile['star']:
|
||||||
tile['star'] = False
|
tile['star'] = False
|
||||||
|
|
||||||
if check_victory and all([not t['star'] for t in self.board.tiles.flatten()]):
|
if all([not t['star'] for t in self.board.tiles.flatten()]):
|
||||||
self.robot.update_pos(self.board.get_xdims(), self.board.get_ydims())
|
|
||||||
print("YOU WON")
|
print("YOU WON")
|
||||||
return 'won'
|
return 'won'
|
||||||
|
|
||||||
|
@ -283,7 +264,7 @@ class Program:
|
||||||
cmd_surf = cmd.render(scale_fac)
|
cmd_surf = cmd.render(scale_fac)
|
||||||
else:
|
else:
|
||||||
cmd_surf = pygame.Surface((scale_fac,scale_fac))
|
cmd_surf = pygame.Surface((scale_fac,scale_fac))
|
||||||
cmd_surf.fill(GRAY)
|
cmd_surf.fill(WHITE)
|
||||||
if prg_counter is not None and i == prg_counter:
|
if prg_counter is not None and i == prg_counter:
|
||||||
pygame.draw.rect(cmd_surf, tuple(GREEN), (0, 0, scale_fac, scale_fac), 5)
|
pygame.draw.rect(cmd_surf, tuple(GREEN), (0, 0, scale_fac, scale_fac), 5)
|
||||||
prg_surf.blit(cmd_surf, (i * scale_fac, 0, scale_fac, scale_fac))
|
prg_surf.blit(cmd_surf, (i * scale_fac, 0, scale_fac, scale_fac))
|
||||||
|
@ -299,14 +280,17 @@ class Program:
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, dimx, dimy, robotx, roboty, orientation, use_real_robot=False):
|
def __init__(self, dimx, dimy, robotx, roboty):
|
||||||
self.robot = Robot(x=robotx, y=roboty, orientation=orientation, use_real_robot=use_real_robot)
|
self.robot = Robot(x=robotx, y=roboty, orientation='v')
|
||||||
#self.board = Board(dimx, dimy)
|
self.board = Board(dimx, dimy)
|
||||||
self.board = Board(dimx, dimy, file='levels/56.npy')
|
coin1x = np.random.randint(0, dimx)
|
||||||
|
coin1y = np.random.randint(0, dimy)
|
||||||
|
self.board.tiles[coin1y,coin1x]['star'] = True
|
||||||
|
self.board.tiles[3,2]['star'] = True
|
||||||
|
|
||||||
# TODO fix number of commands at 5
|
# TODO fix number of commands at 5
|
||||||
self.cmds = [Command('forward'), Command('left', color=RED), Command('left', color=BLUE), Command('P0'), Command('-')]
|
self.cmds = [Command('forward'), Command('left', color=RED), Command('left', color=BLUE), Command('P0'), Command('-')]
|
||||||
self.state = 'reset'
|
self.state = 'won'
|
||||||
|
|
||||||
self.prg = Program(self.robot, self.board, self.cmds)
|
self.prg = Program(self.robot, self.board, self.cmds)
|
||||||
|
|
||||||
|
@ -318,17 +302,15 @@ class Game:
|
||||||
self.screen = pygame.display.set_mode((int(self.board.tiles.shape[1] * self.scale_fac * 1.1),
|
self.screen = pygame.display.set_mode((int(self.board.tiles.shape[1] * self.scale_fac * 1.1),
|
||||||
int((self.board.tiles.shape[0] + 2) * self.scale_fac * 1.2)))
|
int((self.board.tiles.shape[0] + 2) * self.scale_fac * 1.2)))
|
||||||
|
|
||||||
self.game_over_text = myfont.render('GAME OVER', False, WHITE)
|
self.game_over_text = myfont.render('GAME OVER', False, BLACK)
|
||||||
self.won_text = myfont.render('YOU WON', False, BLACK)
|
self.won_text = myfont.render('YOU WON', False, BLACK)
|
||||||
self.run_text = myfont.render('RUN', False, tuple(BLACK))
|
self.run_text = myfont.render('RUN', False, tuple(BLACK))
|
||||||
self.stop_text = myfont_small.render('STOP', False, tuple(BLACK))
|
self.stop_text = myfont_small.render('STOP', False, tuple(BLACK))
|
||||||
self.step_text = myfont_small.render('STEP', False, tuple(BLACK))
|
self.step_text = myfont_small.render('STEP', False, tuple(BLACK))
|
||||||
self.prg_text = myfont_small.render('CURRENT PROGRAM', False, tuple(GREEN))
|
|
||||||
|
|
||||||
|
|
||||||
# save initial state
|
# save initial state
|
||||||
self.initial_pos = (self.robot.x, self.robot.y, self.robot.orientation)
|
self.initial_pos = (self.robot.x, self.robot.y, self.robot.orientation)
|
||||||
self.initial_board_tiles = self.board.tiles.copy()
|
self.inital_board_tiles = self.board.tiles.copy()
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
"""Render the game screen.
|
"""Render the game screen.
|
||||||
|
@ -340,7 +322,7 @@ class Game:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if self.beamer_mode:
|
if self.beamer_mode:
|
||||||
dx = self.xoffset
|
dx = 0
|
||||||
dy = 0
|
dy = 0
|
||||||
else:
|
else:
|
||||||
dx = int(0.05 * self.screen.get_width())
|
dx = int(0.05 * self.screen.get_width())
|
||||||
|
@ -355,69 +337,57 @@ class Game:
|
||||||
board_surf.blit(robot_surf, (self.robot.x * self.scale_fac, self.robot.y * self.scale_fac, self.scale_fac, self.scale_fac))
|
board_surf.blit(robot_surf, (self.robot.x * self.scale_fac, self.robot.y * self.scale_fac, self.scale_fac, self.scale_fac))
|
||||||
self.screen.blit(board_surf, (dx, dy, dx + self.board.tiles.shape[1] * self.scale_fac, dy + self.board.tiles.shape[0] * self.scale_fac))
|
self.screen.blit(board_surf, (dx, dy, dx + self.board.tiles.shape[1] * self.scale_fac, dy + self.board.tiles.shape[0] * self.scale_fac))
|
||||||
|
|
||||||
# render program
|
|
||||||
if self.state == 'input':
|
|
||||||
# in input mode we highlight the command which is selected for edit
|
|
||||||
prg_surf = self.prg.render(self.scale_fac, prg_counter_override=self.programmer.command_to_edit)
|
|
||||||
else:
|
|
||||||
# in other modes we render the current program counter
|
|
||||||
prg_surf = self.prg.render(self.scale_fac)
|
|
||||||
prg_surf = pygame.transform.scale(prg_surf, (self.screen.get_width() * 2 // 3, self.scale_fac * 2 // 3))
|
|
||||||
self.prg.screen_rect = pygame.Rect(
|
|
||||||
(dx, board_surf.get_height() + 2 * dy, prg_surf.get_width(), prg_surf.get_height()))
|
|
||||||
# render input fields and buttons
|
|
||||||
inp_surf = self.programmer.render(self.scale_fac)
|
|
||||||
inp_surf = pygame.transform.scale(inp_surf, (self.screen.get_width() * 2 // 3, self.scale_fac * 2 // 3))
|
|
||||||
self.programmer.screen_rect = pygame.Rect(
|
|
||||||
(dx, board_surf.get_height() + prg_surf.get_height() + 3 * dy, inp_surf.get_width(), inp_surf.get_height()))
|
|
||||||
btn_surf = pygame.Surface((3 * self.scale_fac // 2, self.scale_fac))
|
|
||||||
self.btn_rect = pygame.Rect((2 * dx + prg_surf.get_width(), board_surf.get_height() + 2 * dy,
|
|
||||||
btn_surf.get_height(), btn_surf.get_width()))
|
|
||||||
if self.state == 'input':
|
|
||||||
btn_surf.fill(tuple(GREEN))
|
|
||||||
btn_surf.blit(self.run_text, (0, 10))
|
|
||||||
elif self.state == 'running':
|
|
||||||
btn_surf.fill(tuple(RED))
|
|
||||||
btn_surf.blit(self.stop_text, (0, 10))
|
|
||||||
elif self.state == 'stepping':
|
|
||||||
btn_surf.fill(tuple(YELLOW))
|
|
||||||
btn_surf.blit(self.step_text, (0, 10))
|
|
||||||
|
|
||||||
if not self.beamer_mode:
|
if not self.beamer_mode:
|
||||||
# if we are not in beamer mode we render program and inputs below the board
|
# if we are not in beamer mode we also show the current program / inputs
|
||||||
|
|
||||||
|
# render program
|
||||||
|
if self.state == 'input':
|
||||||
|
# in input mode we highlight the command which is selected for edit
|
||||||
|
prg_surf = self.prg.render(self.scale_fac, prg_counter_override=self.programmer.command_to_edit)
|
||||||
|
else:
|
||||||
|
# in other modes we render the current program counter
|
||||||
|
prg_surf = self.prg.render(self.scale_fac)
|
||||||
|
prg_surf = pygame.transform.scale(prg_surf, (self.screen.get_width() * 2 // 3, self.scale_fac * 2 // 3))
|
||||||
|
self.prg.screen_rect = pygame.Rect((dx, board_surf.get_height() + 2 * dy, prg_surf.get_width(), prg_surf.get_height()))
|
||||||
self.screen.blit(prg_surf, self.prg.screen_rect)
|
self.screen.blit(prg_surf, self.prg.screen_rect)
|
||||||
|
|
||||||
|
# render input fields and buttons
|
||||||
|
inp_surf = self.programmer.render(self.scale_fac)
|
||||||
|
inp_surf = pygame.transform.scale(inp_surf, (self.screen.get_width() * 2 // 3, self.scale_fac * 2 // 3))
|
||||||
|
self.programmer.screen_rect = pygame.Rect((dx, board_surf.get_height() + prg_surf.get_height() + 3 * dy, inp_surf.get_width(), inp_surf.get_height()))
|
||||||
self.screen.blit(inp_surf, self.programmer.screen_rect)
|
self.screen.blit(inp_surf, self.programmer.screen_rect)
|
||||||
|
|
||||||
|
btn_surf = pygame.Surface((3 * self.scale_fac//2, self.scale_fac))
|
||||||
|
self.btn_rect = pygame.Rect((2 * dx + prg_surf.get_width(), board_surf.get_height() + 2 * dy,
|
||||||
|
btn_surf.get_height(), btn_surf.get_width()))
|
||||||
|
if self.state == 'input':
|
||||||
|
btn_surf.fill(tuple(GREEN))
|
||||||
|
btn_surf.blit(self.run_text, (0, 10))
|
||||||
|
elif self.state == 'running':
|
||||||
|
btn_surf.fill(tuple(RED))
|
||||||
|
btn_surf.blit(self.stop_text, (0, 10))
|
||||||
|
elif self.state == 'stepping':
|
||||||
|
btn_surf.fill(tuple(YELLOW))
|
||||||
|
btn_surf.blit(self.step_text, (0, 10))
|
||||||
self.screen.blit(btn_surf, self.btn_rect)
|
self.screen.blit(btn_surf, self.btn_rect)
|
||||||
else:
|
|
||||||
prg_surf = pygame.transform.scale(prg_surf, (dx, dx//5))
|
|
||||||
# in beamer mode we render the program to the left of the board to appear on the laptop
|
|
||||||
self.screen.blit(prg_surf, (0,100))
|
|
||||||
|
|
||||||
prg_descr_surb = pygame.Surface((500, 100))
|
|
||||||
#prg_descr_surb.blit(self.prg_text)
|
|
||||||
self.screen.blit(self.prg_text, (50, 50))
|
|
||||||
mode_text = myfont_small.render(f'STATE: {self.state}', False, tuple(GREEN))
|
|
||||||
self.screen.blit(mode_text, (50, dx//5 + 350))
|
|
||||||
|
|
||||||
# render messages
|
# render messages
|
||||||
if self.state == 'game_over':
|
if self.state == 'game_over':
|
||||||
game_over_surf = pygame.Surface(((self.screen.get_width() - dx) // 2, self.screen.get_height() // 2))
|
game_over_surf = pygame.Surface((self.screen.get_width() // 2, self.screen.get_height() // 2))
|
||||||
game_over_surf.fill(tuple(BLACK))
|
game_over_surf.fill(tuple(GREEN))
|
||||||
game_over_surf.blit(self.game_over_text, ((game_over_surf.get_width() - self.game_over_text.get_width()) // 2,
|
game_over_surf.blit(self.game_over_text, ((game_over_surf.get_width() - self.game_over_text.get_width()) // 2,
|
||||||
(game_over_surf.get_height() - self.game_over_text.get_height()) // 2))
|
(game_over_surf.get_height() - self.game_over_text.get_height()) // 2))
|
||||||
self.screen.blit(game_over_surf, (dx + (self.screen.get_width() - dx) // 4, self.screen.get_height() // 4))
|
self.screen.blit(game_over_surf, (self.screen.get_width() // 4, self.screen.get_height() // 4))
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
pygame.time.wait(1500)
|
pygame.time.wait(1500)
|
||||||
self.state = 'reset'
|
self.state = 'reset'
|
||||||
elif self.state == 'won':
|
elif self.state == 'won':
|
||||||
won_surf = pygame.Surface(((self.screen.get_width() - dx) // 2, self.screen.get_height() // 2))
|
won_surf = pygame.Surface((self.screen.get_width() // 2, self.screen.get_height() // 2))
|
||||||
won_surf.fill(tuple(WHITE))
|
won_surf.fill(tuple(GREEN))
|
||||||
won_surf.blit(self.won_text,
|
won_surf.blit(self.won_text,
|
||||||
((won_surf.get_width() - self.won_text.get_width()) // 2,
|
((won_surf.get_width() - self.won_text.get_width()) // 2,
|
||||||
(won_surf.get_height() - self.won_text.get_height()) // 2))
|
(won_surf.get_height() - self.won_text.get_height()) // 2))
|
||||||
self.screen.blit(won_surf, (dx + (self.screen.get_width() - dx) // 4, self.screen.get_height() // 4))
|
self.screen.blit(won_surf, (self.screen.get_width() // 4, self.screen.get_height() // 4))
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
pygame.time.wait(1500)
|
pygame.time.wait(1500)
|
||||||
self.state = 'reset'
|
self.state = 'reset'
|
||||||
|
@ -457,10 +427,9 @@ class Game:
|
||||||
if event.key == pygame.K_x:
|
if event.key == pygame.K_x:
|
||||||
if not self.beamer_mode:
|
if not self.beamer_mode:
|
||||||
# switch to beamer mode
|
# switch to beamer mode
|
||||||
self.xoffset = 1000
|
os.environ['SDL_VIDEO_WINDOW_POS'] = '1920, 280'
|
||||||
os.environ['SDL_VIDEO_WINDOW_POS'] = f'{1920-self.xoffset}, 280'
|
|
||||||
self.scale_fac = 180
|
self.scale_fac = 180
|
||||||
self.screen = pygame.display.set_mode((self.xoffset + self.board.tiles.shape[1] * self.scale_fac,
|
self.screen = pygame.display.set_mode((self.board.tiles.shape[1] * self.scale_fac,
|
||||||
self.board.tiles.shape[0] * self.scale_fac),
|
self.board.tiles.shape[0] * self.scale_fac),
|
||||||
pygame.NOFRAME)
|
pygame.NOFRAME)
|
||||||
self.beamer_mode = True
|
self.beamer_mode = True
|
||||||
|
@ -481,15 +450,6 @@ class Game:
|
||||||
self.state = self.prg.step(self.state)
|
self.state = self.prg.step(self.state)
|
||||||
elif event.key == pygame.K_r:
|
elif event.key == pygame.K_r:
|
||||||
self.state = 'reset'
|
self.state = 'reset'
|
||||||
elif event.key == pygame.K_n:
|
|
||||||
self.initial_board_tiles = Board(self.board.get_xdims(), self.board.get_ydims()).tiles.copy()
|
|
||||||
self.state = 'reset'
|
|
||||||
elif event.type == pygame.USEREVENT:
|
|
||||||
for i, cmd in enumerate(event.cmds):
|
|
||||||
self.cmds[i].action = cmd.action
|
|
||||||
self.cmds[i].color = np.array(cmd.color, dtype=np.uint8)
|
|
||||||
self.reset()
|
|
||||||
self.state = 'running'
|
|
||||||
return self.state
|
return self.state
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
@ -498,7 +458,7 @@ class Game:
|
||||||
self.robot.y = self.initial_pos[1]
|
self.robot.y = self.initial_pos[1]
|
||||||
self.robot.orientation = self.initial_pos[2]
|
self.robot.orientation = self.initial_pos[2]
|
||||||
self.robot.update_pos(self.board.get_xdims(), self.board.get_ydims())
|
self.robot.update_pos(self.board.get_xdims(), self.board.get_ydims())
|
||||||
self.board.tiles = self.initial_board_tiles.copy()
|
self.board.tiles = self.inital_board_tiles.copy()
|
||||||
return 'input'
|
return 'input'
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -528,13 +488,10 @@ class Game:
|
||||||
pygame.time.wait(100)
|
pygame.time.wait(100)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# launch webapp in thread
|
seed = 2
|
||||||
webserver_thread = threading.Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000})
|
random.seed(seed)
|
||||||
webserver_thread.start()
|
|
||||||
|
|
||||||
seed = 4
|
|
||||||
np.random.seed(seed)
|
np.random.seed(seed)
|
||||||
game = Game(dimx=7, dimy=4, robotx=5, roboty=1, orientation='>', use_real_robot=False)
|
game = Game(dimx=7, dimy=4, robotx=3, roboty=1)
|
||||||
game.run()
|
game.run()
|
||||||
|
|
||||||
# TODOs
|
# TODOs
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
from gauss_turing import Program, Board, Command, Robot
|
|
||||||
import numpy as np
|
|
||||||
import json
|
|
||||||
|
|
||||||
levels = {
|
|
||||||
0: lambda cmds: len(cmds) <= 3,
|
|
||||||
1: lambda cmds: len(cmds) == 3
|
|
||||||
}
|
|
||||||
|
|
||||||
def rate_level(robot_path, cmds, board):
|
|
||||||
path_length = len(set(robot_path))
|
|
||||||
n_cmds = len(cmds)
|
|
||||||
n_cmd_colors = len(set([tuple(c.color) for c in cmds]))
|
|
||||||
|
|
||||||
difficulty = (path_length - 1) * (n_cmds + n_cmd_colors)
|
|
||||||
|
|
||||||
# place coins on the robot path to create a solution
|
|
||||||
if difficulty > 0:
|
|
||||||
n_coins = np.random.randint(1, min(path_length, 5)) - 1
|
|
||||||
|
|
||||||
# put one coin on last tile visited
|
|
||||||
coins = [robot_path[-1]]
|
|
||||||
|
|
||||||
# distribute other coins randomly on the path
|
|
||||||
# path without first and list tile
|
|
||||||
unique_tiles = list(set(robot_path) - {robot_path[-1]} - {robot_path[0]})
|
|
||||||
|
|
||||||
for _ in range(n_coins):
|
|
||||||
c = np.random.randint(0, len(unique_tiles))
|
|
||||||
new_coin = unique_tiles.pop(c)
|
|
||||||
coins.append(new_coin)
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
coins = []
|
|
||||||
|
|
||||||
return difficulty, coins
|
|
||||||
|
|
||||||
def generate_level(dimx, dimy, max_steps=100):
|
|
||||||
n_cmds = np.random.randint(2, 6)
|
|
||||||
assert n_cmds <= 5
|
|
||||||
|
|
||||||
# generate random board without any coins
|
|
||||||
board = Board(dimx, dimy, n_coins=0)
|
|
||||||
|
|
||||||
cmds = []
|
|
||||||
actions = list(sorted(Command.valid_actions - {'-'}))
|
|
||||||
# generate random commands
|
|
||||||
for i in range(n_cmds):
|
|
||||||
action = np.random.choice(actions)
|
|
||||||
color = Board.valid_colors[np.random.randint(len(Board.valid_colors))]
|
|
||||||
cmds.append(Command(action, color))
|
|
||||||
|
|
||||||
# generate robot at random position
|
|
||||||
rx = np.random.randint(0, dimx-1)
|
|
||||||
ry = np.random.randint(0, dimy-1)
|
|
||||||
orientation = np.random.choice(['>','v','<','^'])
|
|
||||||
r = Robot(rx, ry, orientation)
|
|
||||||
|
|
||||||
prg = Program(r, board, cmds)
|
|
||||||
continue_running = True
|
|
||||||
state = 'running'
|
|
||||||
prg_counter_old = prg.prg_counter
|
|
||||||
|
|
||||||
robot_path = [(r.x, r.y)]
|
|
||||||
step = 0
|
|
||||||
|
|
||||||
while continue_running and step < max_steps:
|
|
||||||
#print(f"prg_counter = {prg.prg_counter} - robot: {r} - state: {state}")
|
|
||||||
state = prg.step(state, check_victory=False)
|
|
||||||
|
|
||||||
robot_path.append((r.x, r.y))
|
|
||||||
|
|
||||||
stuck = prg.prg_counter == prg_counter_old
|
|
||||||
|
|
||||||
prg_counter_old = prg.prg_counter
|
|
||||||
|
|
||||||
if state == 'game_over' or stuck:
|
|
||||||
continue_running = False
|
|
||||||
|
|
||||||
step += 1
|
|
||||||
|
|
||||||
last_pos = robot_path[-1]
|
|
||||||
if not ((0 <= last_pos[0] < dimx) and (0 <= last_pos[1] < dimy)):
|
|
||||||
# remove last entry of path if robot leaves the board
|
|
||||||
robot_path.pop(-1)
|
|
||||||
|
|
||||||
difficulty, coins = rate_level(robot_path, cmds, board)
|
|
||||||
|
|
||||||
# put coins on the board
|
|
||||||
for coin in coins:
|
|
||||||
board.tiles[coin[1], coin[0]]['star'] = True
|
|
||||||
n_coins = len(coins)
|
|
||||||
|
|
||||||
|
|
||||||
return difficulty, board, n_coins, set(robot_path), (rx, ry, orientation), cmds
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
np.random.seed(2)
|
|
||||||
|
|
||||||
levels = {}
|
|
||||||
|
|
||||||
for i in range(100):
|
|
||||||
diff, board, n_coins, robot_path, init_robot_pos, solution = generate_level(7, 4)
|
|
||||||
if diff > 0:
|
|
||||||
print("difficulty: ", diff, "n_coins: ", n_coins, "path length: ", len(robot_path))
|
|
||||||
if diff in levels:
|
|
||||||
if n_coins > levels[diff]['n_coins'] and len(robot_path) > levels[diff]['path_length']:
|
|
||||||
levels[diff] = {'board': board, 'init_robot_pos': init_robot_pos, 'solution': solution,
|
|
||||||
'n_coins': n_coins, 'path_length': len(robot_path)}
|
|
||||||
else:
|
|
||||||
levels[diff] = {'board': board, 'init_robot_pos': init_robot_pos, 'solution': solution,
|
|
||||||
'n_coins': n_coins, 'path_length': len(robot_path)}
|
|
||||||
|
|
||||||
level_info = {}
|
|
||||||
for l, data in levels.items():
|
|
||||||
np.save(f'levels/{l}.npy', data['board'].tiles)
|
|
||||||
sol = [(cmd.action, tuple(map(int, cmd.color))) for cmd in data['solution']]
|
|
||||||
level_info[l] = {'init_robot_pos': data['init_robot_pos'], 'solution': sol,
|
|
||||||
'n_coins': int(data['n_coins']), 'path_length': int(data['path_length']),
|
|
||||||
'file': f'levels/{l}.npy'}
|
|
||||||
|
|
||||||
with open('levels/level_info.json', 'w') as f:
|
|
||||||
json.dump(level_info, f, indent=4)
|
|
||||||
pass
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB |
|
@ -1,61 +0,0 @@
|
||||||
.cmd-canvas {
|
|
||||||
outline: 3px solid #dddddd;;
|
|
||||||
width: 430px;
|
|
||||||
height: 120px;
|
|
||||||
margin: 50px auto 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.programmer-canvas {
|
|
||||||
outline: 3px solid #dddddd;;
|
|
||||||
width: 338px;
|
|
||||||
height: 220px;
|
|
||||||
margin: 50px auto 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.register {
|
|
||||||
outline: 3px dashed #dddddd;;
|
|
||||||
width: 120px;
|
|
||||||
height: 240px;
|
|
||||||
margin: 0px auto 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box{
|
|
||||||
width: 62px;
|
|
||||||
height: 100px;
|
|
||||||
position: absolute !important;
|
|
||||||
top: 100px;
|
|
||||||
font-size: 15px;
|
|
||||||
color: #000000;
|
|
||||||
line-height: 25px;
|
|
||||||
text-align: center;
|
|
||||||
cursor: move;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-buffer { margin-top:20px; }
|
|
||||||
|
|
||||||
.center {
|
|
||||||
margin: 20px;
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
-ms-transform: translateX(-50%, -50%);
|
|
||||||
transform: translateX(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cmd0 { left: 0; top: 0; background-color: #E74C3C; position: absolute !important;}
|
|
||||||
.cmd1 { left: 92px; top: 0; background-color: #8E44AD; position: absolute !important;}
|
|
||||||
.cmd2 { left: 184px; top: 0; background-color: #5DADE2; }
|
|
||||||
.cmd3 { left: 276px; top: 0; background-color: #1ABC9C; }
|
|
||||||
.cmd4 { left: 368px; top: 0; background-color: #F1C40F; }
|
|
||||||
|
|
||||||
.programmer_cmd0 { left: 0; top: 0; background-color: #E74C3C; position: absolute !important;}
|
|
||||||
.programmer_cmd1 { left: 92px; top: 0; background-color: #8E44AD; position: absolute !important;}
|
|
||||||
.programmer_cmd2 { left: 184px; top: 0; background-color: #5DADE2; }
|
|
||||||
.programmer_cmd3 { left: 276px; top: 0; background-color: #1ABC9C; }
|
|
||||||
.programmer_cmd4 { left: 38px; top: 120px; background-color: #F1C40F; }
|
|
||||||
.programmer_cmd5 { left: 138px; top: 120px; background-color: #F39C12; }
|
|
||||||
.programmer_cmd6 { right: 38px; top: 120px; background-color: #34495E; }
|
|
||||||
|
|
||||||
.card_hidden { background-color: #dddddd; }
|
|
|
@ -1,136 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
||||||
<title>imaginaerraum.de</title>
|
|
||||||
|
|
||||||
<script src="static/jquery-3.5.1.js"></script>
|
|
||||||
<script src="static/jquery-ui.min.js"></script>
|
|
||||||
<script src="static/bootstrap.min.js"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="static/bootstrap.css">
|
|
||||||
<link rel="stylesheet" href="static/style.css">
|
|
||||||
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- container -->
|
|
||||||
<div class="container">
|
|
||||||
<!-- current program -->
|
|
||||||
<div class="row top-buffer">
|
|
||||||
Aktuelles Programm:
|
|
||||||
<div class="cmd-canvas">
|
|
||||||
{% for cmd in current_program %}
|
|
||||||
<div class="box cmd{{ loop.index0 }}" id="prg_cmd{{ loop.index0 }}" data-action="{{ cmd.action }}" data-color="{{ cmd.color }}" data-img="prg_cmd_img{{ loop.index0 }}"
|
|
||||||
style="background-color: rgba({{ cmd.color[0] }},{{ cmd.color[1] }},{{ cmd.color[2] }},0.85)">
|
|
||||||
<img id="prg_cmd_img{{ loop.index0 }}" src="static/{{ cmd.action }}.png">
|
|
||||||
{{ loop.index0 }}
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- possible commands -->
|
|
||||||
<div class="row top-buffer">
|
|
||||||
Mögliche Befehle:
|
|
||||||
<div class="programmer-canvas">
|
|
||||||
{% for cmd in valid_commands %}
|
|
||||||
<div class="box programmer_cmd{{ loop.index0 }}" id="valid_cmd{{ loop.index0 }}" data-action="{{ cmd.action }}"
|
|
||||||
data-color="{{ cmd.color }}" data-img="valid_cmd_img{{ loop.index0 }}"
|
|
||||||
style="background-color: rgba({{ cmd.color[0] }},{{ cmd.color[1] }},{{ cmd.color[2] }},0.85)">
|
|
||||||
<img id="valid_cmd_img{{ loop.index0 }}" src="static/{{ cmd.action }}.png">
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row top-buffer center">
|
|
||||||
<div class="col-sm">
|
|
||||||
<input class="btn btn-primary" id="btnSubmit" type="submit" value="Befehle abschicken" />
|
|
||||||
</div>
|
|
||||||
<div class="col-sm">
|
|
||||||
<div id = "alert_placeholder"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div><!-- container -->
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
|
|
||||||
var please_wait = $(".notification").hide();
|
|
||||||
|
|
||||||
var box = $(".box");
|
|
||||||
|
|
||||||
bootstrap_alert = function() {};
|
|
||||||
bootstrap_alert.warning = function(message) {
|
|
||||||
$('#alert_placeholder').html('<div class="alert alert-primary"><a class="close" data-dismiss="alert">×</a><span>'+message+'</span></div>')
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$("#btnSubmit").click(function () {
|
|
||||||
//alert("button");
|
|
||||||
var cmds = {
|
|
||||||
{% for i in range(5) %}
|
|
||||||
"cmd{{ i }}": {"color": document.getElementById("prg_cmd{{ i }}").getAttribute("data-color"),
|
|
||||||
"action": document.getElementById("prg_cmd{{ i }}").getAttribute("data-action")},
|
|
||||||
{% endfor %}
|
|
||||||
}
|
|
||||||
//bootstrap_alert.warning('Bitte warten bis alle Spieler ihre Aktion gewählt haben!'); //$(please_wait).show();
|
|
||||||
var cmds_json = JSON.stringify(cmds);
|
|
||||||
|
|
||||||
$.post("/send_cmds", {"cmds_json": cmds_json}, function (data) {
|
|
||||||
console.log(data);
|
|
||||||
/*
|
|
||||||
if (data === 'OK') {
|
|
||||||
location.reload(); // reload page to get new cards for next round
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log('waiting...')
|
|
||||||
$.get("/send_cmds", "", function (data) {
|
|
||||||
if (data === 'OK') {
|
|
||||||
location.reload(); // reload page to get new cards for next round
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
var edited_command = null;
|
|
||||||
|
|
||||||
box.click(function () {
|
|
||||||
//debugger
|
|
||||||
if ( this.id.includes('prg_cmd') ) {
|
|
||||||
// program card clicked -> select clicked card for editing
|
|
||||||
edited_command = this;
|
|
||||||
}
|
|
||||||
else if (this.id.includes('valid_cmd')) {
|
|
||||||
// progamming card clicked -> edit currently selected card
|
|
||||||
var this_card_action = this.getAttribute('data-action');
|
|
||||||
var this_card_color = this.getAttribute('data-color');
|
|
||||||
if (!!edited_command) { // only if there is a card selected
|
|
||||||
console.log("editing command " + edited_command);
|
|
||||||
if (this_card_action === "-") {
|
|
||||||
// set color
|
|
||||||
edited_command.setAttribute("data-color", this_card_color);
|
|
||||||
edited_command.style["backgroundColor"] = this.style["backgroundColor"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// set action
|
|
||||||
edited_command.setAttribute("data-action", this_card_action)
|
|
||||||
var edited_cmd_img = document.getElementById(edited_command.getAttribute("data-img"));
|
|
||||||
var prg_img = document.getElementById(this.getAttribute("data-img"));
|
|
||||||
edited_cmd_img.src = prg_img.src;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,163 +0,0 @@
|
||||||
from flask import Flask, render_template, request, session, make_response
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import numpy as np
|
|
||||||
from playsound import playsound
|
|
||||||
from itertools import zip_longest
|
|
||||||
import random
|
|
||||||
import json
|
|
||||||
import pygame
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
app.secret_key = b'RoboRallyRolling'
|
|
||||||
|
|
||||||
probabilities = [0.21428571428571427, 0.14285714285714285, 0.07142857142857142, 0.07142857142857142,
|
|
||||||
0.21428571428571427, 0.21428571428571427, 0.07142857142857142]
|
|
||||||
|
|
||||||
#deck = roborally.CardDeck()
|
|
||||||
|
|
||||||
class Cmd:
|
|
||||||
possible_moves = ['forward', 'left', 'right', 'P0']
|
|
||||||
possible_colors = [(200,200,200), (255, 0, 0), (0,0,255)]
|
|
||||||
|
|
||||||
def __init__(self, action, color):
|
|
||||||
self.action = action
|
|
||||||
self.color = color
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "Cmd No. " + self.action
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return self.action + " " + str(self.color)
|
|
||||||
|
|
||||||
|
|
||||||
available_robots = {
|
|
||||||
0: {'id': 11, 'ip': '192.168.1.11', 'x': 1, 'y': 2, 'orientation': '>'},
|
|
||||||
1: {'id': 12, 'ip': '192.168.1.12', 'x': 3, 'y': 3, 'orientation': '>'}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
players = {}
|
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
|
||||||
MAX_PLAYERS = 4
|
|
||||||
player_counter = 0
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if Player.player_counter < Player.MAX_PLAYERS:
|
|
||||||
self.id = Player.player_counter
|
|
||||||
Player.player_counter += 1
|
|
||||||
|
|
||||||
self.max_cards = 9
|
|
||||||
|
|
||||||
self.player_hand = deck.draw_cards(self.max_cards)
|
|
||||||
print("current hand: ", [str(c) for c in self.player_hand])
|
|
||||||
|
|
||||||
self.action_count = 5
|
|
||||||
self.action_chosen = False
|
|
||||||
|
|
||||||
self.initialize_robot()
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("max players reached!")
|
|
||||||
|
|
||||||
def initialize_robot(self):
|
|
||||||
x = available_robots[self.id]['x']
|
|
||||||
y = available_robots[self.id]['y']
|
|
||||||
marker_id = available_robots[self.id]['id']
|
|
||||||
ip = available_robots[self.id]['ip']
|
|
||||||
orientation = available_robots[self.id]['orientation']
|
|
||||||
self.robot = game.board.create_robot(x, y, orientation, self.id, marker_id)
|
|
||||||
|
|
||||||
if game.comm_socket is not None:
|
|
||||||
cmd = f"initialize_robot, {marker_id}, {ip}, {x-1}, {y-1}, {orientation}\n"
|
|
||||||
game.comm_socket.sendall(cmd.encode())
|
|
||||||
data = game.comm_socket.recv(32)
|
|
||||||
|
|
||||||
if data.decode() == 'OK\n':
|
|
||||||
print("robot sucessfully initialized!")
|
|
||||||
else:
|
|
||||||
print("error: could not initialize robot!")
|
|
||||||
self.robot = None
|
|
||||||
|
|
||||||
def draw_new_cards(self):
|
|
||||||
self.player_hand += deck.draw_cards(self.max_cards - len(self.player_hand))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/send_cmds', methods=['POST', 'GET'])
|
|
||||||
def send_cmds():
|
|
||||||
if request.method == 'POST':
|
|
||||||
cmds = json.loads(request.form['cmds_json'])
|
|
||||||
|
|
||||||
cmd_list = []
|
|
||||||
for cmd_nr in [f"cmd{i}" for i in range(5)]:
|
|
||||||
cmd = cmds[cmd_nr]
|
|
||||||
action = cmd['action']
|
|
||||||
color_str = cmd['color']
|
|
||||||
color_str = color_str.strip("()").split(",")
|
|
||||||
color = tuple(map(int, color_str))
|
|
||||||
cmd_list.append(Cmd(action, color))
|
|
||||||
print("got commands: ", cmd_list)
|
|
||||||
ev = pygame.event.Event(pygame.USEREVENT, {'cmds': cmd_list})
|
|
||||||
pygame.event.post(ev)
|
|
||||||
|
|
||||||
# send commands to the game
|
|
||||||
|
|
||||||
# if game.ready():
|
|
||||||
# game.process_actions()
|
|
||||||
#
|
|
||||||
# return 'OK'
|
|
||||||
# else:
|
|
||||||
# return 'please wait'
|
|
||||||
return "OK"
|
|
||||||
elif request.method == 'GET':
|
|
||||||
# GET is used when we have to wait for other players to finish
|
|
||||||
while not game.processing_done: # wait for other players to choose commands and processing to finish
|
|
||||||
pass
|
|
||||||
|
|
||||||
return 'OK'
|
|
||||||
|
|
||||||
WHITE = (255, 255, 255)
|
|
||||||
GRAY = (200, 200, 200)
|
|
||||||
RED = (255, 0, 0)
|
|
||||||
BLUE = (0, 0, 255)
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
|
||||||
def hello_world():
|
|
||||||
prg = [Cmd('forward', GRAY), Cmd('left', GRAY), Cmd('right', BLUE),
|
|
||||||
Cmd('P0', GRAY), Cmd('right', RED)]
|
|
||||||
valid_cmds = [Cmd('forward', WHITE), Cmd('right', WHITE), Cmd('left', WHITE),
|
|
||||||
Cmd('P0', WHITE), Cmd('-', RED), Cmd('-', BLUE), Cmd('-', GRAY)]
|
|
||||||
|
|
||||||
if request.method == 'GET':
|
|
||||||
robot_info = None
|
|
||||||
return render_template('drag_example.html', current_program=prg, valid_commands=valid_cmds, robot_info=robot_info)
|
|
||||||
elif request.method == 'POST':
|
|
||||||
# print(request.form)
|
|
||||||
|
|
||||||
if request.form.get('drag') and request.form.get('drop'):
|
|
||||||
# swap cards in the current hand
|
|
||||||
i1 = int(request.form.get('drag')) # number of first card
|
|
||||||
i2 = int(request.form.get('drop')) # number of second card
|
|
||||||
|
|
||||||
card1 = deck.deck[i1] # get card by number
|
|
||||||
card2 = deck.deck[i2]
|
|
||||||
|
|
||||||
print("swapping {} and {}".format(card1, card2))
|
|
||||||
|
|
||||||
j1 = player_hand.index(card1) # get index of card in the hand
|
|
||||||
j2 = player_hand.index(card2)
|
|
||||||
|
|
||||||
player_hand[j1], player_hand[j2] = player_hand[j2], player_hand[j1] # swap the cards in the list
|
|
||||||
|
|
||||||
# print("current hand: ", [str(c) for c in player_hand[player_id]])
|
|
||||||
|
|
||||||
return 'OK'
|
|
||||||
else:
|
|
||||||
return render_template('drag_example.html', cmds=player_hand, player_id=player_id)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
#app.run(host='192.168.1.222', port=5000)
|
|
||||||
app.run(host='0.0.0.0', port=5000)
|
|
|
@ -140,7 +140,7 @@ class ArucoEstimator:
|
||||||
{'name': 'Draw grid', 'type': 'bool', 'value': self.draw_grid, 'tip': "Draw grid spanned by the markers 0 - 3"},
|
{'name': 'Draw grid', 'type': 'bool', 'value': self.draw_grid, 'tip': "Draw grid spanned by the markers 0 - 3"},
|
||||||
{'name': 'Grid columns', 'type': 'int', 'value': self.grid_columns, 'tip': "Number of columns for the grid"},
|
{'name': 'Grid columns', 'type': 'int', 'value': self.grid_columns, 'tip': "Number of columns for the grid"},
|
||||||
{'name': 'Grid rows', 'type': 'int', 'value': self.grid_rows, 'tip': "Number of rows for the grid"},
|
{'name': 'Grid rows', 'type': 'int', 'value': self.grid_rows, 'tip': "Number of rows for the grid"},
|
||||||
{'name': 'Display mode', 'type': 'list', 'values': ['color', 'grayscale'], 'value': 'grayscale', 'tip': "Display mode for the video"},
|
{'name': 'Display mode', 'type': 'list', 'values': ['color', 'grayscale'], 'value': 'color', 'tip': "Display mode for the video"},
|
||||||
{'name': 'Autoexposure', 'type': 'bool', 'value': True},
|
{'name': 'Autoexposure', 'type': 'bool', 'value': True},
|
||||||
{'name': 'Controlled robot', 'type': 'list', 'values': self.robot_marker_ids, 'tip': 'Robot to control'},
|
{'name': 'Controlled robot', 'type': 'list', 'values': self.robot_marker_ids, 'tip': 'Robot to control'},
|
||||||
RobotMarkerGroup(name="Robot markers", children=robot_marker_group),
|
RobotMarkerGroup(name="Robot markers", children=robot_marker_group),
|
||||||
|
@ -569,4 +569,4 @@ if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
QtGui.QApplication.instance().exec_()
|
QtGui.QApplication.instance().exec_()
|
Loading…
Reference in New Issue
Block a user