Explora todo lo que te ofrecemos en Blogpocket. Por ejemplo, regístrate como miembro, para recibir el boletín semanal y acceder a contenidos exclusivos

En este blog encontrarás noticias, artículos, guías, tutoriales, manuales y cursos sobre WordPress (cómo crear un blog y un sitio web, publicar un medio digital), Redes Descentralizadas (Mastodon), IA; así como información acerca de productividad, minimalismo y slow blogging.

-> Consulta el Microblog, donde publicamos notas y apuntes breves con todo lo que estamos pensando y haciendo.

Sigue este blog vía RSS, o vía email.


Nuevo RSS Magazine, la primera revista que se lee solo mediante un lector RSS

Esto es lo que dicen nuestro usuarios

  • No soy informático profesional y me ofreces gran ayuda para conseguir cierta autonomía con WordPress
  • Me gusta más Blogpocket porque encuentro la información que necesito más rápido y sin tanto rollo.
  • Por que lo enseña todo y sin tapujos, facil de entender y de poner en práctica o tomar acción
  • Sigo blogpocket há vários anos. Conteúdos bem organizado, claros e acessíveis. Empatia pessoal pela postura e modo de comunicar de António.
  • Por contener información valiosa, claramente explicada, además de casos prácticos y actuales y explicados por un referente.

Suscríbete a nuestra newsletter «Blogpocket» y descarga los ebooks gratuitos.

Además de las entradas y los episodios del videopodcast, también puedes seguir los fediposts y, puntualmente, la newsletter vía el RSS de Blogpocket.

-> Mira todo lo que tiene el RSS: Últimas publicaciones

Mira todo lo que tiene el RSS: Últimas publicaciones

Código PdH

Este script, escrito en lenguaje PHP, funciona mejor inyectado dentro de una página de un sitio web de la plataforma WordPress. Posiblemente, contenga algún bug aunque ha sido probado concienzudamente. Es susceptible de mejorarse, de hecho esta es la versión 3.0. El propósito es no repetir emparejamientos entre los jugadores que participan en el sorteo. No se tiene en cuenta los enfrentamientos anteriores por lo que en un sorteo se puede repetir contrincante. La función aleatoria utilizada es shuffle. El algoritmo de aleatorización interna es el Generador de números aleatorios Mersenne Twister.

