diff --git a/api/resources/game.py b/api/resources/game.py index 3cc1b64..90a1792 100644 --- a/api/resources/game.py +++ b/api/resources/game.py @@ -2,7 +2,7 @@ from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView -from game.models import Game, GameEvent +from game.models import Game, GameEvent, GameStatuses from ..serializers import GameSerializer, GameEventSerializer @@ -41,9 +41,16 @@ class GameEventResource(APIView): """ Creates a new event """ try: - Game.objects.get(pk=game_id) + game = Game.objects.get(pk=game_id) except Game.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) + print(game.status, game.status == GameStatuses.FINISHED) + if game.status == GameStatuses.FINISHED: + print("WTF, DEVERIA PASSAR AQUI") + return Response( + {"message": "Game is already finished"}, + status=status.HTTP_412_PRECONDITION_FAILED, + ) serializer = GameEventSerializer(data=request.data) if serializer.is_valid(): diff --git a/game/admin.py b/game/admin.py index e69de29..60e6a79 100644 --- a/game/admin.py +++ b/game/admin.py @@ -0,0 +1,29 @@ +from django.contrib import admin + +from .models import Game, GameEvent + + +@admin.register(Game) +class GameAdmin(admin.ModelAdmin): + list_display = ( + "id", + "created_at", + "modified_at", + "rows", + "cols", + "mines", + "win", + "status", + ) + + list_filter = ( + "win", + "status", + ) + + +@admin.register(GameEvent) +class GameEventAdmin(admin.ModelAdmin): + list_display = ("id", "created_at", "game", "type", "event_row", "event_col") + + list_filter = ("type",) diff --git a/game/migrations/0005_auto_20201106_2357.py b/game/migrations/0005_auto_20201106_2357.py new file mode 100644 index 0000000..83e1568 --- /dev/null +++ b/game/migrations/0005_auto_20201106_2357.py @@ -0,0 +1,51 @@ +# Generated by Django 3.1.3 on 2020-11-06 23:57 + +from django.db import migrations, models +import game.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("game", "0004_auto_20201106_0453"), + ] + + operations = [ + migrations.RemoveField(model_name="gameevent", name="metadata",), + migrations.AddField( + model_name="gameevent", + name="event_col", + field=models.PositiveIntegerField( + blank=True, + default=None, + help_text="Column on the board where the event occurred, if applicable", + null=True, + verbose_name="The column clicked", + ), + ), + migrations.AddField( + model_name="gameevent", + name="event_row", + field=models.PositiveIntegerField( + blank=True, + default=None, + help_text="Row on the board where the event occurred, if applicable", + null=True, + verbose_name="The row clicked", + ), + ), + migrations.AlterField( + model_name="game", + name="status", + field=models.IntegerField( + choices=[ + (0, "NOT_PLAYED"), + (1, "PLAYING"), + (2, "PAUSED"), + (3, "FINISHED"), + ], + default=game.models.GameStatuses["NOT_PLAYED"], + help_text="Actual game status", + ), + ), + ] diff --git a/game/models.py b/game/models.py index 779ab12..3a51d09 100644 --- a/game/models.py +++ b/game/models.py @@ -2,7 +2,7 @@ from enum import IntEnum from django.db import models from django_mysql.models import JSONField -from internal.utils import empty_list, empty_object +from internal.utils import empty_list from .game import Minesweeper @@ -19,7 +19,8 @@ class GameStatuses(EnumChoicesBase): NOT_PLAYED = 0 PLAYING = 1 - FINISHED = 2 + PAUSED = 2 + FINISHED = 3 class Game(models.Model): @@ -93,8 +94,19 @@ class GameEvent(models.Model): help_text="The game event", ) - metadata = JSONField( - "Event metadata", default=empty_object, help_text="Some usefull event metadata" + event_row = models.PositiveIntegerField( + "The row clicked", + default=None, + null=True, + blank=True, + help_text="Row on the board where the event occurred, if applicable", + ) + event_col = models.PositiveIntegerField( + "The column clicked", + default=None, + null=True, + blank=True, + help_text="Column on the board where the event occurred, if applicable", ) class Meta: diff --git a/game/signals.py b/game/signals.py index 5f83578..8ca2152 100644 --- a/game/signals.py +++ b/game/signals.py @@ -1,17 +1,45 @@ from django.db.models.signals import post_save, pre_save from django.dispatch import receiver -from .models import Game, GameEvent, EventTypes +from .models import Game, GameEvent, EventTypes, GameStatuses from .game import Minesweeper @receiver(post_save, sender=Game) def game_start(sender, signal, instance, **kwargs): """ If the game was just created, insert the first event START_GAME """ - + if not instance.status == GameStatuses.NOT_PLAYED: + return GameEvent.objects.get_or_create(game=instance, type=EventTypes.START_GAME) +@receiver(pre_save, sender=GameEvent) +def mark_game_as_playing(sender, signal, instance, **kwargs): + """ When event match, mark the game instance as playing """ + + playing_events = [ + EventTypes.START_GAME, + EventTypes.RESUME, + EventTypes.CLICK_MINE, + EventTypes.CLICK_POINT, + EventTypes.CLICK_EMPTY, + EventTypes.CLICK_FLAG, + ] + + if instance.type in playing_events: + instance.game.status = GameStatuses.PLAYING + instance.game.save() + + elif instance.type == EventTypes.PAUSE: + instance.game.status = GameStatuses.PAUSED + instance.game.save() + + if instance.type == EventTypes.CLICK_MINE: + instance.game.status = GameStatuses.FINISHED + instance.game.win = False + instance.game.save() + + @receiver(pre_save, sender=GameEvent) def identify_click_event(sender, signal, instance, **kwargs): """ Verify what is on the naive click: mine, point or empty """