-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodels.py
More file actions
97 lines (72 loc) · 3.15 KB
/
models.py
File metadata and controls
97 lines (72 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from __future__ import annotations
from typing import Any
import chess
from django.db import models
from users.models import AnonymousSessionUser, User
from .chess_board import CustomTermination
class GameTerminations(models.IntegerChoices):
CHECKMATE = 0, "CHECKMATE"
STALEMATE = 1, "STALEMATE"
INSUFFICIENT_MATERIAL = 2, "INSUFFICIENT_MATERIAL"
FIFTY_MOVES = 3, "FIFTY_MOVES"
THREEFOLD_REPETITION = 4, "THREEFOLD_REPETITION"
TIMEOUT = 5, "TIMEOUT"
RESIGNATION = 6, "RESIGNATION"
AGREEMENT = 7, "AGREEMENT"
@staticmethod
def from_chess_termination(termination: chess.Termination | CustomTermination) -> GameTerminations:
# Swap the keys and values of TERMINATIONS and get the value of the key
return {v: k for k, v in TERMINATIONS.items()}[(termination)]
TERMINATIONS = {
GameTerminations.CHECKMATE: chess.Termination.CHECKMATE,
GameTerminations.STALEMATE: chess.Termination.STALEMATE,
GameTerminations.INSUFFICIENT_MATERIAL: chess.Termination.INSUFFICIENT_MATERIAL,
GameTerminations.FIFTY_MOVES: chess.Termination.FIFTY_MOVES,
GameTerminations.THREEFOLD_REPETITION: chess.Termination.THREEFOLD_REPETITION,
GameTerminations.TIMEOUT: CustomTermination.TIMEOUT,
GameTerminations.RESIGNATION: CustomTermination.RESIGNATION,
GameTerminations.AGREEMENT: CustomTermination.AGREEMENT,
}
COLORS = {
True: "white",
False: "black",
None: "draw",
}
class Player(models.Model):
"""
Abstraction class for the Player.
- Either has to be a regular logged-in user or an anonymous user.
"""
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
anonymousUser = models.ForeignKey(AnonymousSessionUser, null=True, on_delete=models.CASCADE)
def clean(self) -> None:
userObjects = [self.user, self.anonymousUser]
isValid = sum(item is not None for item in userObjects) == 1
if not isValid:
raise ValueError("Exactly one of user or anonymousUser must be set.")
def save(self, *args: Any, **kwargs: Any) -> None:
self.clean()
super().save(*args, **kwargs)
class Game(models.Model):
game_id = models.AutoField(primary_key=True)
player_white = models.ForeignKey(Player, related_name="player_white", on_delete=models.SET_NULL, null=True)
player_black = models.ForeignKey(Player, related_name="player_black", on_delete=models.SET_NULL, null=True)
termination = models.IntegerField(choices=GameTerminations.choices)
winner_color = models.BooleanField(null=True)
time_control = models.PositiveBigIntegerField()
date = models.DateTimeField(auto_now_add=True)
objects: models.Manager[Game]
class Meta:
get_latest_by = ["date"]
def __str__(self) -> str:
return str(self.game_id)
class Move(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
order = models.PositiveIntegerField()
move = models.CharField(max_length=5)
objects: models.Manager[Move]
class Meta:
get_latest_by = ("game", "order")
unique_together = ("game", "order")
def __str__(self) -> str:
return f"{self.game} - {self.order} - {self.move}"