RoboRallyGUI/app.py

219 lines
7.1 KiB
Python
Raw Normal View History

from flask import Flask, render_template, request, session, make_response
import random
import socket
import time
2020-09-11 12:30:40 +00:00
app = Flask(__name__)
app.secret_key = b'RoboRallyRolling'
random.seed(0)
2020-09-11 12:30:40 +00:00
moves = ['forward', 'backward', 'turn left', 'turn right', 'turn around']
class Game:
def __init__(self):
self.action_stack = {}
self.processing_done = False # indicates whether all commands in the current round have been processed
self.comm_socket = socket.socket() # socket for communicating with the program controlling the robots
try:
self.comm_socket.connect(('192.168.1.213', 1337))
except socket.error:
print("could not connect to robot control socket!")
def ready(self):
# have all players chosen an action?
return len(self.action_stack.keys()) == Player.player_counter
def register_actions(self, player_id, actions):
if not player_id in self.action_stack.keys():
print("registered actions: ", [str(a) for a in actions])
self.action_stack[player_id] = actions
deck.return_cards(actions) # put cards back into the deck
self.processing_done = False
return True
else:
print("actions already chosen!")
return False
def process_actions(self):
# send commands to the robots in the order of priority
for i in range(5):
current_actions = []
for p in self.action_stack.keys():
current_actions += [(p, self.action_stack[p][i])]
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(3)
time.sleep(0.5)
#self.comm_socket.send()
# clear the action stack for the next round
self.action_stack = {}
self.processing_done = True
2020-09-11 12:30:40 +00:00
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=20):
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:
MAX_PLAYERS = 3
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
else:
print("max players reached!")
def draw_new_cards(self):
self.player_hand += deck.draw_cards(self.max_cards - len(self.player_hand))
players = {}
game = Game()
@app.route('/send_cmds', methods=['POST', 'GET'])
def send_cmds():
if request.method == 'POST':
# POST is used for submitting commands
player_id = session['player_id']
p = players[player_id]
if game.register_actions(p.id, p.player_hand[0:p.action_count]):
p.player_hand = p.player_hand[p.action_count:] # discard used cards
p.draw_new_cards()
if game.ready():
game.process_actions()
return 'OK'
else:
return 'please wait'
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'
@app.route('/', methods=['GET', 'POST'])
2020-09-11 12:30:40 +00:00
def hello_world():
if not 'player_id' in session:
if Player.player_counter < Player.MAX_PLAYERS:
# new player
p = Player()
session['player_id'] = p.id
players[p.id] = p
player_id = session['player_id']
else:
return "Sorry, maximum number of players reached!"
else:
player_id = session['player_id']
if Player.player_counter < player_id + 1:
session.clear()
response = make_response('Please reload the page!')
#response.set_cookie('player_id', '', expires=0)
return response
player_hand = players[player_id].player_hand
if request.method == 'GET':
return render_template('drag_example.html', cmds=player_hand, player_id=player_id)
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)
2020-09-11 12:30:40 +00:00
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)