bholaday Posted December 13, 2009 Share Posted December 13, 2009 Hi, I am writing a script for a game that needs players to randomly be assigned a target (another player) in a loop so that each player is matched with someone other than who has them. See below: Andy matched with Jan Jan matched with Alex Alex matched with Sue Sue matched with Andy My code retrieves name from the database in the order they sign up to play. I need to randomize the pairings for fairness. <? $targets = array("Andy","Jan","Alex","Sue"); //names from DB in order of signup ?> I make a copy of the array, shuffle it and check to make sure that two players are not paired with each other. <? $targets = array("Andy","Jan","Alex","Sue"); //names from DB in order of signup $targets_shuffled = $targets; //copy array shuffle($targets_shuffled); //shuffle targets ?> I am having trouble figuring out how to check for duplicate pairings and then reshuffling until it works. Originally I had looped through the arrays to check each pairing: <? if($targets[$i] == $targets_shuffled[$i]){ echo "same!"; } ?> Then I realized when one pair was matched incorrectly the whole pairing would need to be reshuffled. I tried to flag it, break out, and reshuffle, but could never get anything that worked. Any ideas? -Blake Code currently: <? shuffle($targets_shuffled); echo "<br /><br />"; $retry = true; $tries = 1; while($retry == true){ echo "try: $tries<br />"; $retry = false; $i = 0; while($i < count($targets)){ if($targets[$i] == $targets_shuffled[$i]){ echo "found match!<br />"; $retry = true; echo "breaking<br />"; break; } $i++; } $tries++; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/ Share on other sites More sharing options...
Alex Posted December 13, 2009 Share Posted December 13, 2009 You could do something like this: $targets = array("Andy","Jan","Alex","Sue"); $available = $targets; foreach($targets as $target) { do { $rand = $targets[array_rand($available)]; } while ($rand == $target || $pairs[$rand] == $target); $pairs[$target] = $rand; $index = array_search($rand, $available); unset($available[$index]); } foreach($pairs as $player1 => $player2) { echo "$player1 matched with $player2<br />\n"; } Example output: Andy matched with Sue Jan matched with Alex Alex matched with Andy Sue matched with Jan Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976624 Share on other sites More sharing options...
bholaday Posted December 13, 2009 Author Share Posted December 13, 2009 That works well at matching, but I also need it to be a continuous loop. In the game players try to eliminate each other. They need to be in a loop so the last two people alive are trying to eliminate each other. I tried it with more names and got this result (reformatted to easily see multiple loops within the results) --loop1-- Allison matched with Kara Kara matched with Jon Jon matched with Chelsea Chelsea matched with Quinn Quinn matched with Austin Austin matched with Timothy Timothy matched with Samantha Samantha matched with Jesse Jesse matched with Allison --loop 2-- Kirk matched with Kathryn Kathryn matched with Shawn Shawn matched with Sara Sara matched with Peggy Peggy matched with Kirk I didnt know about array_search and array_rand though! Thanks for the ideas. Any way to eliminate pairing a new target with one that has already been paired, until the last pairing of course? Thanks so much for your help. Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976638 Share on other sites More sharing options...
Alex Posted December 13, 2009 Share Posted December 13, 2009 Each set of matches that gets played there should be half as many players right? How do you decide who gets removed if each player has 2 matches per round? Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976647 Share on other sites More sharing options...
bholaday Posted December 13, 2009 Author Share Posted December 13, 2009 Sorry I didnt explain this well. The game doesnt have rounds. Players are constantly trying to eliminate each other. It is not like a tournament-type pairing system where survivors move on to the next round. In the previous example, ideally Jesse would not be matched with Allison but Kirk and the last pairing would not be a match between Peggy and Kirk but would complete the loop - Peggy matched with Allison. --loop1-- Allison matched with Kara Kara matched with Jon Jon matched with Chelsea Chelsea matched with Quinn Quinn matched with Austin Austin matched with Timothy Timothy matched with Samantha Samantha matched with Jesse Jesse matched with Allison --loop 2-- Kirk matched with Kathryn Kathryn matched with Shawn Shawn matched with Sara Sara matched with Peggy Peggy matched with Kirk Ideally: --loop1-- Allison matched with Kara Kara matched with Jon Jon matched with Chelsea Chelsea matched with Quinn Quinn matched with Austin Austin matched with Timothy Timothy matched with Samantha Samantha matched with Jesse Jesse matched with Kirk Kirk matched with Kathryn Kathryn matched with Shawn Shawn matched with Sara Sara matched with Peggy Peggy matched with Allison Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976653 Share on other sites More sharing options...
Alex Posted December 13, 2009 Share Posted December 13, 2009 Didn't really answer my question. How are players eliminated? If they lose once they should be removed or what? Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976656 Share on other sites More sharing options...
bholaday Posted December 13, 2009 Author Share Posted December 13, 2009 Let's say player A is eliminated by player B. Player B will then inherit player A's target, keeping the loop intact. So, yes... players are eliminated/removed. Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-976657 Share on other sites More sharing options...
bholaday Posted December 15, 2009 Author Share Posted December 15, 2009 Does that make sense? Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-977920 Share on other sites More sharing options...
bholaday Posted December 15, 2009 Author Share Posted December 15, 2009 Found a simple solution. I copied the array, shuffled it, copied the shuffled array, and shifted the copied array indexes by one. The last unmatched value is matched with the first creating a simple loop. $targets = array("Allison","Kirk","Jesse","Quinn","Shawn","Jon","Austin","Kathryn","Samantha","Kara","Chelsea","Timothy","Sara","Peggy"); $targets_shuffled = $targets; //copy array (unnecessary, but I didnt want to mess with the original) shuffle($targets_shuffled); //shuffle array $targets_shuffled_copy = array(); //copy shuffled array $i = 0; //create counter while($i < count($targets_shuffled)){ //loop through each index if($i+1 == count($targets_shuffled)){ //if we reach the last index match it with the first $targets_shuffled_copy[$i] = $targets_shuffled[0]; //assign value to index }else{ //if we're not at the end, assign value from next index $targets_shuffled_copy[$i] = $targets_shuffled[$i+1]; //assign value to index } /* //echo results echo "<br />-------------------------<br />"; echo "i: " . $i . "<br />"; echo $targets_shuffled[$i] . " matched with " . $targets_shuffled_copy[$i]; echo "<br />-------------------------<br /><br />"; */ $i++; } This works well enough for me. Thanks for your help and ideas. -Blake Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-977971 Share on other sites More sharing options...
salathe Posted December 15, 2009 Share Posted December 15, 2009 You could also use array functions to do the manipulation of the randomised array. E.g. // Shuffle the player names $shuffled = $targets; shuffle($shuffled); // Create partners by rotating the randomly ordered names $partners = $shuffled; $partners[] = array_shift($partners); Quote Link to comment https://forums.phpfreaks.com/topic/185012-shuffle-array/#findComment-978001 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.