<?php
// Sorteo PdH
// Autor: Antonio Cambronero (Blogpocket.com)
// Versión 3.0
// Licencia: CC Atribución-NoComercial-SinDerivadas 4.0 Internacional (CC BY-NC-ND 4.0)
// Se recomienda ejecutar este código en un entorno privado
//
//
// Nombre del archivo CSV
$filename = 'PONER EL NOMBRE DEL ARCHIVO CSV AQUÍ';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Obtenemos y procesamos la lista de jugadores desde el formulario
    $playersInput = isset($_POST['players']) ? $_POST['players'] : '';
    // Convertimos la entrada en un array, eliminando espacios y líneas vacías
    $players = array_filter(array_map('trim', explode("\n", $playersInput)));

    // Verificamos que el número de jugadores sea par (para emparejarlos a todos)
    if (count($players) % 2 != 0) {
        echo "<p><strong>Error:</strong> El número de jugadores debe ser par para emparejarlos todos.</p>";
        exit;
    }
    // Verificamos la existencia del archivo CSV
    if (!file_exists($filename)) {
        echo "<p><strong>Error:</strong> El archivo CSV no se encontró.</p>";
        exit;
    }
    // Cargamos el historial de emparejamientos en un array asociativo para controlar parejas prohibidas
    $forbiddenPairs = array();
    if (($handle = fopen($filename, "r")) !== false) {
        while (($data = fgetcsv($handle, 1000, ",")) !== false) {
            // El primer campo es el jugador y los siguientes son sus parejas previas
            if (count($data) > 1) {
                $player = trim($data[0]);
                for ($i = 1; $i < count($data); $i++) {
                    $partner = trim($data[$i]);
                    if ($player !== '' && $partner !== '') {
                        // Guardamos la pareja en orden alfabético para evitar duplicados
                        $pair = array($player, $partner);
                        sort($pair, SORT_STRING);
                        $key = implode("|", $pair);
                        $forbiddenPairs[$key] = true;
                    }
                }
            }
        }
        fclose($handle);
    } else {
        echo "<p><strong>Error:</strong> No se pudo leer el archivo CSV.</p>";
        exit;
    }
    /**
     * Función que verifica si dos jugadores pueden emparejarse
     * según el historial de emparejamientos (archivo CSV).
     */
    function isPairAllowed($p1, $p2, $forbiddenPairs) {
        $pair = array($p1, $p2);
        sort($pair, SORT_STRING);
        $key = implode("|", $pair);
        return !isset($forbiddenPairs[$key]);
    }
    /**
     * Función recursiva que intenta encontrar un emparejamiento completo
     * de todos los jugadores sin repetir parejas ya realizadas.
     */
    function findMatching($players, $forbiddenPairs) {
        // Caso base: no quedan jugadores por emparejar
        if (empty($players)) {
            return array();
        }
        // Tomamos el primer jugador de la lista y lo sacamos de la lista con array_shift
        // (la lista se queda sin el jugador extraído)
        $first = array_shift($players);
        // Mezclamos aleatoriamente el resto de jugadores para introducir aleatoriedad
        shuffle($players);
        // Fin de la mezcla
        // Probamos emparejar al primer jugador con cada uno de los demás
        foreach ($players as $index => $partner) {
            if (isPairAllowed($first, $partner, $forbiddenPairs)) {
                // Creamos una copia de la lista sin el jugador emparejado
                $remaining = $players;
                unset($remaining[$index]);
                $remaining = array_values($remaining); // Reindexamos el array
                // Llamada recursiva para emparejar el resto
                $result = findMatching($remaining, $forbiddenPairs);
                if ($result !== false) {
                    // Si se encontró un emparejamiento válido, retornamos la solución parcial junto con la pareja actual
                    return array_merge(array(array($first, $partner)), $result);
                }
            }
        }
        // Si no se encontró un emparejamiento válido para este camino, retornamos false
        return false;
    }
   /**
    * Función para visualizar el historial de emparejamientos de un jugado.
    */
   function mostrarHistorialCompleto($players, $filename) {
    // Inicializar un array para almacenar el historial de cada jugador del sorteo
    $historial = array();
    foreach ($players as $jugador) {
        $historial[$jugador] = array();
    }
    // Abrir y leer el archivo CSV
    if (($handle = fopen($filename, "r")) !== false) {
        while (($data = fgetcsv($handle, 1000, ",")) !== false) {
            // El primer elemento es el jugador principal; el resto, sus compañeros
            $jugadorPrincipal = trim($data[0]);
            $companeros = array_map('trim', array_slice($data, 1));

            // Si el jugador principal está en el sorteo, agregar sus compañeros al historial
            if (in_array($jugadorPrincipal, $players)) {
                foreach ($companeros as $comp) {
                    if ($comp !== '' && !in_array($comp, $historial[$jugadorPrincipal])) {
                        $historial[$jugadorPrincipal][] = $comp;
                    }
                }
            }
            // Además, si alguno de los compañeros forma parte del sorteo,
            // se añade el jugador principal al historial de ese compañero.
            foreach ($companeros as $comp) {
                if (in_array($comp, $players)) {
                    if (!in_array($jugadorPrincipal, $historial[$comp])) {
                        $historial[$comp][] = $jugadorPrincipal;
                    }
                }
            }
        }
        fclose($handle);
    } else {
        echo "No se pudo abrir el archivo CSV";
        return;
    }
    // Mostrar el historial solo para aquellos jugadores que han jugado con todos los demás participantes.
    foreach ($historial as $jugador => $partners) {
        // Filtrar el historial para quedarnos solo con los compañeros que están en el sorteo
        $partnersSorteo = array_unique(array_intersect($partners, $players));
        // Se espera que un jugador que haya jugado con todos los demás tenga (total participantes - 1) compañeros
        if (count($partnersSorteo) === count($players) - 1) {
            echo $jugador;
            if (!empty($partnersSorteo)) {
                echo " ha jugado con... " . implode(", ", $partnersSorteo);
            }
            echo "<br />";
        }
    }
}
    // INICIO DEL PROGRAMA
    // Intentamos encontrar un emparejamiento completo
    $matching = findMatching($players, $forbiddenPairs);
    // Si no ha sido posible encontrar emparejamiento para al menos un jugador
    // entonces se muestra el historial completo de emparejamientos para aquellos
    // jugadores para los que no ha sido posible encontrar un emparejamiento
    // En ese caso, el sorteo se suspende y lo recomendable es limpiar el archivo CSV
    if ($matching === false) {
        echo "Participantes en el sorteo: ";
        foreach ($players as $player) {
           echo $player . ", ";
        }
        echo "<br />";
         mostrarHistorialCompleto($players, $filename);
        echo "<p><strong>Advertencia:</strong> No se pudo encontrar un emparejamiento válido para todos los jugadores. Se han agotado todas las combinaciones disponibles en el historial.</p><p><strong><a href='https://www.lanzatu.blog/resetear.php'>RESETEAR LA TABLA</a></strong></p>";
        exit;
    } else {
        // Si el sorteo es válido,
        // mostramos las parejas formadas (opcional) y actualizamos el archivo CSV
        // echo "<h2>Emparejamientos:</h2>";
        //echo "<ul>";
        //foreach ($matching as $pair) {
            //echo "<li>" . htmlspecialchars($pair[0]) . " - " . htmlspecialchars($pair[1]) . "</li>";
        //}
        //echo "</ul>";
        // =====================================
        // Actualización del archivo CSV
        // =====================================
       // Cargamos el contenido actual del CSV en un array asociativo: jugador => [lista de parejas]
        $partnersData = array();
        if (($handle = fopen($filename, "r")) !== false) {
            while (($data = fgetcsv($handle, 1000, ",")) !== false) {
                if (count($data) > 0) {
                    $player = trim($data[0]);
                    $partnersData[$player] = array();
                    // Los siguientes campos son los emparejamientos previos
                    for ($i = 1; $i < count($data); $i++) {
                        $p = trim($data[$i]);
                        if ($p !== '') {
                            $partnersData[$player][] = $p;
                        }
                    }
                }
            }
            fclose($handle);
        }
        // Para cada emparejamiento, actualizamos las filas correspondientes
        foreach ($matching as $pair) {
            list($p1, $p2) = $pair;
            // Actualizar para p1
            if (!isset($partnersData[$p1])) {
                $partnersData[$p1] = array();
            }
            if (!in_array($p2, $partnersData[$p1])) {
                $partnersData[$p1][] = $p2;
            }
            // Actualizar para p2
            if (!isset($partnersData[$p2])) {
                $partnersData[$p2] = array();
            }
            if (!in_array($p1, $partnersData[$p2])) {
                $partnersData[$p2][] = $p1;
            }
        }
        // Escribimos el array actualizado de vuelta en el archivo CSV
        if (($handle = fopen($filename, "w")) !== false) {
            foreach ($partnersData as $player => $partners) {
                // La primera columna es el jugador, seguido de sus emparejamientos
                $row = array_merge(array($player), $partners);
                fputcsv($handle, $row);
            }
            fclose($handle);
            //echo "<p><strong>Actualización:</strong> Los emparejamientos se han guardado en '$filename'.</p>";
        } else {
            echo "<p><strong>Error:</strong> No se pudo escribir en el archivo CSV.</p>";
        }
        // =====================================
        // Formación de partidos
        // =====================================
        //
        // Cada partido se formará combinando dos de los emparejamientos obtenidos.
        // Se mezclan aleatoriamente las parejas y se agrupan de a dos.
        //
        $pairsForDoubles = $matching;
        // Barajar para formar partidos aleatorios  
        shuffle($pairsForDoubles);
        // Fin de barajar
        $doublesMatches = array();
        // Si el número de parejas es impar, se notificará que una pareja queda sin partido
        if (count($pairsForDoubles) % 2 != 0) {
            echo "<p><strong>Advertencia:</strong> Una pareja quedó sin formar partido de dobles.</p>";
        }
             // Agrupamos de dos en dos
             for ($i = 0; $i < count($pairsForDoubles) - 1; $i += 2) {
                $doublesMatches[] = array($pairsForDoubles[$i], $pairsForDoubles[$i + 1]);
             }
        // Mostramos los partidos de dobles formados
        echo "<h3>Partidos formados:</h3>";
        echo "<ul>";
        foreach ($doublesMatches as $match) {
            list($team1, $team2) = $match;
            echo "<li>" . htmlspecialchars($team1[0]) . " y " . htmlspecialchars($team1[1]) . " vs " . htmlspecialchars($team2[0]) . " y " . htmlspecialchars($team2[1]) . "</li>";
        }
        echo "</ul>";
    }
} else {
    // Si no se envió el formulario, se muestra el formulario de entrada
    ?>
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Emparejamientos y Sorteo Grupo Barakka PdH</title>
    </head>
    <body>
        <form method="post">
            <label for="players">Ingresa la lista de jugadores (uno por línea):</label><br>
            <textarea id="players" name="players" rows="10" cols="30" placeholder=""></textarea><br>
            <input type="submit" value="Sortear">
        </form>
    </body>
    </html>
    <?php
}
?>