arrays auf bestimmte weiße kombinieren

Maniac

Erfahrenes Mitglied
Hi,

Ich steh vor einen Problem das mir schon den ganzen Tag kopfzerbrechen macht.
Mein Vorhaben besteht darin, dynamisch Spielbegegnungen zu erstellen wo pro Begegnung 4 Spieler teilnehmen und kein Spieler aus dem selben Team sein darf.

Das ganze hol ich mir aus einer M<SQL-Tabelle die folgt aufgebaut ist:
Tabelle: teams; Spalten: id,teamname
Tabelle: spieler; Spalten: id,team_id,name

In der Spalte team_id steht die ID des Teams aus der Tabelle teams.

Ein Team hat immer 4 Spieler, Beispieltabelle:

teams: id=5, teamname=Team 1;
teams: id=12, teamname=Team 8;

spieler: id=1, team_id=5, name=Spieler 1;
spieler: id=2, team_id=5, name=Spieler 2;
spieler: id=3, team_id=5, name=Spieler 3;
spieler: id=4, team_id=5, name=Spieler 4;

spieler: id=25, team_id=12, name=Spieler 1;
spieler: id=26, team_id=12, name=Spieler 2;
spieler: id=27, team_id=12, name=Spieler 3;
spieler: id=28, team_id=12, name=Spieler 4;

Jetzt hab ich mir alls Spieler aus der Tabelle geholt und als Array ausgeben lassen:
Code:
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => Spieler 1
            [team_id] => 1
        )

    [1] => Array
        (
            [id] => 2
            [name] => Spieler 2
            [team_id] => 1
        )

    [2] => Array
        (
            [id] => 3
            [name] => Spieler 3
            [team_id] => 1
        )

    [3] => Array
        (
            [id] => 4
            [name] => Spieler 4
            [team_id] => 1
        )

    [4] => Array
        (
            [id] => 5
            [name] => Spieler 1
            [team_id] => 2
        )

    [5] => Array
        (
            [id] => 6
            [name] => Spieler 2
            [team_id] => 2
        )

    [6] => Array
        (
            [id] => 7
            [name] => Spieler 3
            [team_id] => 2
        )

    [7] => Array
        (
            [id] => 8
            [name] => Spieler 4
            [team_id] => 2
        )
..... geht weiter bis mehrere Hundert
)
jetzt möchte ich wie schon gesagt immer 4 Spieler mit ungleicher team_id in dieses Array packen:
Code:
Array
(
    [Begegnung 1] => Array
        (
            [Spieler 1] => Spieler 2 - team_id: 5
            [Spieler 2] => Spieler 1 - team_id: 6
            [Spieler 3] => Spieler 1 - team_id: 9
            [Spieler 4] => Spieler 4 - team_id: 10
        )

    [Begegnung2] => Array
        (
            [Spieler 1] => Spieler 1 - team_id: 5
            [Spieler 2] => Spieler 2 - team_id: 6 
            [Spieler 3] => Spieler 2 - team_id: 10 
            [Spieler 4] => Spieler 4 - team_id: 4 
        )
....weitere
)
Die Keys sind nur symbloisch als Strings hier gesetzt.
Es darf jeder Spieler auch nur einmal gesetzt werden.

Mein Ansatz war folgender:
PHP:
for($i=1;$i<=300;$i++){
	for($p=1;$p<=4;$p++){
		$arr['Begegnung'.$i]['Spieler'.$p] = '';
 // hier muss immer ein Spieler rein, vom Array $players wie oben beschrieben	
	}
			
			
}

Nur komm ich nicht drauf wie ich immer einen Spieler in das array bekomme und dieser dann in keiner anderen Begegnung mehr vorkommt.
 
Filterfunktionen sind was tolles.
PHP:
/**
 * getSet
 * @param $array            Array<Spieler>
 * @param $countPlayers     Anzahl Spieler pro Spiel
 * @return Array<Spieler>
 */
function getSet($array, $countPlayers = 4){
    for($i = 0; $i < $countPlayers; $i++){
        //Zufälliger Spieler auswählen und in den Ausgabearray schreiben
        $key = array_rand($array);        
        $players[$key] = $array[$key];
        //Alle Spieler mit der team_id des Spielers entfernen
        $array = array_filter($array, create_function('$node', "return (\$node['team_id'] != {$players[$key]['team_id']});"));
    }
    return $players;
}

Und angewendet:
PHP:
<?php
//Testdaten
$array = Array(
            Array(
                    'id' => 1,
                    'name' => 'Spieler 1',
                    'team_id' => 1
                ),
            Array(
                    'id' => 2,
                    'name' => 'Spieler 2',
                    'team_id' => 2
                ),
            Array(
                    'id' => 3,
                    'name' => 'Spieler 3',
                    'team_id' => 3
                ),
            Array(
                    'id' => 4,
                    'name' => 'Spieler 4',
                    'team_id' => 1
                ),
            Array(
                    'id' => 5,
                    'name' => 'Spieler 1',
                    'team_id' => 4
                ),
            Array(
                    'id' => 6,
                    'name' => 'Spieler 2',
                    'team_id' => 2
                ),
            Array(
                    'id' => 7,
                    'name' => 'Spieler 3',
                    'team_id' => 2
                ),
            Array(
                    'id' => 8,
                    'name' => 'Spieler 4',
                    'team_id' => 2
                )
        );
// 2 Spiele auswürfeln
print_r(getSet($array));
print_r(getSet($array));

/**
 * getSet
 * @param $array            Array<Spieler>
 * @param $countPlayers     Anzahl Spieler pro Spiel
 * @return Array<Spieler>
 */
