Skip to content
This repository has been archived by the owner on Jul 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #64 from davidcr01/3.1
Browse files Browse the repository at this point in the history
Release v3.1.0
  • Loading branch information
davidcr01 authored Jul 12, 2023
2 parents 5705134 + d2a3dd7 commit f62c4e8
Show file tree
Hide file tree
Showing 37 changed files with 1,309 additions and 105 deletions.
4 changes: 3 additions & 1 deletion Wordle+/django/djangoproject/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
router.register(r'api/classicwordles', views.ClassicWordleViewSet)
router.register(r'api/notifications', views.NotificationsViewSet)
router.register(r'api/games', views.GameViewSet)
router.register(r'api/tournaments', views.TournamentViewSet)
router.register('api/friendlist', FriendListViewSet, basename='friendlist')
router.register('api/friendrequest', FriendRequestViewSet, basename='friendrequest')

Expand All @@ -42,9 +43,10 @@

path('api/avatar/<int:user_id>/', AvatarView.as_view(), name='avatar'),
path('api/users-info/', UserInfoAPIView.as_view(), name='user-detail'),
path('api/tournaments/', TournamentViewSet.as_view({'get': 'list'}), name='tournaments-list'),
path('api/participations/', ParticipationViewSet.as_view({'get': 'list', 'post': 'create'}), name='participations'),
path('api/list-players/', PlayerListAPIView.as_view(), name='player-list'),
path('api/games/<int:pk>/tournament/', views.GameViewSet.as_view({'patch': 'tournament'}), name='game-partial-update-tournament'),



] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
27 changes: 24 additions & 3 deletions Wordle+/django/djapi/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from django.db import models
from django import forms
from django.core.validators import MaxValueValidator
import math

from .models import CustomUser, Player, StaffCode, ClassicWordle, Notification, Tournament, Participation, FriendList, FriendRequest, Game
from .models import *

class CustomUserAdmin(UserAdmin):
model = CustomUser
Expand Down Expand Up @@ -125,12 +126,24 @@ def save_model(self, request, obj, form, change):
tournament = obj.tournament
if (tournament.num_players >= tournament.max_players):
raise forms.ValidationError("The max number of participations for this tournament has been reached.")

tournament.num_players += 1
super().save_model(request, obj, form, change)
if (tournament.num_players >= tournament.max_players):
tournament.is_closed = True
rounds = int(math.log2(tournament.max_players))
for round_number in range(1, rounds+1):
round = Round.objects.create(tournament=tournament, number=round_number)
if round_number == 1:
participants = Participation.objects.filter(tournament=tournament)
participants_count = participants.count()
for i in range(0, participants_count, 2):
player1 = participants[i].player
player2 = participants[i + 1].player
new_game = Game.objects.create(player1=player1, player2=player2, is_tournament_game=True)
RoundGame.objects.create(round=round, game=new_game)

tournament.save()
super().save_model(request, obj, form, change)

player = obj.player
message = f"You were assigned in {tournament.name}. Good luck!"
Expand Down Expand Up @@ -177,6 +190,14 @@ class FriendRequestAdmin(admin.ModelAdmin):
class GameAdmin(admin.ModelAdmin):
list_display = ('id', 'player1', 'player2', 'winner', 'word',)

class RoundAdmin(admin.ModelAdmin):
list_display = ('id', 'tournament', 'number',)

class RoundGameAdmin(admin.ModelAdmin):
list_display = ('id', 'round', 'game',)

admin.site.register(RoundGame, RoundGameAdmin)
admin.site.register(Round, RoundAdmin)
admin.site.register(Game, GameAdmin)
admin.site.register(FriendRequest, FriendRequestAdmin)
admin.site.register(FriendList, FriendListAdmin)
Expand Down
3 changes: 3 additions & 0 deletions Wordle+/django/djapi/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
class DjapiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'djapi'

def ready(self):
import djapi.signals
18 changes: 17 additions & 1 deletion Wordle+/django/djapi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Tournament(models.Model):
max_players = models.PositiveIntegerField()
word_length = models.PositiveIntegerField()
is_closed = models.BooleanField(default=False)
current_round = models.PositiveIntegerField(default=1)

