forked from Telos4/RoboRally
connected game to web server
This commit is contained in:
parent
ca8e5aac9b
commit
e669b10ebc
|
@ -2,11 +2,15 @@ import numpy as np
|
||||||
import random
|
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)
|
||||||
|
@ -26,7 +30,7 @@ tiledt = np.dtype([('x', np.uint8), ('y', np.uint8), ('color', np.uint8, 3), ('s
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
valid_colors = [WHITE, RED, BLUE]
|
valid_colors = [GRAY, RED, BLUE]
|
||||||
|
|
||||||
def __init__(self, dim_x, dim_y):
|
def __init__(self, dim_x, dim_y):
|
||||||
self.tiles = np.zeros((dim_y, dim_x), dtype=tiledt)
|
self.tiles = np.zeros((dim_y, dim_x), dtype=tiledt)
|
||||||
|
@ -80,11 +84,12 @@ class Robot:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, x, y, orientation):
|
def __init__(self, x, y, orientation, use_real_robot=False):
|
||||||
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
|
||||||
|
@ -112,7 +117,8 @@ class Robot:
|
||||||
return robot_surf
|
return robot_surf
|
||||||
|
|
||||||
def update_pos(self, dimx, dimy):
|
def update_pos(self, dimx, dimy):
|
||||||
move_grid(self.x, self.y, self.orientation, dimx, dimy)
|
if self.use_real_robot:
|
||||||
|
move_grid(self.x, self.y, self.orientation, dimx, dimy)
|
||||||
self.position_changed = False
|
self.position_changed = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -122,7 +128,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=WHITE):
|
def __init__(self, action=None, color=GRAY):
|
||||||
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
|
||||||
|
@ -157,7 +163,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=WHITE)]
|
Command('-', color=RED), Command('-', color=BLUE), Command('-', color=GRAY)]
|
||||||
self.command_to_edit = 0
|
self.command_to_edit = 0
|
||||||
self.screen_rect = None
|
self.screen_rect = None
|
||||||
|
|
||||||
|
@ -196,6 +202,8 @@ class Program:
|
||||||
self.screen_rect = None
|
self.screen_rect = None
|
||||||
|
|
||||||
def step(self, state='running'):
|
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
|
||||||
|
|
||||||
|
@ -207,7 +215,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 == WHITE) or np.all(cmd.color == tile['color']):
|
if np.all(cmd.color == GRAY) 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()
|
||||||
|
@ -264,7 +272,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(WHITE)
|
cmd_surf.fill(GRAY)
|
||||||
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))
|
||||||
|
@ -280,8 +288,8 @@ class Program:
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, dimx, dimy, robotx, roboty):
|
def __init__(self, dimx, dimy, robotx, roboty, use_real_robot=False):
|
||||||
self.robot = Robot(x=robotx, y=roboty, orientation='v')
|
self.robot = Robot(x=robotx, y=roboty, orientation='v', use_real_robot=use_real_robot)
|
||||||
self.board = Board(dimx, dimy)
|
self.board = Board(dimx, dimy)
|
||||||
coin1x = np.random.randint(0, dimx)
|
coin1x = np.random.randint(0, dimx)
|
||||||
coin1y = np.random.randint(0, dimy)
|
coin1y = np.random.randint(0, dimy)
|
||||||
|
@ -290,7 +298,7 @@ class Game:
|
||||||
|
|
||||||
# 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 = 'won'
|
self.state = 'reset'
|
||||||
|
|
||||||
self.prg = Program(self.robot, self.board, self.cmds)
|
self.prg = Program(self.robot, self.board, self.cmds)
|
||||||
|
|
||||||
|
@ -450,6 +458,12 @@ 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.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):
|
||||||
|
@ -488,10 +502,14 @@ class Game:
|
||||||
pygame.time.wait(100)
|
pygame.time.wait(100)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
# launch webapp in thread
|
||||||
|
webserver_thread = threading.Thread(target=app.run, kwargs={'host': '0.0.0.0', 'port': 5000})
|
||||||
|
webserver_thread.start()
|
||||||
|
|
||||||
seed = 2
|
seed = 2
|
||||||
random.seed(seed)
|
random.seed(seed)
|
||||||
np.random.seed(seed)
|
np.random.seed(seed)
|
||||||
game = Game(dimx=7, dimy=4, robotx=3, roboty=1)
|
game = Game(dimx=7, dimy=4, robotx=3, roboty=1, use_real_robot=False)
|
||||||
game.run()
|
game.run()
|
||||||
|
|
||||||
# TODOs
|
# TODOs
|
||||||
|
|
BIN
gauss-turing/game/static/-.png
Normal file
BIN
gauss-turing/game/static/-.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
gauss-turing/game/static/P0.png
Normal file
BIN
gauss-turing/game/static/P0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
gauss-turing/game/static/forward.png
Normal file
BIN
gauss-turing/game/static/forward.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 846 B |
BIN
gauss-turing/game/static/left.png
Normal file
BIN
gauss-turing/game/static/left.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
gauss-turing/game/static/right.png
Normal file
BIN
gauss-turing/game/static/right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
105
gauss-turing/game/static/style.css
Normal file
105
gauss-turing/game/static/style.css
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
.main-canvas {
|
||||||
|
outline: 1px solid #dddddd;;
|
||||||
|
width: 500px;
|
||||||
|
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: #ffffff;
|
||||||
|
line-height: 25px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
.robotOrientation {
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.robotOrientation90 {
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
-moz-transform: rotate(90deg);
|
||||||
|
-o-transform: rotate(90deg);
|
||||||
|
-ms-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.robotOrientation180 {
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
-moz-transform: rotate(180deg);
|
||||||
|
-o-transform: rotate(180deg);
|
||||||
|
-ms-transform: rotate(180deg);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.robotOrientation270 {
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
-webkit-transform: rotate(270deg);
|
||||||
|
-moz-transform: rotate(270deg);
|
||||||
|
-o-transform: rotate(270deg);
|
||||||
|
-ms-transform: rotate(270deg);
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate90 {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
-moz-transform: rotate(90deg);
|
||||||
|
-o-transform: rotate(90deg);
|
||||||
|
-ms-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate180 {
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
-moz-transform: rotate(180deg);
|
||||||
|
-o-transform: rotate(180deg);
|
||||||
|
-ms-transform: rotate(180deg);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate270 {
|
||||||
|
-webkit-transform: rotate(270deg);
|
||||||
|
-moz-transform: rotate(270deg);
|
||||||
|
-o-transform: rotate(270deg);
|
||||||
|
-ms-transform: rotate(270deg);
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-buffer { margin-top:20px; }
|
||||||
|
|
||||||
|
|
||||||
|
.card0 { left: 0; top: 0; background-color: #E74C3C; position: absolute !important;
|
||||||
|
}
|
||||||
|
.card1 { left: 100px; top: 0; background-color: #8E44AD; position: absolute !important;
|
||||||
|
}
|
||||||
|
.card2 { left: 200px; top: 0; background-color: #5DADE2; }
|
||||||
|
.card3 { left: 300px; top: 0; background-color: #1ABC9C; }
|
||||||
|
.card4 { left: 400px; top: 0; background-color: #F1C40F; }
|
||||||
|
.card5 { left: 50px; top: 120px; background-color: #F39C12; }
|
||||||
|
.card6 { left: 150px; top: 120px; background-color: #34495E; }
|
||||||
|
.card7 { left: 250px; top: 120px; background-color: #FF00FF; }
|
||||||
|
.card8 { left: 350px; top: 120px; background-color: #008080; }
|
||||||
|
|
||||||
|
.card_hidden { background-color: #dddddd; }
|
287
gauss-turing/game/templates/drag_example.html
Normal file
287
gauss-turing/game/templates/drag_example.html
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
<!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>Drag</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="main-canvas">
|
||||||
|
{% for cmd in current_program %}
|
||||||
|
<div class="box card{{ 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="main-canvas">
|
||||||
|
{% for cmd in valid_commands %}
|
||||||
|
<div class="box card{{ 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">
|
||||||
|
{% if robot_info is none %}
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="inputRobotX">X Position:</label>
|
||||||
|
<input class="form-control" type="number" id="inputRobotX" name="robot_x" min="1" max="13" value="1">
|
||||||
|
<br>
|
||||||
|
<label for="inputRobotY">Y Position:</label>
|
||||||
|
<input class="form-control" type="number" id="inputRobotY" name="robot_y" min="1" max="7" value="1">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="orientation">Blickrichtung:</label><br>
|
||||||
|
<img id="orientation" class="robotOrientation" src="/static/orientation.png" alt="0">
|
||||||
|
<input hidden id="inputRobotOrientation" value=">" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="inputRobotID">Roboter ID:</label>
|
||||||
|
<select name="robotID" class="form-control" id="inputRobotID">
|
||||||
|
<option value="11">11</option>
|
||||||
|
<option value="12">12</option>
|
||||||
|
<option value="13">13</option>
|
||||||
|
<option value="14">14</option>
|
||||||
|
</select>
|
||||||
|
<label for="outputRobotFlags">Flaggen:</label><br>
|
||||||
|
{% for f in ['a', 'b', 'c', 'd'] %}
|
||||||
|
<input type="checkbox" class="form-check-input" id="flag_{{ f }}" onclick="return false;">
|
||||||
|
<label class="form-check-label" for="flag_{{ f }}">{{ f }}</label><br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="outputRobotX">X Position:</label>
|
||||||
|
<input class="form-control" type="number" id="outputRobotX" name="robot_x" min="1" max="12" value="{{ robot_info[0] }}" readonly>
|
||||||
|
<br>
|
||||||
|
<label for="outputRobotY">Y Position:</label>
|
||||||
|
<input class="form-control" type="number" id="outputRobotY" name="robot_y" min="1" max="6" value="{{ robot_info[1] }}" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="outputOrientation">Blickrichtung:</label><br>
|
||||||
|
{% if robot_info[2] == '>' %}
|
||||||
|
<img id="outputOrientation" class="robotOrientation" src="/static/orientation.png" alt="0">
|
||||||
|
{% elif robot_info[2] == 'v' %}
|
||||||
|
<img id="outputOrientation" class="robotOrientation90" src="/static/orientation.png" alt="0">
|
||||||
|
{% elif robot_info[2] == '<' %}
|
||||||
|
<img id="outputOrientation" class="robotOrientation180" src="/static/orientation.png" alt="0">
|
||||||
|
{% elif robot_info[2] == '^' %}
|
||||||
|
<img id="outputOrientation" class="robotOrientation270" src="/static/orientation.png" alt="0">
|
||||||
|
{% endif %}
|
||||||
|
<br>
|
||||||
|
<label for="outputRobotDmg">Schaden:</label><br>
|
||||||
|
<input class="form-control" name="robotDmg" id="outputRobotDmg" value="{{ robot_info[4] }}" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm">
|
||||||
|
<label for="outputRobotID">Roboter ID:</label>
|
||||||
|
<input class="form-control" name="robotID" id="outputRobotID" value="{{ robot_info[3] }}" readonly>
|
||||||
|
<label for="outputRobotFlags">Flaggen:</label><br>
|
||||||
|
{% for f in ['a', 'b', 'c', 'd'] %}
|
||||||
|
{% if f in robot_info[5] %}
|
||||||
|
<input type="checkbox" class="form-check-input" id="flag_{{ f }}" checked onclick="return false;">
|
||||||
|
{% else %}
|
||||||
|
<input type="checkbox" class="form-check-input" id="flag_{{ f }}" onclick="return false;">
|
||||||
|
{% endif %}
|
||||||
|
<label class="form-check-label" for="flag_{{ f }}">{{ f }}</label><br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
<div class="row top-buffer">
|
||||||
|
<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 class="row top-buffer">
|
||||||
|
Viel Spaß beim Spielen!
|
||||||
|
</div>
|
||||||
|
</div><!-- container -->
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
|
||||||
|
var please_wait = $(".notification").hide();
|
||||||
|
|
||||||
|
var box = $(".box");
|
||||||
|
var mainCanvas = $(".main-canvas");
|
||||||
|
|
||||||
|
var orientation_icon = $("#orientation");
|
||||||
|
var orientation_input = $("#inputRobotOrientation");
|
||||||
|
|
||||||
|
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>')
|
||||||
|
};
|
||||||
|
|
||||||
|
orientation_icon.click(function () {
|
||||||
|
if (this.alt === "0") {
|
||||||
|
this.alt = "90";
|
||||||
|
$("#inputRobotOrientation").val("v");
|
||||||
|
//document.getElementById("inputRobotOrientation").value = "v";
|
||||||
|
}
|
||||||
|
else if (this.alt === "90") {
|
||||||
|
this.alt = "180";
|
||||||
|
$("#inputRobotOrientation").val("<");
|
||||||
|
//document.getElementById("inputRobotOrientation").value = "<";
|
||||||
|
}
|
||||||
|
else if (this.alt === "180") {
|
||||||
|
this.alt = "270";
|
||||||
|
$("#inputRobotOrientation").val("^");
|
||||||
|
//document.getElementById("inputRobotOrientation").value = "^";
|
||||||
|
}
|
||||||
|
else if (this.alt === "270") {
|
||||||
|
this.alt = "0";
|
||||||
|
$("#inputRobotOrientation").val(">");
|
||||||
|
//document.getElementById("inputRobotOrientation").value = ">";
|
||||||
|
}
|
||||||
|
$(this).css({'transform' : 'rotate('+ this.alt +'deg)'});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
box.draggable({
|
||||||
|
containment: mainCanvas,
|
||||||
|
helper: "clone",
|
||||||
|
|
||||||
|
start: function () {
|
||||||
|
$(this).css({
|
||||||
|
opacity: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".box").css("z-index", "0");
|
||||||
|
},
|
||||||
|
|
||||||
|
stop: function () {
|
||||||
|
$(this).css({
|
||||||
|
opacity: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
box.droppable({
|
||||||
|
accept: box,
|
||||||
|
|
||||||
|
drop: function (event, ui) {
|
||||||
|
var draggable = ui.draggable;
|
||||||
|
var droppable = $(this);
|
||||||
|
var dragPos = draggable.position();
|
||||||
|
var dropPos = droppable.position();
|
||||||
|
|
||||||
|
var cmds = [ui.draggable.attr('name').toString(), $(this).attr('name')]
|
||||||
|
|
||||||
|
//console.log(dragPos);
|
||||||
|
//console.log(dropPos);
|
||||||
|
|
||||||
|
//console.log($(cmds));
|
||||||
|
// notify server that cards have been swapped
|
||||||
|
$.post(url='/', {drag: ui.draggable.attr('name'), drop: $(this).attr('name')});
|
||||||
|
|
||||||
|
draggable.css({
|
||||||
|
left: dropPos.left + "px",
|
||||||
|
top: dropPos.top + "px",
|
||||||
|
"z-index": 20
|
||||||
|
});
|
||||||
|
|
||||||
|
droppable.css("z-index", 10).animate({
|
||||||
|
left: dragPos.left,
|
||||||
|
top: dragPos.top
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
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>
|
163
gauss-turing/game/webapp.py
Normal file
163
gauss-turing/game/webapp.py
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
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)
|
Loading…
Reference in New Issue
Block a user