equipos()->get()->values()->toArray(); $n = count($equipos); if ($n < 2) { throw new \InvalidArgumentException('Se necesitan al menos 2 equipos para generar un fixture.'); } // Si número impar, agregar BYE $hayBye = false; if ($n % 2 !== 0) { $equipos[] = null; // BYE $n++; $hayBye = true; } $mitad = $n / 2; $jornadas = $n - 1; $partidos = []; $fechaActual = Carbon::parse($fechaInicio); // Algoritmo Round-Robin: fijar el primer equipo, rotar el resto $lista = range(0, $n - 1); for ($jornada = 0; $jornada < $jornadas; $jornada++) { $jornadaPartidos = []; for ($i = 0; $i < $mitad; $i++) { $localIdx = $lista[$i]; $visitanteIdx= $lista[$n - 1 - $i]; // Si alguno es BYE (null), saltar if ($equipos[$localIdx] === null || $equipos[$visitanteIdx] === null) continue; $local = $equipos[$localIdx]; $visitante = $equipos[$visitanteIdx]; // Alternar localía: en jornadas pares, invertir if ($jornada % 2 === 1) { [$local, $visitante] = [$visitante, $local]; } $jornadaPartidos[] = [ 'id_equipo_local' => $local['id_equipo'], 'id_equipo_visitante' => $visitante['id_equipo'], 'fecha_evento' => $fechaActual->format('Y-m-d'), 'hora_inicio' => '20:00:00', 'hora_fin' => '22:00:00', 'sede' => $sedeDefault, 'id_torneo' => $torneo->id, 'nombre_evento' => null, // se genera automáticamente 'precio' => 0, 'jornada' => $jornada + 1, ]; } $partidos = array_merge($partidos, $jornadaPartidos); $fechaActual->addDays($diasEntreJornadas); // Rotar la lista (el primer elemento fijo) $rotatable = array_slice($lista, 1); array_push($rotatable, array_shift($rotatable)); $lista = array_merge([$lista[0]], $rotatable); } // Doble rueda: agregar vuelta con localías invertidas if ($dobleRueda && !empty($partidos)) { $vuelta = []; foreach ($partidos as $p) { $vuelta[] = array_merge($p, [ 'id_equipo_local' => $p['id_equipo_visitante'], 'id_equipo_visitante' => $p['id_equipo_local'], 'fecha_evento' => Carbon::parse($p['fecha_evento'])->addDays($jornadas * $diasEntreJornadas)->format('Y-m-d'), 'jornada' => $p['jornada'] + $jornadas, ]); } $partidos = array_merge($partidos, $vuelta); } return $partidos; } /** * Persiste el fixture generado como Evento records en la DB. */ public function persistirFixture(array $partidos, Torneo $torneo): int { $contador = 0; foreach ($partidos as $p) { $local = Equipo::with('club')->find($p['id_equipo_local']); $visitante = Equipo::with('club')->find($p['id_equipo_visitante']); $nombreEvento = ($local->club->nombre ?? '?') . ' vs ' . ($visitante->club->nombre ?? '?'); \App\Models\Evento::create([ 'id_evento' => uniqid('ev_'), 'nombre_evento' => $nombreEvento, 'id_equipo_local' => $p['id_equipo_local'], 'id_equipo_visitante' => $p['id_equipo_visitante'], 'fecha_evento' => $p['fecha_evento'], 'hora_inicio' => $p['hora_inicio'], 'hora_fin' => $p['hora_fin'], 'sede' => $p['sede'] ?: null, 'id_torneo' => $torneo->id, 'precio' => $p['precio'] ?? 0, ]); $contador++; } return $contador; } }