|
|
|
@ -1,5 +1,7 @@
|
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
from io import BytesIO
|
|
|
|
|
import hashlib
|
|
|
|
|
import json
|
|
|
|
|
import qrcode
|
|
|
|
|
|
|
|
|
|
from django.db import transaction
|
|
|
|
@ -89,17 +91,77 @@ def qr_code(request, access_code):
|
|
|
|
|
return HttpResponse(output.getvalue(), content_type='image/png')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
@lookup_access_code
|
|
|
|
|
@require_http_methods(["HEAD", "GET", "POST"])
|
|
|
|
|
def game(request, game):
|
|
|
|
|
def load_players(game):
|
|
|
|
|
players = OrderedDict()
|
|
|
|
|
for player in game.player_set.order_by('order').all():
|
|
|
|
|
player.total_fear = 0
|
|
|
|
|
player.changed_to_ready = False
|
|
|
|
|
player.fear = OrderedDict()
|
|
|
|
|
players[player.order] = player
|
|
|
|
|
|
|
|
|
|
return players
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_players_with_fear(game, current_phase=None, players=None):
|
|
|
|
|
if players is None:
|
|
|
|
|
players = load_players(game)
|
|
|
|
|
if current_phase is None:
|
|
|
|
|
current_phase = game.get_current_phase()
|
|
|
|
|
|
|
|
|
|
for fear in current_phase.fear_set.order_by('effect').all():
|
|
|
|
|
players[fear.player.order].fear[fear.effect] = {
|
|
|
|
|
'pure_fear': fear.pure_fear,
|
|
|
|
|
'towns': fear.towns_destroyed,
|
|
|
|
|
'cities': fear.cities_destroyed,
|
|
|
|
|
}
|
|
|
|
|
players[fear.player.order].total_fear +=\
|
|
|
|
|
fear.pure_fear + fear.towns_destroyed + 2*fear.cities_destroyed
|
|
|
|
|
|
|
|
|
|
return players
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def game_status_object(game, current_phase=None, players_with_fear=None):
|
|
|
|
|
if current_phase is None:
|
|
|
|
|
current_phase = game.get_current_phase()
|
|
|
|
|
if players_with_fear is None:
|
|
|
|
|
players_with_fear = get_players_with_fear(game, current_phase)
|
|
|
|
|
|
|
|
|
|
players = OrderedDict()
|
|
|
|
|
for order, player in players.items():
|
|
|
|
|
players[order] = {
|
|
|
|
|
'ready': player.ready,
|
|
|
|
|
'fear': player.fear,
|
|
|
|
|
'total_fear': player.total_fear
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_obj = {
|
|
|
|
|
'turn': game.game_turn,
|
|
|
|
|
'phase': game.get_current_phase_name(),
|
|
|
|
|
'phase_id': game.game_phase,
|
|
|
|
|
'available_fear_cards': game.num_available_fear_cards(),
|
|
|
|
|
'fear_to_next_card': game.get_fear_to_next_card(),
|
|
|
|
|
'fear_this_phase': current_phase.fear_this_phase(),
|
|
|
|
|
'total_fear': game.get_current_total_fear(),
|
|
|
|
|
'players': players,
|
|
|
|
|
'all_ready': all(player.ready for player in players.values()),
|
|
|
|
|
}
|
|
|
|
|
h = hashlib.sha256()
|
|
|
|
|
h.update(json.dumps(status_obj).encode('utf-8'))
|
|
|
|
|
status_hash = h.hexdigest()
|
|
|
|
|
status_obj['hash'] = status_hash
|
|
|
|
|
|
|
|
|
|
return status_obj
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@transaction.atomic
|
|
|
|
|
@lookup_access_code
|
|
|
|
|
@require_http_methods(["HEAD", "GET", "POST"])
|
|
|
|
|
def game(request, game):
|
|
|
|
|
# TODO Should check if game is over and redirect to summary table view.
|
|
|
|
|
|
|
|
|
|
players = load_players(game)
|
|
|
|
|
for player in players.values():
|
|
|
|
|
player.changed_to_ready = False
|
|
|
|
|
|
|
|
|
|
errors = []
|
|
|
|
|
fear_kind_dict = {
|
|
|
|
|
'fear': 'pure_fear',
|
|
|
|
@ -198,14 +260,10 @@ def game(request, game):
|
|
|
|
|
for player in players.values():
|
|
|
|
|
player.ready = True
|
|
|
|
|
|
|
|
|
|
for fear in current_phase.fear_set.order_by('effect').all():
|
|
|
|
|
players[fear.player.order].fear[fear.effect] = {
|
|
|
|
|
'pure_fear': fear.pure_fear,
|
|
|
|
|
'towns': fear.towns_destroyed,
|
|
|
|
|
'cities': fear.cities_destroyed,
|
|
|
|
|
}
|
|
|
|
|
players[fear.player.order].total_fear +=\
|
|
|
|
|
fear.pure_fear + fear.towns_destroyed + 2*fear.cities_destroyed
|
|
|
|
|
players = get_players_with_fear(game, current_phase, players)
|
|
|
|
|
status_obj = game_status_object(game, current_phase, players)
|
|
|
|
|
status_string = json.dumps(status_obj)
|
|
|
|
|
|
|
|
|
|
for player in players.values():
|
|
|
|
|
info = player.fear
|
|
|
|
|
if not info:
|
|
|
|
@ -217,17 +275,12 @@ def game(request, game):
|
|
|
|
|
'towns': 0,
|
|
|
|
|
'cities': 0,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return render(request, 'game.html', {
|
|
|
|
|
'access_code': game.access_code,
|
|
|
|
|
'turn': game.game_turn,
|
|
|
|
|
'phase': game.get_current_phase_name(),
|
|
|
|
|
'phase_id': game.game_phase,
|
|
|
|
|
'available_fear_cards': game.num_available_fear_cards(),
|
|
|
|
|
'fear_to_next_card': game.get_fear_to_next_card(),
|
|
|
|
|
'fear_this_phase': current_phase.fear_this_phase(),
|
|
|
|
|
'total_fear': game.get_current_total_fear(),
|
|
|
|
|
'status': status_obj,
|
|
|
|
|
'status_json': status_string,
|
|
|
|
|
'players': players,
|
|
|
|
|
'all_ready': all(player.ready for player in players.values()),
|
|
|
|
|
'range': range(21),
|
|
|
|
|
'errors': errors,
|
|
|
|
|
})
|
|
|
|
@ -235,6 +288,6 @@ def game(request, game):
|
|
|
|
|
|
|
|
|
|
@lookup_access_code
|
|
|
|
|
@require_safe
|
|
|
|
|
def status(request, game):
|
|
|
|
|
def status(request, game, hashcode=None):
|
|
|
|
|
# TODO status json
|
|
|
|
|
pass
|
|
|
|
|