ola pessoal, estou a tentar criar um jogo de futebol tipo FM ao gerar o calendário da época, surge-me um problema. estou a sortear as equipas para cada jornada. mas quando começam a chegar as ultimas jornadas para sortear para cada equipa, por vezes, a equipa sorteada para essa jornada, já saiu numa outra equipa nessa mesma jornada. dá para perceber? não consigo descobrir forma de resolver isto. ou então a forma que estou a gerar o calendário não é a melhor solução... alguem me pode ajudar? senão, ajudem-me a arranjar uma boa solução para gerar cumps
Boas =) Por o que li, tens de criar algo do tipo, poens todas as equipas em uma array list, fazes o sorteio e remove a que sauí para não voltares a repetir.. Se puder explicar melhor, e/ou mostrar o codigo que está a utilizar talvez te possa ajudar.. Compr.
é o que faço. eu até fazia copy paste do código mas está bastante grande e já não pego nele +ou- desde maio... portanto estou a pensar fazer um novo código para gerar o calendário são 12 equipas. para cada equipa tenho um array onde coloco as equipas sorteadas. depois vou sorteando as equipas e fazendo verificações, ou seja, ver se a equipa sorteada já existe nessa equipa pela qual está a ser gerado o calendário e se já existe nessa jornada para uma outra equipa. fui claro? ora, aqui o problema é que por vezes a equipa sorteada ja existe nessa jornada ou nessa equipa pela qual está a gerado o calendário, e não há mais equipas para sortear. eu até fiz um algoritmo que troque essa equipa sorteada por outra ja sorteada em que não haja problema trocar, ou seja, onde essas 2 equipas não "colidam" na mesma jornada do calendário duma outra equipa. (que confusão... ) apesar de ter feito isto, voltei a ter problemas e já não me lembro quais eram e sinceramente foi bastante confuso para mim porque já estava a pensar em muita coisa... cumps
Como prometi, aqui está uma das possíveis soluções. Atenção que isto está em Java, mas acho que podes tirar umas ideias do algoritmo e passar para VB (não domino minimamente VB). Já agora, um disclaimer, este código podia estar mais bonito (fiz tudo no main, por exemplo), mas é só para tentar passar a ideia. Also, parti do principio que a "segunda mão" de cada jogo acontecia na segunda metade do campeonato. Por exemplo, se o FCPxSLB foi na jornada 1, o SLBxFCP é na jornada 12 (visto que são 12 equipas). Código: import java.util.LinkedList; import java.util.Random; public class Sorteio { public static void main(String[] args) { int num_equipas = Equipas.values().length; int num_jornadas = num_equipas*2-2; LinkedList<Jornada> jornadas = new LinkedList<Jornada>(); //Metade das jogadas (a outra metade são os jogos inversos) for(int jornada = 0 ; jornada < num_jornadas/2 ; jornada++){ Jornada nova_jornada = new Jornada(jornada+1); LinkedList<Equipas> equipas_temp = new LinkedList<Equipas>(); for(int i = 0 ; i < num_equipas ; i++)//Inicializar equipas da jornada equipas_temp.add(Equipas.values()[i]); //Cada jogo for(int jogo = 0 ; jogo < Jornada.NUM_JOGOS_JORNADA ; jogo++){ boolean jogo_valido = false; Random r = new Random(); while(!jogo_valido){ int random = r.nextInt(equipas_temp.size()); //Vai buscar 2 equipas aleatorias Equipas home = equipas_temp.get(random); equipas_temp.remove(home); random = r.nextInt(equipas_temp.size()); Equipas visitante = equipas_temp.get(random); equipas_temp.remove(visitante); //Cria um jogo com essas 2 equipas Jogo jogo_temp = new Jogo(home,visitante); //Verifica se esse jogo (ou o inverso) já aconteceu for(Jornada j : jornadas)//Em cada jornada ja existente if(j.jogoNaJornada(jogo_temp)){//Se este jogo já existe //repor equipas equipas_temp.add(home); equipas_temp.add(visitante); continue; //tenta de novo } //Jogo válido nova_jornada.addJogo(jogo_temp); jogo_valido = true; } } jornadas.add(nova_jornada); } //Segunda metade dos jogos (vai buscar cada jogo das jornadas antigas e inverte-o) for(int jornada = num_jornadas/2, jornadas_orig = 0 ; jornada < num_jornadas ; jornada++, jornadas_orig++){ Jornada nova = new Jornada(jornada+1); Jornada antiga = jornadas.get(jornadas_orig); for(int jogo = 0 ; jogo < antiga.n_jogo ; jogo++){ nova.addJogo(antiga.jogos[jogo].trocaEquipas()); } jornadas.add(nova); } imprimeJornadas(jornadas); } static void imprimeJornadas(LinkedList<Jornada> jornadas){ for(Jornada j : jornadas) System.out.println(j); } } enum Equipas{UM,DOIS,TRES,QUATRO,CINCO,SEIS,SETE,OITO,NOVE,DEZ,ONZE,DOZE} class Jornada{ Jogo jogos[]; int n_jogo = 0; int n_jornada; static final int NUM_JOGOS_JORNADA = 6; public Jornada(int n){ n_jornada = n; jogos = new Jogo[NUM_JOGOS_JORNADA]; } public void addJogo(Jogo j){ jogos[n_jogo] = j; n_jogo++; } public boolean jogoNaJornada(Jogo j){ for(int i = 0 ; i < n_jogo ; i++){ if(jogos[i].home == j.home && jogos[i].visitante == j.visitante) return true; if(jogos[i].home == j.visitante && jogos[i].visitante == j.home) return true; } return false; } public String toString(){ String r = "Jornada " + n_jornada + ": "; for(int i = 0 ; i < n_jogo ; i++){ r+=jogos[i].toString(); } return r; } } class Jogo{ Equipas home; Equipas visitante; public Jogo(Equipas home, Equipas visitante){ this.home = home; this.visitante = visitante; } public Jogo trocaEquipas(){ return new Jogo(visitante,home); } public String toString(){ return home+"x"+visitante + " \t"; } } Aqui vai um dos possíveis outputs: Código: Jornada 1: DOISxNOVE OITOxONZE QUATROxSETE CINCOxUM TRESxDEZ DOZExSEIS Jornada 2: DOZExOITO DEZxSETE UMxTRES DOISxCINCO SEISxNOVE ONZExQUATRO Jornada 3: CINCOxDOIS TRESxDEZ ONZExUM TRESxDEZ TRESxCINCO NOVExOITO Jornada 4: ONZExSETE SEISxDOZE QUATROxTRES OITOxDOZE DEZxSEIS UMxDOZE Jornada 5: UMxDOIS DEZxQUATRO DOZExNOVE SEISxCINCO ONZExTRES SETExOITO Jornada 6: DOZExUM QUATROxDEZ DEZxSETE SEISxONZE TRESxNOVE DEZxUM Jornada 7: UMxQUATRO DOZExDOIS OITOxSETE SETExONZE ONZExOITO TRESxSEIS Jornada 8: CINCOxNOVE DOISxDOZE OITOxDOZE UMxDOZE DOZExQUATRO DOISxONZE Jornada 9: DEZxONZE NOVExTRES SEISxUM OITOxQUATRO DOZExDOIS NOVExCINCO Jornada 10: DOZExCINCO UMxNOVE DOISxTRES SETExONZE ONZExONZE SETExQUATRO Jornada 11: UMxSEIS DEZxONZE SETExCINCO DOZExTRES DOISxUM ONZExOITO Jornada 12: NOVExDOIS ONZExOITO SETExQUATRO UMxCINCO DEZxTRES SEISxDOZE Jornada 13: OITOxDOZE SETExDEZ TRESxUM CINCOxDOIS NOVExSEIS QUATROxONZE Jornada 14: DOISxCINCO DEZxTRES UMxONZE DEZxTRES CINCOxTRES OITOxNOVE Jornada 15: SETExONZE DOZExSEIS TRESxQUATRO DOZExOITO SEISxDEZ DOZExUM Jornada 16: DOISxUM QUATROxDEZ NOVExDOZE CINCOxSEIS TRESxONZE OITOxSETE Jornada 17: UMxDOZE DEZxQUATRO SETExDEZ ONZExSEIS NOVExTRES UMxDEZ Jornada 18: QUATROxUM DOISxDOZE SETExOITO ONZExSETE OITOxONZE SEISxTRES Jornada 19: NOVExCINCO DOZExDOIS DOZExOITO DOZExUM QUATROxDOZE ONZExDOIS Jornada 20: ONZExDEZ TRESxNOVE UMxSEIS QUATROxOITO DOISxDOZE CINCOxNOVE Jornada 21: CINCOxDOZE NOVExUM TRESxDOIS ONZExSETE ONZExONZE QUATROxSETE Jornada 22: SEISxUM ONZExDEZ CINCOxSETE TRESxDOZE UMxDOIS OITOxONZE
Código: Public Class Sorteio Public Shared Sub main(args As String()) Dim num_equipas As Integer = Equipas.values().length Dim num_jornadas As Integer = num_equipas * 2 - 2 Dim jornadas As New LinkedList(Of Jornada)() 'Metade das jogadas (a outra metade são os jogos inversos) For jornada As Integer = 0 To num_jornadas / 2 - 1 Dim nova_jornada As New Jornada(jornada__1 + 1) Dim equipas_temp As New LinkedList(Of Equipas)() For i As Integer = 0 To num_equipas - 1 'Inicializar equipas da jornada equipas_temp.add(Equipas.values()(i)) Next 'Cada jogo For jogo As Integer = 0 To Jornada.NUM_JOGOS_JORNADA - 1 Dim jogo_valido As Boolean = False Dim r As New Random() While Not jogo_valido Dim random As Integer = r.nextInt(equipas_temp.size()) 'Vai buscar 2 equipas aleatorias Dim home As Equipas = equipas_temp.[get](random) equipas_temp.remove(home) random = r.nextInt(equipas_temp.size()) Dim visitante As Equipas = equipas_temp.[get](random) equipas_temp.remove(visitante) 'Cria um jogo com essas 2 equipas Dim jogo_temp As New Jogo(home, visitante) 'Verifica se esse jogo (ou o inverso) já aconteceu 'for(Jornada j : jornadas) //Em cada jornada ja existente ' if(j.jogoNaJornada(jogo_temp)){ //Se este jogo já existe ' //repor equipas ' equipas_temp.add(home); ' equipas_temp.add(visitante); ' continue; //tenta de novo ' } 'Jogo válido nova_jornada.addJogo(jogo_temp) jogo_valido = True End While Next jornadas.add(nova_jornada) Next 'Segunda metade dos jogos (vai buscar cada jogo das jornadas antigas e inverte-o) Dim jornada__1 As Integer = num_jornadas / 2, jornadas_orig As Integer = 0 While jornada__1 < num_jornadas Dim nova As New Jornada(jornada__1 + 1) Dim antiga As Jornada = jornadas.[get](jornadas_orig) For jogo As Integer = 0 To antiga.n_jogo - 1 nova.addJogo(antiga.jogos(jogo).trocaEquipas()) Next jornadas.add(nova) jornada__1 += 1 jornadas_orig += 1 End While imprimeJornadas(jornadas) End Sub Private Shared Sub imprimeJornadas(jornadas As LinkedList(Of Jornada)) ' for(Jornada j : jornadas) ' System.out.println(j); End Sub End Class Enum Equipas UM DOIS TRES QUATRO CINCO SEIS SETE OITO NOVE DEZ ONZE DOZE End Enum Class Jornada 'Jogo jogos[]; Private n_jogo As Integer = 0 Private n_jornada As Integer 'static final int NUM_JOGOS_JORNADA = 6; Public Sub New(n As Integer) n_jornada = n jogos = New Jogo(NUM_JOGOS_JORNADA - 1) {} End Sub Public Sub addJogo(j As Jogo) jogos(n_jogo) = j n_jogo += 1 End Sub Public Function jogoNaJornada(j As Jogo) As Boolean For i As Integer = 0 To n_jogo - 1 If jogos(i).home = j.home AndAlso jogos(i).visitante = j.visitante Then Return True End If If jogos(i).home = j.visitante AndAlso jogos(i).visitante = j.home Then Return True End If Next Return False End Function Public Function toString() As String Dim r As String = "Jornada " + n_jornada + ": " For i As Integer = 0 To n_jogo - 1 r += jogos(i).toString() Next Return r End Function End Class Class Jogo Private home As Equipas Private visitante As Equipas Public Sub New(home As Equipas, visitante As Equipas) Me.home = home Me.visitante = visitante End Sub Public Function trocaEquipas() As Jogo Return New Jogo(visitante, home) End Function Public Function toString() As String Return home + "x" + visitante + " " & vbTab End Function End Class Nota: É uma dependencia java a ter em conta. Compr.
Código: for(Jornada j : jornadas)//Em cada jornada ja existente if(j.jogoNaJornada(jogo_temp)){//Se este jogo já existe //repor equipas equipas_temp.add(home); equipas_temp.add(visitante); continue; //tenta de novo } pode transformar-se em Código: for(int i = 0 ; i < jornadas.size() ; i++)//Em cada jornada ja existente if(jornadas.get(i).jogoNaJornada(jogo_temp)){//Se este jogo já existe //repor equipas equipas_temp.add(home); equipas_temp.add(visitante); continue; //tenta de novo } se der mais jeito para passar para VB. E o outro for maluco também Código: static void imprimeJornadas(LinkedList<Jornada> jornadas){ for(int i = 0 ; i <jornadas.size() ; i++) System.out.println(jornadas.get(i)); }
xD eu nunca toquei em java... mas vou dar uma vista d'olhos e tentar passar para VB. obrigado pessoal. Mike42, sim penso que basta gerar calendário para metade da epoca porque na "2a volta" as jornadas sao iguais cumps
Código: For u = 0 To 11 'vector temporario com as equipas da 1a liga Dim eqL1(11) As String For t = 0 To 11 eqL1(t) = eqLiga1(t).nomeEquipa Next For t = 0 To 5 ReDim Preserve Jornadas(u).Jogo(t) Dim sair As Byte = 0 While sair = 0 Dim jogo As String = "" 'equipa1------------------------ Randomize() Dim nTemp As Byte = nR.Next(0, eqL1.Length) 'Jornadas(u).Jogo(t) = eqL1(nTemp) jogo = eqL1(nTemp) Dim eqT1 As String = eqL1(nTemp) 'string temporaria com a equipa sorteada para voltar a colocar no array no caso de já existir o jogo 'remover sorteado Dim lTop As Byte = UBound(eqL1) For k = nTemp To lTop - 1 eqL1(k) = eqL1(k + 1) Next ReDim Preserve eqL1(lTop - 1) 'equipa2------------------------ Randomize() nTemp = nR.Next(0, eqL1.Length) 'Jornadas(u).Jogo(t) = Jornadas(u).Jogo(t) & " x " & eqL1(nTemp) jogo = jogo & " x " & eqL1(nTemp) Dim eqT2 As String = eqL1(nTemp) 'string temporaria com a equipa sorteada para voltar a colocar no array no caso de já existir o jogo 'remover sorteado lTop = UBound(eqL1) For k = nTemp To lTop - 1 eqL1(k) = eqL1(k + 1) Next ReDim Preserve eqL1(lTop - 1) 'verificar se já existe Dim existe As Byte = 0 For q = 0 To u For w = 0 To t Dim e1 As String = Mid(jogo, 1, InStr(jogo, " x ") - 1) Dim e2 As String = Mid(jogo, InStr(jogo, " x ") + 3) Dim jogoInv As String = e2 & " x " & e1 If (Jornadas(q).Jogo(w) = jogo) Or (Jornadas(q).Jogo(w) = jogoInv) Then ReDim Preserve eqL1(UBound(eqL1) + 1) eqL1(UBound(eqL1)) = eqT1 ReDim Preserve eqL1(UBound(eqL1) + 1) eqL1(UBound(eqL1)) = eqT2 existe = 1 : Exit For End If Next If existe = 1 Then Exit For Next If existe = 0 Then 'não existe Jornadas(u).Jogo(t) = jogo : sair = 1 End If End While Next Next o código postado aqui pelo fLaSh_CF em VB, é um pouco diferente daquele que aprendi portanto tentei fazer a minha maneira. fiz da mesma forma que aqui foi postada (penso eu...) mas à minha maneira no entanto, surge-me um problema, que é o mesmo que já tinha referido. eu vou sortenado as equipas para cada jornada. estou a sortear 2 equipas e a "fazer" um jogo, por exemplo: "Arsenal - Liverpool". porém, chega a uma altura em que as 2 últimas equipas (que formam 1 jogo) para sortear para uma determinada jornada, já sairam numa outra jornada. ora como so restam 2 equipas e já foram sorteadas, o ciclo não vai parar até o VB "estourar" como o meu prof dizia como resolvo isto? cumps