Add private voting (show vote totals only) mode. Closes #14. (#23)

* Add flag for private voting.
* Always show numbers after a vote.
* Add vote totals to history table and respect private voting flag.
* Make votes no longer private once game is over.
master
Daniel Perelman 5 years ago committed by GitHub
parent 9d72eb6cd3
commit b69b21d518
  1. 2
      avalon/avalon_game/forms.py
  2. 18
      avalon/avalon_game/models.py
  3. 4
      avalon/avalon_game/static/css/styles.css
  4. 15
      avalon/avalon_game/templates/in_game.html
  5. 3
      avalon/avalon_game/templates/mission_base.html
  6. 2
      avalon/avalon_game/templates/mission_wait.html
  7. 3
      avalon/avalon_game/templates/pick.html
  8. 3
      avalon/avalon_game/templates/pick_wait.html
  9. 9
      avalon/avalon_game/views.py

@ -87,6 +87,8 @@ class JoinGameForm(forms.Form):
class StartGameForm(forms.Form):
display_history = forms.BooleanField(required=False, initial=True,
label="show history table")
private_voting = forms.BooleanField(required=False, initial=True,
label="private voting (only reveal vote totals)")
merlin = forms.BooleanField(required=False, initial=True, label="Merlin")
percival = forms.BooleanField(required=False, initial=True,
label="Percival")

@ -27,6 +27,7 @@ class Game(models.Model):
game_phase = models.IntegerField(default=GAME_PHASE_LOBBY)
times_started = models.IntegerField(null=False, default=0)
display_history = models.NullBooleanField()
private_voting = models.NullBooleanField()
player_assassinated = models.ForeignKey('Player', null=True, default=None,
related_name='+')
created = models.DateTimeField()
@ -283,12 +284,25 @@ class VoteRound(models.Model):
def is_final_vote(self):
return self.vote_num == 5
def team_approved(self):
def previous_vote(self):
if self.is_first_vote():
return None
return VoteRound.objects.get(game_round=self.game_round,
vote_num=self.vote_num-1)
def vote_totals(self):
num_players = self.game_round.game.num_players()
if self.playervote_set.count() == num_players:
accepts = self.playervote_set.filter(accept=True).count()
rejects = num_players - accepts
return accepts > rejects
return {'accepts': accepts, 'rejects': rejects}
else:
return None
def team_approved(self):
votes = self.vote_totals()
if votes:
return votes['accepts'] > votes['rejects']
else:
return None

@ -307,11 +307,11 @@ li.player, li.player form {
padding: 0;
margin: 0;
}
#history tbody td.accept:before {
#history tbody td.accept:after, #history tbody th.accept:after {
color: green;
content: "\2713";
}
#history tbody td.reject:before {
#history tbody td.reject:after, #history tbody th.reject:after{
color: brown;
content: "\2717";
}

@ -79,7 +79,7 @@
{% block history %}
{{ debug }}
{% if not display_history %}
{% if not display_history and not game_over %}
<table id="player_order">
<thead>
<tr>
@ -98,11 +98,14 @@
<table id="history">
<thead>
<tr>
<th class="accept"></th>
<th class="reject"></th>
{% for p in players %}
<th><p><span{% if game_over %} class="{{ p.team }}"{% endif %}>{{ p.name }}</span></p></th>
{% endfor %}
</tr>
{% if game_over %}
<th colspan="2"></th>
{% for p in players %}
<th><p><span{% if game_over %} class="{{ p.team }}"{% endif %}>{{ p.role_string }}</span></p></th>
{% endfor %}
@ -118,10 +121,14 @@
{% elif vote_round.is_voting_complete %}{% if game_over %}reject{% else %}accept-pending{% endif %}
{% endif %}">
{% if vote_round.is_voting_complete %}
<td class="accept">{{ vote_round.vote_totals.accepts }}</td>
<td class="reject">{{ vote_round.vote_totals.rejects }}</td>
{% for pv in vote_round.playervote_set.all|dictsort:'player.order' %}
<td class="{% if pv.player == vote_round.leader %}leader{% endif %} {% if pv.player in vote_round.chosen.all %}chosen {% if game_over and vote_round.team_approved %}{% if pv.player in game_round.played_fail %}played-fail{% else %}played-success{% endif %}{% endif %}{% endif %} {% if pv.accept %}accept{% else %}reject{% endif %}"></td>
<td class="{% if pv.player == vote_round.leader %}leader{% endif %} {% if pv.player in vote_round.chosen.all %}chosen {% if game_over and vote_round.team_approved %}{% if pv.player in game_round.played_fail %}played-fail{% else %}played-success{% endif %}{% endif %}{% endif %} {% if not private_voting or game_over %}{% if pv.accept %}accept{% else %}reject{% endif %}{% endif %}"></td>
{% endfor %}
{% else %}
<td class="accept"></td>
<td class="reject"></td>
{% for p in players %}
<td class="{% if p == vote_round.leader %}leader{% endif %} {% if vote_round.is_team_finalized and p in vote_round.chosen.all %}chosen{% endif %}"></td>
{% endfor %}
@ -130,14 +137,14 @@
{% endfor %}
{% if game_round.mission_passed != None %}
<tr class="summary {{ game_round.result_string }}">
<td colspan="{{ num_players }}">
<td colspan="{{ num_players|add:2 }}">
Mission {{ game_round.round_num }} {{ game_round.result_string }}ed
with {{ game_round.num_fails }} failures
</td>
</tr>
{% elif game_over %}
<tr class="summary fail">
<td colspan="{{ num_players }}">
<td colspan="{{ num_players|add:2 }}">
Mission {{ game_round.round_num }} failed as the resistance was unable
to choose a team 5 times in a row
</td>

