coupled roborally game logic with web server
This commit is contained in:
parent
a334fab2c6
commit
003113cb89
179
app.py
179
app.py
|
@ -2,90 +2,22 @@ from flask import Flask, render_template, request, session, make_response
|
||||||
import random
|
import random
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
import roborally
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = b'RoboRallyRolling'
|
app.secret_key = b'RoboRallyRolling'
|
||||||
|
|
||||||
random.seed(0)
|
|
||||||
|
|
||||||
moves = ['forward', 'forward x2', 'forward x3', 'backward', 'turn left', 'turn right', 'turn around']
|
|
||||||
probabilities = [0.21428571428571427, 0.14285714285714285, 0.07142857142857142, 0.07142857142857142, 0.21428571428571427, 0.21428571428571427, 0.07142857142857142]
|
probabilities = [0.21428571428571427, 0.14285714285714285, 0.07142857142857142, 0.07142857142857142, 0.21428571428571427, 0.21428571428571427, 0.07142857142857142]
|
||||||
|
|
||||||
|
deck = roborally.CardDeck()
|
||||||
class Robot:
|
|
||||||
def __init__(self, x, y, orientation, id):
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
self.orientation = orientation
|
|
||||||
self.id = id
|
|
||||||
|
|
||||||
def move(self, type):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.id)
|
|
||||||
|
|
||||||
class Tile:
|
|
||||||
# possible modifiers:
|
|
||||||
# conveyors: <, >, ^, v
|
|
||||||
# repair station: r
|
|
||||||
# flag: f<number>
|
|
||||||
def __init__(self, x, y, modifier=None):
|
|
||||||
self.modifier = modifier
|
|
||||||
self.occupant = None
|
|
||||||
self.x = x
|
|
||||||
self.y = y
|
|
||||||
|
|
||||||
def is_empty(self):
|
|
||||||
return self.occupant is None
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
if self.is_empty():
|
|
||||||
if self.modifier is None:
|
|
||||||
return ' '
|
|
||||||
else:
|
|
||||||
return self.modifier
|
|
||||||
else:
|
|
||||||
return str(self.occupant)
|
|
||||||
|
|
||||||
class Board:
|
|
||||||
x_dims = 12 # number of tiles in x direction
|
|
||||||
y_dims = 6 # number of tiles in y direction
|
|
||||||
def __init__(self):
|
|
||||||
self.board = {}
|
|
||||||
for x in range(Board.x_dims):
|
|
||||||
for y in range(Board.y_dims):
|
|
||||||
if x == 0 and (y >= 1) and (y <= 4):
|
|
||||||
self.board[(x,y)] = Tile(x,y,'v')
|
|
||||||
else:
|
|
||||||
self.board[(x, y)] = Tile(x, y)
|
|
||||||
|
|
||||||
self.board[(0,0)].occupant = Robot(0,0,'>',1)
|
|
||||||
self.board[(2,0)].occupant = Robot(2,0,'v',2)
|
|
||||||
|
|
||||||
def apply_actions(self, actions):
|
|
||||||
# apply the actions to the board and generate a list of movement commands
|
|
||||||
# sort actions by priority
|
|
||||||
sorted_actions = sorted(actions, key=lambda a: a[1].priority)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
output = '#' * (Board.x_dims + 2) + '\n'
|
|
||||||
for y in range(Board.y_dims):
|
|
||||||
output += '#'
|
|
||||||
for x in range(Board.x_dims):
|
|
||||||
output += str(self.board[(x,y)])
|
|
||||||
output += '#\n'
|
|
||||||
output += '#' * (Board.x_dims + 2)
|
|
||||||
return output
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.action_stack = {}
|
self.action_stack = {}
|
||||||
self.processing_done = False # indicates whether all commands in the current round have been processed
|
self.processing_done = False # indicates whether all commands in the current round have been processed
|
||||||
|
|
||||||
self.board = Board()
|
self.board = roborally.Board()
|
||||||
|
|
||||||
self.comm_socket = socket.socket() # socket for communicating with the program controlling the robots
|
self.comm_socket = socket.socket() # socket for communicating with the program controlling the robots
|
||||||
try:
|
try:
|
||||||
|
@ -98,7 +30,8 @@ class Game:
|
||||||
return len(self.action_stack.keys()) == Player.player_counter
|
return len(self.action_stack.keys()) == Player.player_counter
|
||||||
|
|
||||||
def register_actions(self, player_id, actions):
|
def register_actions(self, player_id, actions):
|
||||||
if not player_id in self.action_stack.keys():
|
# store the selected actions for the given player
|
||||||
|
if not player_id in self.action_stack.keys(): # make sure that the actions have not been registered before
|
||||||
print("registered actions: ", [str(a) for a in actions])
|
print("registered actions: ", [str(a) for a in actions])
|
||||||
self.action_stack[player_id] = actions
|
self.action_stack[player_id] = actions
|
||||||
deck.return_cards(actions) # put cards back into the deck
|
deck.return_cards(actions) # put cards back into the deck
|
||||||
|
@ -109,37 +42,34 @@ class Game:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def process_actions(self):
|
def process_actions(self):
|
||||||
# send commands to the robots in the order of priority
|
l = []
|
||||||
for i in range(5):
|
for p in self.action_stack.keys():
|
||||||
current_actions = []
|
l.append(zip([p] * len(self.action_stack[p]), self.action_stack[p]))
|
||||||
for p in self.action_stack.keys():
|
chosen_cards = list(zip(*l))
|
||||||
current_actions += [(p, self.action_stack[p][i])]
|
|
||||||
|
|
||||||
print("current actions = ", current_actions)
|
|
||||||
# generate list of movement commands to send to the control program
|
|
||||||
|
|
||||||
self.board.apply_actions(current_actions)
|
|
||||||
|
|
||||||
if False:
|
# apply the chosen commands to the board which generates a list of movement commands to send to the control program
|
||||||
# send movements to the program
|
cmd_list = self.board.apply_actions(chosen_cards)
|
||||||
for c in current_actions:
|
|
||||||
if c[0] == 0:
|
|
||||||
print("{}, {}\n".format(c[1].action, 11))
|
|
||||||
self.comm_socket.sendall("{}, {}\n".format(c[1].action, 11).encode())
|
|
||||||
elif c[0] == 1:
|
|
||||||
print("{}, {}\n".format(c[1].action, 14))
|
|
||||||
self.comm_socket.sendall("{}, {}\n".format(c[1].action, 14).encode())
|
|
||||||
data = self.comm_socket.recv(32)
|
|
||||||
|
|
||||||
if data == b'OK\n':
|
if False:
|
||||||
print("an error occured while processing the commands")
|
# send movements to the program
|
||||||
self.processing_done = True
|
for c in current_actions:
|
||||||
self.action_stack = {}
|
if c[0] == 0:
|
||||||
return
|
print("{}, {}\n".format(c[1].action, 11))
|
||||||
|
self.comm_socket.sendall("{}, {}\n".format(c[1].action, 11).encode())
|
||||||
|
elif c[0] == 1:
|
||||||
|
print("{}, {}\n".format(c[1].action, 14))
|
||||||
|
self.comm_socket.sendall("{}, {}\n".format(c[1].action, 14).encode())
|
||||||
|
data = self.comm_socket.recv(32)
|
||||||
|
|
||||||
time.sleep(0.5)
|
if data == b'OK\n':
|
||||||
|
print("an error occured while processing the commands")
|
||||||
|
self.processing_done = True
|
||||||
|
self.action_stack = {}
|
||||||
|
return
|
||||||
|
|
||||||
#self.comm_socket.send()
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
#self.comm_socket.send()
|
||||||
|
|
||||||
|
|
||||||
# clear the action stack for the next round
|
# clear the action stack for the next round
|
||||||
|
@ -147,57 +77,6 @@ class Game:
|
||||||
|
|
||||||
self.processing_done = True
|
self.processing_done = True
|
||||||
|
|
||||||
class Card:
|
|
||||||
card_counter = 0
|
|
||||||
def __init__(self):
|
|
||||||
self.number = Card.card_counter
|
|
||||||
Card.card_counter += 1
|
|
||||||
self.action = random.choice(moves)
|
|
||||||
self.priority = random.randint(0, 100)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "Card No. " + str(self.number) + " " + self.action + " " + str(self.priority)
|
|
||||||
|
|
||||||
class CardDeck:
|
|
||||||
def __init__(self, n=84):
|
|
||||||
self.deck = {}
|
|
||||||
# generate cards
|
|
||||||
for i in range(0,n):
|
|
||||||
self.deck[i] = Card()
|
|
||||||
self.dealt = set()
|
|
||||||
self.discard_pile = set()
|
|
||||||
|
|
||||||
def draw_cards(self, n=1):
|
|
||||||
available = set(self.deck.keys()).difference(self.dealt)
|
|
||||||
#print("{} cards are available".format(len(available)))
|
|
||||||
|
|
||||||
if len(available) < n:
|
|
||||||
drawn = list(available) # give out remaining cards
|
|
||||||
#print("drawing remaining {} cards".format(len(drawn)))
|
|
||||||
self.dealt = self.dealt.union(drawn)
|
|
||||||
|
|
||||||
# put the cards from the discard pile back into the game
|
|
||||||
self.dealt = self.dealt - self.discard_pile
|
|
||||||
self.discard_pile = set() # reset the discard pile
|
|
||||||
|
|
||||||
# draw rest of cards
|
|
||||||
available = set(self.deck.keys()).difference(self.dealt)
|
|
||||||
#print("drawing another {} cards".format(n - len(drawn)))
|
|
||||||
drawn += random.sample(available, n - len(drawn))
|
|
||||||
else:
|
|
||||||
drawn = random.sample(available, n)
|
|
||||||
#print("cards drawn: {}".format(drawn))
|
|
||||||
|
|
||||||
self.dealt = self.dealt.union(drawn)
|
|
||||||
|
|
||||||
return [self.deck[i] for i in drawn]
|
|
||||||
|
|
||||||
def return_cards(self, cards):
|
|
||||||
self.discard_pile = self.discard_pile.union(set([c.number for c in cards]))
|
|
||||||
pass
|
|
||||||
|
|
||||||
deck = CardDeck()
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
MAX_PLAYERS = 3
|
MAX_PLAYERS = 3
|
||||||
player_counter = 0
|
player_counter = 0
|
||||||
|
|
|
@ -58,9 +58,6 @@ class CardDeck:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
deck = CardDeck()
|
|
||||||
|
|
||||||
|
|
||||||
class Robot:
|
class Robot:
|
||||||
# dictionary mapping the current orientation and a turn command to the resulting orientation
|
# dictionary mapping the current orientation and a turn command to the resulting orientation
|
||||||
resulting_orientation = {
|
resulting_orientation = {
|
||||||
|
@ -403,6 +400,7 @@ class Board:
|
||||||
print(cmd_list)
|
print(cmd_list)
|
||||||
print(self)
|
print(self)
|
||||||
pass
|
pass
|
||||||
|
return cmd_list
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
#output = '#' * (Board.x_dims + 2) + '\n'
|
#output = '#' * (Board.x_dims + 2) + '\n'
|
||||||
|
@ -420,6 +418,9 @@ class Board:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
n = 5
|
n = 5
|
||||||
|
|
||||||
|
deck = CardDeck()
|
||||||
|
|
||||||
player_1_cards = random.sample(list(filter(lambda c: 'backward' in c.action, deck.deck.values())), n)
|
player_1_cards = random.sample(list(filter(lambda c: 'backward' in c.action, deck.deck.values())), n)
|
||||||
player_2_cards = random.sample(list(filter(lambda c: 'turn around' in c.action, deck.deck.values())), n)
|
player_2_cards = random.sample(list(filter(lambda c: 'turn around' in c.action, deck.deck.values())), n)
|
||||||
#player_1_cards = deck.draw_cards(40)
|
#player_1_cards = deck.draw_cards(40)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user