Skip to content

Commit

Permalink
some changes I think
Browse files Browse the repository at this point in the history
  • Loading branch information
Tankman61 committed Jul 30, 2024
1 parent 298a131 commit 957a611
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 62 additions & 4 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,42 @@ class Profile(models.Model):
choices=[(str(i), str(i)) for i in range(1, 12)] + [('<1', '<1'), ('>12', '>12')],
default='11')
friends = models.ManyToManyField(User, related_name='friends', blank=True)
elo_rating = models.IntegerField(default=1500) # Starting ELO rating
problems_solved = models.IntegerField(default=0)
country = models.CharField(max_length=2, default='US')
max_streak = models.IntegerField(default=0)
def update_elo(self, opponent_elo, result):
k = 32 # K-factor for ELO calculation
expected_score = 1 / (1 + 10 ** ((opponent_elo - self.elo_rating) / 400))
new_elo = self.elo_rating + k * (result - expected_score)
self.elo_rating = int(new_elo)
self.save()
def increment_problems_solved(self):
self.problems_solved += 1
self.save()

def ProfilePhoto(self):
pass

# Add more fields as necessary

def __str__(self):
return f"{self.user.username}'s Profile"

class Ranking(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
rank = models.PositiveIntegerField(unique=True)
last_updated = models.DateTimeField(auto_now=True)

class Meta:
ordering = ['rank']

def __str__(self):
return f"{self.user.username} - Rank {self.rank}"

@classmethod
def update_rankings(cls):
profiles = Profile.objects.all().order_by('-elo_rating', '-problems_solved')
for index, profile in enumerate(profiles, start=1):
ranking, created = cls.objects.get_or_create(user=profile.user)
ranking.rank = index
ranking.save()

class Room(models.Model):
user1 = models.ForeignKey(User, related_name='room_user1', on_delete=models.CASCADE)
Expand All @@ -79,8 +106,39 @@ def is_battle_ended(self):
def __str__(self):
return f"Room {self.id} by {self.user1.username} and {self.user2.username if self.user2 else 'empty'}"

def end_battle(self):
if self.user1_score > self.user2_score:
self.winner = self.user1
result_user1, result_user2 = 1, 0
elif self.user2_score > self.user1_score:
self.winner = self.user2
result_user1, result_user2 = 0, 1
else:
self.winner = None
result_user1 = result_user2 = 0.5

self.status = 'Ended'
self.save()

# Update ELO ratings
user1_profile = self.user1.profile
user2_profile = self.user2.profile
user1_profile.update_elo(user2_profile.elo_rating, result_user1)
user2_profile.update_elo(user1_profile.elo_rating, result_user2)

# Update problems solved
user1_profile.problems_solved += self.questions.count()
user2_profile.problems_solved += self.questions.count()
user1_profile.save()
user2_profile.save()

# Update global rankings
Ranking.update_rankings()
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.status == 'Ended' and not hasattr(self, '_battle_ended'):
self._battle_ended = True
self.end_battle()
if not self.questions.exists() and self.user1 and self.user2:
self.questions.set(Question.get_random_questions(10))
for question in self.questions.all():
Expand Down
2 changes: 1 addition & 1 deletion api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ProfileSerializer(serializers.ModelSerializer):

class Meta:
model = Profile
fields = ['id', 'user', 'biography', 'grade']
fields = ['id', 'user', 'biography', 'grade', 'max_streak', 'elo_rating', 'country']
depth = 1


Expand Down
3 changes: 3 additions & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

path('profile/', views.profile_view, name='profile'),
path('profile/update_biography/', views.update_biography, name='update_biography'),

path('profile/update_rankings/', views.update_ranking, name='update_ranking'),
path('profile/update_streak/', views.update_streak, name='update_streak'),
path('profile/search/', views.search_users, name='search_users'),
path('profile/send_friend_request/', views.send_friend_request, name='send_friend_request'),
path('profile/respond_friend_request/<int:request_id>/', views.respond_friend_request, name='respond_friend_request'),
Expand Down
50 changes: 50 additions & 0 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,56 @@ def list_friends(request):
serializer = ProfileSerializer(profiles, many=True)
return Response(serializer.data)

@api_view(['PATCH'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
def update_ranking(request, user_id):
try:
# Fetch the profile of the authenticated user
profile = Profile.objects.get(user=request.user)
except Profile.DoesNotExist:
return Response({'error': 'Profile not found'}, status=status.HTTP_404_NOT_FOUND)

# Get the new streak value from the request data
new_streak = request.data.get('max_streak')

if new_streak is None:
return Response({'error': 'max_streak is required'}, status=status.HTTP_400_BAD_REQUEST)

# Compare the new streak with the current max streak
if new_streak > profile.max_streak:
profile.max_streak = new_streak
profile.save()
return Response(ProfileSerializer(profile).data, status=status.HTTP_200_OK)

return Response({'max_streak': profile.max_streak}, status=status.HTTP_200_OK)

@api_view(['PATCH'])
@authentication_classes([JWTAuthentication])
@permission_classes([IsAuthenticated])
def update_streak(request):
try:
# Fetch the profile of the authenticated user
profile = Profile.objects.get(user=request.user)
except Profile.DoesNotExist:
return Response({'error': 'Profile not found'}, status=status.HTTP_404_NOT_FOUND)

# Get the new streak value from the request data
new_streak = request.data.get('max_streak')

if new_streak is None:
return Response({'error': 'max_streak is required'}, status=status.HTTP_400_BAD_REQUEST)

# Compare the new streak with the current max streak
if new_streak > profile.max_streak:
profile.max_streak = new_streak
profile.save()
return Response(ProfileSerializer(profile).data, status=status.HTTP_200_OK)

return Response({'max_streak': profile.max_streak}, status=status.HTTP_200_OK)




@api_view(['GET'])
@authentication_classes([JWTAuthentication])
Expand Down
2 changes: 2 additions & 0 deletions satduel/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

urlpatterns = [
path('admin/', admin.site.urls),

path('api/', include('api.urls')),

path('auth/', include('dj_rest_auth.urls')),
path('auth/registration/', include('dj_rest_auth.registration.urls')),
path('accounts/', include('allauth.urls')), # allauth urls
Expand Down

0 comments on commit 957a611

Please sign in to comment.