function getSet($array, $countPlayers = 4){
    for($i = 0; $i < $countPlayers; $i++){
        //Zufälliger Spieler auswählen und in den Ausgabearray schreiben
        $key = array_rand($array);        
        $players[$key] = $array[$key];
        //Alle Spieler mit der team_id des Spielers entfernen
        $array = array_filter($array, create_function('$node', "return (\$node['team_id'] != {$players[$key]['team_id']});"));
    }
    return $players;
}


?>
 
Danke yaslaw für deine Antwort, aber das funktioniert leider nicht richtig.

Ich habe 1200 Spieler in 300 Teams verteilt in der DB stehen.
Mit deiner Funktion und dem Array der Spieler:
PHP:
function getSet($array, $countPlayers = 4){
	for($i = 0; $i < $countPlayers; $i++){
	//Zufälliger Spieler auswählen und in den Ausgabearray schreiben
	$key = array_rand($array);        
	$players[$key] = $array[$key];
	//Alle Spieler mit der team_id des Spielers entfernen
	$array = array_filter($array, create_function('$node', "return (\$node['team_id'] != {$players[$key]['team_id']});"));
	}
	return $players;
}  
		
for($i=1;$i<=300;$i++){			
	$arr[$i] = getSet($array);		
}
		
echo "<pre>";
print_r($arr);

werden Spieler trotzdem doppelt verwendet. Also ich hab mehrere Einträge gefunden wo eine Spieler-id in mehreren Begegnungen vorhanden war.
zb:
Code:
Array
(
    [1] => Array
        (
            [772] => Array
                (
                    [id] => 773
                    [name] => Spieler 1
                    [team_id] => 194
                )

            [736] => Array
                (
                    [id] => 737
                    [name] => Spieler 1
                    [team_id] => 185
                )

            [805] => Array
                (
                    [id] => 806
                    [name] => Spieler 2
                    [team_id] => 202
                )

            [177] => Array
                (
                    [id] => 178
                    [name] => Spieler 2
                    [team_id] => 45
                )

        )
)
[139] => Array
        (
            [529] => Array
                (
                    [id] => 530
                    [name] => Spieler 2
                    [team_id] => 133
                )

            [714] => Array
                (
                    [id] => 715
                    [name] => Spieler 3
                    [team_id] => 179
                )

            [609] => Array
                (
                    [id] => 610
                    [name] => Spieler 2
                    [team_id] => 153
                )

            [736] => Array
                (
                    [id] => 737
                    [name] => Spieler 1
                    [team_id] => 185
                )

        )

Die spieler-id 737 kommt bei Key[1] und [139] vor.

edit: hab jetzt mal die Funktion ohne den Filter versucht und das Ergebniß ist das gleiche. Scheint also das der Filter nicht funktioniert.

edit2: so scheint es nun zu funktionieren:
PHP:
shuffle($array);
		
		function getSet(&$array, $countPlayers = 4){
			
				for($i = 0; $i < $countPlayers; $i++){
					//Zufälliger Spieler auswählen und in den Ausgabearray schreiben
					$key = array_rand($array);        
					$players[$key] = $array[$key];
					//Alle Spieler mit der team_id des Spielers entfernen
					#$array = array_filter($array, create_function('$node', "return (\$node['team_id'] != {$players[$key]['team_id']});"));
					unset($array[$key]);
					
				}
			
			return $players;
		}  
		
		for($i=1;$i<=300;$i++){			
			$arr[$i] = getSet($array);		
		}
		
		
		
		echo "<pre>";
		print_r($arr);
 
Zuletzt bearbeitet:
Bei deiner Lösung ist nicht gatrantiert, dass in einer Runde nicht Spieler des gleichen Teams sind.

Dass jeder Spieler insgesammt nur einmal vorkommen darf, erkenn ich erst jetzt.
Ich habe die Funktion mal soweit angepasst, dass der $array-Parameter neu als Referenz übergeben wird.
Dann wird davon eine Kopie gezogen um innerhalb der Funktion gefiltert werden zu können. Die ausgewählten Spieler werden in $array gelöscht um zu verhindern dass sie anschliessend nochmals ausgewählt werden

PHP:
/**
 * getSet
 * @param $array            Array<Spieler> als Referenz
 * @param $countPlayers     Anzahl Spieler pro Spiel
 * @return Array<Spieler>
 */
function getSet(&$array, $countPlayers = 4){
    //Kopiei des Arrays erstellen
    $tempArray = $array;
    for($i = 0; $i < $countPlayers; $i++){
        //Zufälliger Spieler auswählen und in den Ausgabearray schreiben
        $key = array_rand($tempArray);        
        $players[$key] = $tempArray[$key];
        //Alle Spieler mit der team_id des Spielers entfernen
        $tempArray = array_filter($tempArray, create_function('$node', "return (\$node['team_id'] != {$players[$key]['team_id']});"));
        //Spieler aus dem Ursprungsarray entfernen
        unset($array[$key]); 
    }
    return $players;
}

PS: der shuffle() ist nicht nötig, da die getSet() den Spieler mit der Funktion array_rand() aus dem Array ausliest und somit einen zufälligen Spieler wählt.
 
Zuletzt bearbeitet:
Dieser Code funktioniert nun auch wie ich es wollte danke yaslaw :-)
Zumindest auf den ersten Blick. Es ist schwer das bei 1200 Spielern mit dem Auge zu testen *g*
das mit dem Shuffle wusste ich schon, hatte es nur noch drine vom testen.
 
Zurück