Modelando um torneio suíço em Django

votos
2

Eu estou tentando criar modelos que representam um torneio suíço , com várias rodadas. Cada todos rodada vai ser emparelhado com outro jogador, exceto no caso em que há um jogador impar para fora, quando um jogador vai ter um bye.

Eu preciso acompanhar o resultado de cada emparelhamento; ou seja, o jogador que ganhou. Além disso, eu gostaria de ser capaz de pesquisar de forma eficiente mais tarde para todos os jogadores que já jogaram contra um determinado jogador.

As coisas óbvias:

class Tournament(models.Model):
    name = models.CharField(max_length=80)

class Player(models.Model):
    name = models.CharField(max_length=80)

No começo eu estava planejando ter uma classe TournamentPairing que parecia algo como isto:

class TournamentPairing(models.Model):
    tournament = models.ForeignKey(Tournament)
    round = models.IntegerKey()
    player1 = models.ForeignKey(Player)
    player2 = models.ForeignKey(Player, null = True) # In case of a bye, this is None.
    outcome = models.CharField(max_length=1) # player1 wins, loses, bye, or tie

Mas que se sente tipo de hacky, especialmente a parte sobre player2 sendo Nenhum vezes. Além disso, eu não acho que isso facilita a procura muito bem (desde que o jogador que estamos procurando poderia ser no slot player1 ou player2).

Existe uma maneira melhor? Eu suspeito que o meu django Noob-ness está me impedindo de encontrar a solução aqui.

Publicado 11/05/2009 em 02:55
fonte usuário
Em outras línguas...                            


2 respostas

votos
5

Você pode refazer a sua classe TournamentPairing a ser mais "redondo" centric para auxiliar na tomada de consultas.

ESCOLHAS = (( 'n', 'normal'), ( 'b', 'Bye'),)

class Round(models.Model):        
    number = models.IntegerField()
    round_type = models.CharField(max_length=1, default="n", choices=CHOICES)
    tournament = models.ForeignKey(Tournament)
    players = models.ManyToManyField(Player, related_name="rounds")
    winner = models.ForeignKey(Player, null=True, related_name="round_winner") 

No caso de empate, tem ponto de campo vencedor de jogador chamado "Laço".

Então, para os seus critérios de pesquisa, para ver uma lista dos jogadores que um determinado jogador tenha jogado contra:

# grab a player 
p = Player.objects.get(name='Tom')

# see what rounds this player played in
rounds_played = p.rounds.all()

# who did this player play against?
[r.players for r in rounds_played]

# to see all rounds this player won
p.round_winner.all()
Respondeu 11/05/2009 em 06:55
fonte usuário

votos
1

Eu acho que você deve ter apenas uma única lista de jogadores e não dividi-lo em player1 e player2, aqueles podem ser construídas quando uma ronda está configurado.

Sua classe jogador poderia incluir uma lista de jogadores que têm desempenhado, e o último jogador nessa lista seria o jogador atual eles estão enfrentando. Quando você escolhe o próximo jogador alguém deve jogar, adicionar esse jogador para a lista.

class Player(Models.model):
  name = models.CharField(max_length=80)
  playersPlayed = []

Durante cada rodada, para um único jogador, simplesmente percorrer a lista global de jogadores e comparar um jogador em particular para cada elemento na playersPlayed. Se o elemento não existe, essa pessoa pode ser jogado e que o jogador deve ser então adicionado à lista. Se um jogador não pode ser encontrado para um círculo particular, então esse jogador é dado um bye.

Espero que este é, pelo menos, um ponto de partida.

Respondeu 11/05/2009 em 03:13
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more