Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help sorting highscore - rsort()

Status
Not open for further replies.

mofle

Technical User
Apr 6, 2007
2
NO
Hi all you beautiful people

I'm making a Flashgame with a php highscore.
In my game I have a timer and I want the highscore to show me the lowest time.
But the code is created to show the best score.
I think I have to do something with the "rsort" or something.

Can anybody help me with this?

It works as it is, but the highest time is sortet to the top not the bottom.

If you help me I will include your name in the credits of the game.


Start the game and click on the button named "Highscore" to test the Highscore.

The game is far from be finished...


Code:
<?php

	$winscore = (int)$winscore;

	// Create a Blank File if it doesn't already exist
	if (!file_exists($filename))
	{
		$file=fopen($filename, "w");
		fclose ($file);
	}

	// Read the file in
	$oscores = file ($filename);
	$numreadin = count($oscores);

	// Break out the data into a new 2-d array called $tscores
	for ($i = 0; $i < $numreadin; $i++)
	{
		$g = unserialize($oscores[$i]);
		$tscores[$i][0] = $g[0];
		$tscores[$i][1] = $g[1];
	}

	// Fill in any missing data with none/0
	for ($i = $numreadin; $i < $scoresize; $i++)
	{
		$tscores[$i][0] = 0;
		$tscores[$i][1] = "none";
	}

	// Process the actions	

	// Insert a score/name
	if ($action == "INSERT")
	{

		// Add name to end of list, and sort
		$tscores[$scoresize + 1][0] = $winscore;
		$tscores[$scoresize + 1][1] = $winname;
		rsort ($tscores);

		$file=fopen($filename, "w");

		// Write them out
		for ($i = 0; $i < $scoresize; $i++)
		{
			$st = serialize($tscores[$i]) . "\n";
			fputs($file, $st);
		}

		fclose($file);
	}

	// Clear the list	
	if ($action == "CLEAR")
	{

		$k[0] = 0;
		$k[1] = "none";
		$ser = serialize($k);

		$file=fopen($filename, "w");

		for ($i = 0; $i < $scoresize; $i++)
		{
			$st = $ser . "\n";
			fputs($file, $st);
		}

		fclose($file);
	}

	// Process the OUTPUT options
	if ($viewtype == "HTML")
	{
	  // HTML PAGE CREATED HERE
	  ?>


		<table cellpadding=2 cellspacing=2 border=0 width="152">
		<tr align=center> 
		<th bgcolor="#000033"><font color="#FFFFFF" face="Arial, Helvetica, sans-serif">#</font></th>
		<th bgcolor="#000033"><font color="#FFFFFF" face="Arial, Helvetica, sans-serif">Name</font></th>
		<th bgcolor="#000033"><font color="#FFFFFF" face="Arial, Helvetica, sans-serif">Score</font></th>
		</tr>

   	  <?
	
		for ($i = 0; $i < $scoresize; $i++)
		{
			echo ("<tr bgcolor='#666666' align='center'><td><font size='2' face='Arial, Helvetica, sans-serif'>");
			echo ($i + 1);
			echo ("</font></td><td><font size='2' face='Arial, Helvetica, sans-serif'>");
			echo ($tscores[$i][1]);
			echo ("</font></td><td><font size='2' face='Arial, Helvetica, sans-serif'>");
			echo ($tscores[$i][0]);
			echo ("</font></td></tr>");
		}

  	  ?>
		</table>
	  <?

	}

	// FLASH DATA CREATED HERE
	if ($viewtype == "FLASH")
	{
		for ($i = 0; $i < $scoresize; $i++)
		{
			echo ("NAME" . $i . "=");
			echo ($tscores[$i][1]);
			echo ("&SCORE" . $i . "=");
			echo ($tscores[$i][0]);
			echo ("&");
		}
	}

?>
 
Try changing rsort() to sort(). sort() will sort and array from lowest to highest. rsort() is reverse sort.
 
Hi, I tried, but it didn't work.

And I think I have to do something more, cause the code not only sort, but also finds out which score is the highest and put it on the top.

And I need the code to exactly that in reverse.
 
i think the shape of your array is the problem. rsort works on the main array and the values are themselves arrays. i'm surprised you get anything meaningful.

i would keep two arrays one of the scores and one of the times, using the player's names as the key in each case. then it's just a case of:

Code:
asort($player_times); //sort in declining order maintaining indices
reset($player_times); //make sure we are at the top of the array
$lowest_times = each ($player_times); //extract the first key value pair
$time = $lowest_time['value'];  //get the time
$playername = $lowest_time['key']; //get the name
echo "the lowest time was $time achieved by $playername";
 
Here's another option:
Code:
	function array_msort($array, $subkey, $ASC=TRUE){
		if(!is_array($array) || sizeof($array) < 2)
			return $array;

		foreach ($array as $key=>$val) 
			$sort_values[$key] = $val[$subkey];

		if($ASC)
			asort($sort_values);
		else
			arsort($sort_values);
		
		foreach($sort_values as $key=>$val)
			$sorted_arr[$key] = $array[$key];

		return $sorted_arr;
	}

I used this function previously when I needed a sort by a sub-level key on multi-dimensional arrays. My array was generally [x][20] so it would have been unwieldy sto split it up into multiple arrays.

Basically the function takes an array, the key from the sub-arrays you want to sort on, and a boolean (defaults to TRUE) that indicates whether you want an Ascending (T) or Descending (F) sort.

It creates a temporary array of just the values you want to sort with the top level array keys, sorts them, then rebuilds the full array based on that sorted set of keys.

If anyone see's any issues with this, please let me know. I am by no means a PHP guru, I just have spent a lot of time banging my head against the desk :)

-T

 
it's horses for courses. my rule of thumb is that if you have to reorganise your array to get a desired result, then you haven't built your array properly to start with: don't build a multi-dimensional array if you have to sort it by a key=>value pair inside a secondary dimension.
 
Another option (that I didn't remember earlier) would be to use usort(), a php function designed to work with a custom compare function. If you look at the php.net manual it has an example of using this with a multidimensional array and for sorting arrays of objects.

Out of curiosity, what is the advantage of using multiple arrays instead of a multi-dimension array to organize your data? Does this not add complexity to the code in order to keep them aligned, or reduce capabilities if you do not want to add the complexity? Or are you suggesting the use of objects instead of an array? Or an array of objects using a built-in compare function?

 
what is the advantage of using multiple arrays instead of a multi-dimension array to organize your data?

sorting.

i don't think usort is the tool here. i can't see how it would benefit other than by using the callback to sever the arrays. am I missing something? can you provide an example of how you see it working, Tarwn?

there is, of course, array multi sort but even for that you would first need to make the array columnar rather than "row" based.
 
Again, remember I am not an expert with PHP and with 50 ways to do each thing I don't necessarily pick the best one :)

To use usort() to sort the above array I think you would do something along the lines of:
Code:
function compare($a,$b){
   if($a[0] == $b[0])
      return 0;
   else
      return ($a > $b)?1:-1;
}

//sort the tscores array
usort($tscores, "compare");

Obviously this would sort ascending. For a descending sort you would switch the greater than comparison to a less than or use array_reverse after the sort.

-T

 
Oops, I mistyped that, guess I should have tried it, I only just noticed it:
Code:
function compare($a,$b){
   if($a[0] == $b[0])
      return 0;
   else
      return ($a[highlight][0][/highlight] > $b[highlight][0][/highlight])?1:-1;
}

//sort the tscores array
usort($tscores, "compare");

 
it appeared to work without the qualification.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top