def __str__(self):
return self.name
Expand Down Expand Up @@ -124,7 +125,7 @@ def __str__(self):
class Game(models.Model):
player1 = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='player1_wordle')
player2 = models.ForeignKey(Player, on_delete=models.CASCADE, related_name='player2_wordle')
word = models.CharField(max_length=255)
word = models.CharField(max_length=255, blank=True)
player1_time = models.PositiveIntegerField(default=0)
player1_attempts = models.PositiveIntegerField(default=0)
player1_xp = models.PositiveIntegerField(default=0)
Expand All @@ -133,10 +134,25 @@ class Game(models.Model):
player2_xp = models.PositiveIntegerField(default=0)
winner = models.ForeignKey(Player, on_delete=models.SET_NULL, null=True, blank=True, related_name='winner')
timestamp = models.DateTimeField(auto_now_add=True)
is_tournament_game = models.BooleanField(default=False)

def __str__(self):
return f"{self.player1.user.username} - {self.player2.user.username}"

class Round(models.Model):
tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)
number = models.PositiveIntegerField()

def __str__(self):
return f"Tournament: {self.tournament.name}, Round: {self.number}"

class RoundGame(models.Model):
round = models.ForeignKey(Round, on_delete=models.CASCADE)
game = models.ForeignKey(Game, on_delete=models.CASCADE)

def __str__(self):
return f"Round: {self.round.number}, Game: {self.game}"

# Method to add the 'Staff' group automatically when creating an administrator
@receiver(post_save, sender=CustomUser)
def assign_permissions(sender, instance, created, **kwargs):
Expand Down
9 changes: 7 additions & 2 deletions Wordle+/django/djapi/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.contrib.auth.models import Group
from .models import CustomUser, Player, StaffCode, ClassicWordle, Notification, Tournament, Participation, FriendList, FriendRequest, Game
from .models import CustomUser, Player, StaffCode, ClassicWordle, Notification, Tournament, Participation, FriendList, FriendRequest, Game, Round
from rest_framework import serializers
from django.contrib.auth.hashers import make_password

Expand Down Expand Up @@ -134,7 +134,7 @@ class Meta:
class TournamentSerializer(serializers.ModelSerializer):
class Meta:
model = Tournament
fields = ['id', 'name', 'description', 'max_players', 'num_players', 'word_length', 'is_closed']
fields = ['id', 'name', 'description', 'max_players', 'num_players', 'word_length', 'is_closed', 'current_round']

class ParticipationSerializer(serializers.ModelSerializer):
class Meta:
Expand Down Expand Up @@ -195,6 +195,11 @@ class Meta:
def get_player2(self, obj):
return obj.player2.user.username

class RoundSerializer(serializers.ModelSerializer):
class Meta:
model = Round
fields = '__all__'

class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
Expand Down
39 changes: 39 additions & 0 deletions Wordle+/django/djapi/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.dispatch import receiver
from django.db.models.signals import post_save
from .models import Game, RoundGame, Round
import math

@receiver(post_save, sender=Game)
def game_completed(sender, instance, created, **kwargs):
if instance.is_tournament_game and instance.winner:
round = Round.objects.filter(roundgame__game=instance).last()
if round:
round_games = RoundGame.objects.filter(round=round)
if all(game.game.winner for game in round_games):
tournament = round.tournament
# Get current round
current_round_number = tournament.current_round
num_rounds = int(math.log2(tournament.max_players))

# Get winners of current round
winners = [game.game.winner for game in round_games]

# If its the last round, games are not created (tournament end)
if current_round_number == num_rounds:
winner = instance.winner
winner.wins_tournament += 1
winner.xp += 1000
winner.save()
else:
# Get next round
next_round_number = current_round_number + 1
next_round = Round.objects.get(tournament=tournament, number=next_round_number)
tournament.current_round = next_round_number
tournament.save()

# Create games and assign them to the round
for i in range(0, len(winners), 2):
player1 = winners[i]
player2 = winners[i + 1]
new_game = Game.objects.create(player1=player1, player2=player2, is_tournament_game=True)
RoundGame.objects.create(round=next_round, game=new_game)
Loading

0 comments on commit f62c4e8

Please sign in to comment.