Permalink
Browse files

[+] Now user can leave the game

  • Loading branch information...
1 parent 841ca20 commit f83000982239673c3fb5af706286d5139ad53abe Igor Kobylin committed Jul 31, 2011
View
1 setwithme/apps/core/views.py
@@ -23,6 +23,7 @@ def home(request):
def lobby(request):
qs = GameSession.objects.\
filter(user=request.user,
+ left=False,
game__finished=False).\
exclude(client_state=ClientConnectionState.LOST)
if qs.count():
View
87 setwithme/apps/game/migrations/0003_auto__add_field_gamesession_left.py
@@ -0,0 +1,87 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'GameSession.left'
+ db.add_column('game_gamesession', 'left', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'GameSession.left'
+ db.delete_column('game_gamesession', 'left')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'game.facts': {
+ 'Meta': {'object_name': 'Facts'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'text': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'game.game': {
+ 'Meta': {'object_name': 'Game'},
+ 'desk_cards': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'default': "''", 'max_length': '250'}),
+ 'end': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
+ 'finished': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.CharField', [], {'max_length': '36', 'primary_key': 'True'}),
+ 'remaining_cards': ('django.db.models.fields.CommaSeparatedIntegerField', [], {'default': "'29,61,18,67,64,12,47,43,63,31,35,3,45,14,49,51,68,21,52,19,77,57,38,62,20,46,0,24,74,17,55,27,58,4,80,36,16,2,66,50,40,53,8,54,22,30,7,32,70,56,75,25,71,23,28,11,78,65,48,59,73,10,33,6,26,1,13,9,60,69,76,42,34,15,72,5,37,39,79,44,41'", 'max_length': '250'}),
+ 'start': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
+ },
+ 'game.gamesession': {
+ 'Meta': {'object_name': 'GameSession'},
+ 'client_state': ('django.db.models.fields.CharField', [], {'default': "'ACTIVE'", 'max_length': '50'}),
+ 'failures': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'game': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['game.Game']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_access': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'left': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'set_pressed_dt': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'sets_found': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'state': ('django.db.models.fields.CharField', [], {'default': "'NORMAL'", 'max_length': '50'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ }
+ }
+
+ complete_apps = ['game']
View
8 setwithme/apps/game/models.py
@@ -150,7 +150,9 @@ def count_sets(self):
def is_finished(self):
has_cards = len(self.remaining_cards) > 0
has_sets = self.has_sets()
- active_players = self.gamesession_set.exclude(client_state=ClientConnectionState.LOST).count()
+ active_players = self.gamesession_set\
+ .exclude(client_state=ClientConnectionState.LOST)\
+ .exclude(state=GameSessionState.LEFT).count()
is_finished = (active_players < 2) or (not has_cards and not has_sets)
if is_finished:
self.finished = True
@@ -161,19 +163,22 @@ def is_finished(self):
def leader(self):
"""Determines leading user, can be user after game end for determining winner"""
scores = self.gamesession_set.exclude(client_state=ClientConnectionState.LOST)\
+ .exclude(state=GameSessionState.LEFT)\
.values_list('sets_found', 'failures', 'user')
return max([(score[0] - score[1], score[2]) for score in scores])[1]
class GameSessionState:
NORMAL = "NORMAL"
+ LEFT = "LEFT"
SET_PRESSED = "SET_PRESSED"
SET_PENALTY = "SET_PENALTY"
SET_ANOTHER_USER = "SET_ANOTHER_USER"
GameSessionStateChoices = (
(GameSessionState.NORMAL, 'Normal'),
+ (GameSessionState.LEFT, 'Left'),
(GameSessionState.SET_PRESSED, 'Set pressed'),
(GameSessionState.SET_PENALTY, 'Set penalty'),
(GameSessionState.SET_ANOTHER_USER, 'Set another user'),
@@ -208,6 +213,7 @@ class GameSession(models.Model):
sets_found = models.IntegerField(default=0)
failures = models.IntegerField(default=0)
last_access = models.DateTimeField(default=datetime.datetime.now)
+ left = models.BooleanField(default=False)
def press_set(self):
self.set_pressed_dt = datetime.datetime.now()
View
1 setwithme/apps/game/urls.py
@@ -8,4 +8,5 @@
url(r'^get_status/(?P<game_id>[\w]+)$', 'get_status'),
url(r'^put_set_mark/(?P<game_id>[\w]+)$', 'put_set_mark'),
url(r'^check_set/(?P<game_id>[\w]+)$', 'check_set'),
+ url(r'^leave/(?P<game_id>[\w]+)$', 'leave_game', name='leave_game'),
)
View
23 setwithme/apps/game/views.py
@@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
import datetime
import json
-from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
from annoying.decorators import ajax_request, render_to
+from django.core.urlresolvers import reverse
+from django.shortcuts import get_object_or_404, redirect
-from game.models import Game, GameSession, GameSessionState, ClientConnectionState, get_uid
+from chat.models import ChatMessage
+from game import constants
+from game.models import ClientConnectionState, Game, GameSession, GameSessionState, get_uid
from game.utils import Card, is_set
from users.models import WaitingUser
-from game import constants
-from chat.models import ChatMessage
@render_to('game/game_screen.html')
@@ -37,7 +37,9 @@ def game_screen(request, game_id):
def start_game(request):
user = request.user
qs = GameSession.objects.\
- filter(user=user, game__finished=False).exclude(client_state=ClientConnectionState.LOST)
+ filter(user=user,
+ left=False,
+ game__finished=False).exclude(client_state=ClientConnectionState.LOST)
if qs.count():
gs = qs.all()[0]
return {'status': 302,
@@ -167,3 +169,12 @@ def is_set_wrapper(*args):
gs.save()
return add_stat(gs, {'success': False, 'msg': 'Not in time!'})
+
+def leave_game(request, game_id):
+ gs = get_object_or_404(request.user.gamesession_set, game=game_id, left=False)
+ gs.state = GameSessionState.LEFT
+ gs.left = True
+ gs.save()
+ gs.game.finished = True
+ gs.game.save()
+ return redirect('/')
View
3 setwithme/static/css/base.css
@@ -551,6 +551,9 @@ a.pseudo:hover {
.players .player.lost {
opacity: 0.2;
}
+.players .player.left {
+ opacity: 0.2;
+}
.player {
overflow: hidden;
View
2 setwithme/static/js/base.js
@@ -468,7 +468,6 @@ SetWithMe.Game = {
if (changed.hasOwnProperty(key)) {
var card = changed[key];
var $place = this._cardsContainer.find('#' + card.oldId);
- console.debug(card)
if ($place.length) {
if ($place.css('opacity') == 0) {
$place.animate({opacity: '0'}, 1000);
@@ -478,7 +477,6 @@ SetWithMe.Game = {
this._bindCardEvents($place);
this._cardsContainer.append($place);
}
- console.debug($place);
$place.attr('class', 'card ' + card['class']);
$place.attr('id', card['id']);
$place.animate({opacity: '1'}, 1000);
View
15 setwithme/templates/game/game_screen.html
@@ -39,12 +39,17 @@
</div>
<div class="winner_plate">
- <h1>Game over. And winner is...</h1>
- <div id="js_user_place"></div>
- <div class="share_game">
- {% include 'game/include/sharing.html' %}
+ <h1>Game over. And winner is...</h1>
+ <div></div>
+ <div id="js_user_place"></div>
+ <div class="share_game">
+ {% include 'game/include/sharing.html' %}
+ </div>
+ <a href="{% url lobby %}" class="playagain">Play one more time</a>
</div>
- <a href="{% url lobby %}" class="playagain">Play one more time</a>
+
+ <div>
+ <a href="{% url leave_game game_id %}">Leave game</a>
</div>
</div>

0 comments on commit f830009

Please sign in to comment.