@ -5,7 +5,8 @@
<h2>Mission Phase</h2>
<p>
The vote has passed. You have been chosen to go on the mission.
The vote has passed (<b class="approve">{{ vote.accepts }}</b>-<b class="reject">{{ vote.rejects }}</b>).
You have been chosen to go on the mission.
The following players are on the mission:
<ul id="chosen-for-mission">
{% for chosen_player in chosen %}

@ -5,7 +5,7 @@
<h2>Mission Phase</h2>
<p>
The vote has passed.
The vote has passed (<b class="approve">{{ vote.accepts }}</b>-<b class="reject">{{ vote.rejects }}</b>).
{% if not is_observer %}
You have not been selected. Please wait.
{% endif %}

@ -5,7 +5,8 @@
<h2>Pick Phase</h2>
{% if vote_rejected %}
<p class="red">
The previous vote has been rejected. You are now the leader.
The previous vote has been rejected (<b class="approve">{{ previous_vote.accepts }}</b>-<b class="reject">{{previous_vote.rejects }}</b>).
You are now the leader.
</p>
{% endif %}
This will be vote #{{ vote_num }} of 5 for this mission.

@ -5,7 +5,8 @@
<h2>Pick Phase</h2>
{% if vote_rejected %}
<p class="red">
The previous vote has been rejected. A new leader has been chosen.
The previous vote has been rejected (<b class="approve">{{ previous_vote.accepts }}</b>-<b class="reject">{{previous_vote.rejects }}</b>).
A new leader has been chosen.
</p>
{% endif %}
This will be vote #{{ vote_num }} of 5 for this mission.

@ -211,6 +211,8 @@ def game_base_context(game, player):
if game.display_history is not None:
context['display_history'] = game.display_history
if game.private_voting is not None:
context['private_voting'] = game.private_voting
try:
round_scores = {}
@ -267,7 +269,10 @@ def _game(request, game, player, extra_context=None):
vote_round = VoteRound.objects.get_current_vote_round(game=game)
assert vote_round.vote_status == VoteRound.VOTE_STATUS_WAITING
context['chosen'] = vote_round.chosen.order_by('order').all()
context['vote_rejected'] = not vote_round.is_first_vote()
vote_rejected = not vote_round.is_first_vote()
context['vote_rejected'] = vote_rejected
if vote_rejected:
context['previous_vote'] = vote_round.previous_vote().vote_totals()
context['leader'] = vote_round.leader
context['round_num'] = vote_round.game_round.round_num
context['vote_num'] = vote_round.vote_num
@ -309,6 +314,7 @@ def _game(request, game, player, extra_context=None):
context['round_num'] = round_num
vote_num = vote_round.vote_num
context['vote_num'] = vote_num
context['vote'] = vote_round.vote_totals()
if player in chosen:
game_round = vote_round.game_round
mission_action = game_round.missionaction_set.filter(player=player)
@ -405,6 +411,7 @@ def _start(request, game, player):
form.add_error(None, "There will only be %d spies. Select no more than that many special roles for spies." % num_spies)
else:
game.display_history = form.cleaned_data.get('display_history')
game.private_voting = form.cleaned_data.get('private_voting')
game.game_phase = Game.GAME_PHASE_ROLE
game.times_started += 1

Loading…
Cancel
Save