Format leaderboard in different ways.
authorCMDR furrycat <elite@furrycat.net>
Fri, 5 Feb 2016 11:37:34 +0000 (06:37 -0500)
committerCMDR furrycat <elite@furrycat.net>
Fri, 5 Feb 2016 11:56:56 +0000 (06:56 -0500)
lib/race.php

index 50b1c3f..7229679 100644 (file)
@@ -79,8 +79,9 @@
     return sprintf("%s%s%s", open_tags($formatting, $tags), $text, close_tags($formatting, $tags));
   }
 
-  function entry_header($type) {
-    $fields = array('P', 'R', 'S', 'E', 'CMDR name', 'Forum name', 'Ship name', 'Ship type', 'Distance', 'Penalty', 'Lap distance', 'Laps', 'Allotted', 'Bonus', 'Raced', 'Total', 'Best speed', 'Average speed', 'Fastest lap', 'Average lap', 'Award');
+  function entry_header($format, $type) {
+    $fields = array('R', 'S', 'E', 'CMDR name', 'Forum name', 'Ship name', 'Ship type', 'Distance', 'Penalty', 'Lap distance', 'Laps', 'Allotted', 'Bonus', 'Raced', 'Total', 'Best speed', 'Average speed', 'Fastest lap', 'Average lap', 'Award');
+    if ($format == "full") array_unshift($fields, 'P');
     $small_fields = array('Distance', 'Penalty', 'Lap distance', 'Fastest lap', 'Average lap', 'Average speed');
     if ($type == 'html') {
       echo "<table class=\"entries\">\n";
     }
   }
 
-  function show_entry($entry, $allotted_time, $position, $rank, $ship_rank, $row, $type, $prize_name) {
+  function filtered($condition, $format, $formats) {
+    return (array_key_exists($condition, $formats) && $formats[$condition][0] >= $formats[$format][0]);
+  }
+
+  function show_entry($format, $entry, $allotted_time, $position, $rank, $ship_rank, $row, $type, $prize_name) {
     $fields = array();
-    $fields[] = $position;
+    if ($format == "full") $fields[] = $position;
     $fields[] = $position ? $rank : '';
     $fields[] = $ship_rank;
     $fields[] = $entry->getEndorsementString();
       if (add_race($_POST["name"], $_POST["allotted_time"])) unset($_POST);
     }
 
+    $methods = array(
+      'distance' => 'StandardSort',
+      'best_speed' => 'ByBestSpeed',
+      'average_speed' => 'ByAverageSpeed',
+      'fastest_lap' => 'ByFastestLap',
+      'average_lap' => 'ByAverageLap'
+    );
+    $formats = array(
+      'prizes' => array(1, 'prizewinners'),
+      'ranked' => array(2, 'ranked entries'),
+      'competitors' => array(3, 'best entries'),
+      'ships' => array(4, 'best per ship'),
+      'full' => array(5, 'all entries')
+    );
+
+    $params_str = str_replace(array(' ', ':'), array('&', '='), $args);
+    parse_str($params_str, $params);
+    $sort = (array_key_exists("sort", $params)) ? $params["sort"] : null;
+    if (! in_array($sort, array_keys($methods))) $sort = 'distance';
+    $sort_method = $methods[$sort];
+    $format = (array_key_exists("format", $params)) ? $params["format"] : "ships";
+
     $rq = new RaceQuery;
     if ($action) $rq->filterById($action);
     $races = $rq->find();
       }
       if (count($entry_objects)) {
         $entries = array();
-        foreach ($entry_objects as $entry) $entries[] = $entry;
+        $entries_by_id = array();
+        foreach ($entry_objects as $entry) {
+          $entries[] = $entry;
+          $entries_by_id[$entry->getId()] = $entry;
+        }
         $prizewinners = find_prizewinners($race, $entries);
         $plots = array(
           "cmdr" => array(
         echo "var laps = " . json_encode(array_values($laps)) . ";\n";
         echo "//--></script>\n";
 
-        $methods = array(
-          'distance' => 'StandardSort',
-          'best_speed' => 'ByBestSpeed',
-          'average_speed' => 'ByAverageSpeed',
-          'fastest_lap' => 'ByFastestLap',
-          'average_lap' => 'ByAverageLap'
-        );
-        if (! in_array($args, array_keys($methods))) $args = 'distance';
-        $sort_method = $methods[$args];
         uasort($entries, "Entry::$sort_method");
       }
       else {
       echo "<div id=\"plot_laps\"></div>\n";
       echo "<div class=\"classification\">\n";
 
-      echo "<p>Sort by:";
+      /* Sort options. */
+      $uri_list = array();
       foreach (array_keys($methods) as $method) {
         $Method = ucfirst($method);
-        if ($method == $arg) echo " $Method";
+        if ($method == $sort) $uri = " $Method";
+        else {
+          $uri = preg_replace('/&args=[^&]+/', '', $_SERVER['REQUEST_URI']);
+          $uri = " <a href=\"$uri&args=sort:$method";
+          if ($format) $uri .= "+format:$format";
+          $uri .= "\">$Method</a>";
+        }
+        $uri_list[] = $uri;
+      }
+      echo "<p class=\"header\">Sort by: " . implode(" // ", $uri_list) . "</p>\n";
+
+      /* Format options. */
+      $uri_list = array();
+      foreach (array_keys($formats) as $fmt) {
+        $Fmt = ucfirst($formats[$fmt][1]);
+        if ($fmt == $format) $uri = " $Fmt";
         else {
           $uri = preg_replace('/&args=[^&]+/', '', $_SERVER['REQUEST_URI']);
-          echo " <a href=\"$uri&args=$method\">$Method</a>";
+          $uri = " <a href=\"$uri&args=";
+          if ($sort) $uri .= "sort:$sort+";
+          $uri .= "format:$fmt";
+          $uri .= "\">$Fmt</a>";
         }
+        $uri_list[] = $uri;
       }
-      echo "</p>\n";
+      echo "<p class=\"header\">Show: " . implode(" // ", $uri_list) . "</p>\n";
 
       foreach (array('html', 'bbcode') as $type) {
         echo "<div class=\"$type\">\n";
-        entry_header($type);
+        entry_header($format, $type);
         $n = $position = $rank = 1;
         $ship_entries = array();
         $competitor_entries = array();
+        $competitor_hull_entries = array();
         $excluded_competitors = array();
         foreach ($entries as $entry) {
           $entry_id = $entry->getId();
           $p = $r = $s = '';
-          $prize_name = null;
-          $competitor = $entry->getShip()->getCompetitor();
+          $ship = $entry->getShip();
+          $hull_id = $ship->getHullId();
+          $competitor = $ship->getCompetitor();
+          $competitor_id = $competitor->getId();
           $name = $competitor->getForumName();
           if (! $name) $name = $competitor->getCmdrName();
+          if (! array_key_exists($name, $competitor_hull_entries)) $competitor_hull_entries[$name] = array($hull_id => 0);
+
+          /* Is this a prize entry? */
+          if (array_key_exists($entry_id, $prizewinners["entries"])) {
+            $prize_name = $prizewinners["entries"][$entry_id];
+            $prize_entry = $entry;
+          }
+          else {
+            $prize_name = null;
+            /* If not, does this racer have a prize? */
+            if (array_key_exists($competitor_id, $prizewinners["competitors"])) {
+              $prize_entry_id = $prizewinners["competitors"][$competitor_id];
+              $prize_entry = $entries_by_id[$prize_entry_id];
+            }
+            else $prize_entry = null;
+          }
+
           if (! $entry->isExcluded()) {
-            if (array_key_exists($entry_id, $prizewinners["entries"])) $prize_name = $prizewinners["entries"][$entry_id];
-            if ($prize_name || ! array_key_exists($competitor->getId(), $prizewinners["competitors"])) {
-              if (array_key_exists($name, $competitor_entries)) $competitor_entries[$name]++;
+            if (! $prize_name) {
+              if (filtered("prizes", $format, $formats)) continue;
+              /* Exclude if there's also a prize. */
+              if ($prize_entry) {
+                if (filtered("competitors", $format, $formats)) continue;
+                if (filtered("ships", $format, $formats) && $prize_entry->getShip()->getHullId() == $hull_id) continue;
+              }
+            }
+            if ($prize_name || ! $prize_entry) {
+              /* One entry per racer per ship. */
+              if (filtered("ships", $format, $formats) && $competitor_hull_entries[$name][$hull_id]++) continue;
+
+              if (array_key_exists($name, $competitor_entries)) {
+                /* One entry per competitor. */
+                if (filtered("competitors", $format, $formats)) continue;
+                $competitor_entries[$name]++;
+              }
               else {
+                if (array_key_exists($name, $excluded_competitors) && filtered("competitors", $format, $formats)) continue;
                 $competitor_entries[$name] = 1;
                 $r = count($competitor_entries);
               }
             }
+            else {
+              /* Racer has a prize but this isn't it. */
+              /* One entry per racer per ship. */
+              if (filtered("ships", $format, $formats) && $competitor_hull_entries[$name][$hull_id]++) continue;
+              /* One entry per racer. */
+              if ((array_key_exists($name, $excluded_competitors) || array_key_exists($name, $competitor_entries)) && filtered("competitors", $format, $formats)) continue;
+            }
+            /* Ranked only. */
+            if (! $r && filtered("ranked", $format, $formats)) continue;
 
             $hull_id = $entry->getShip()->getHull()->getId();
             if (array_key_exists($hull_id, $ship_entries)) $ship_entries[$hull_id]++;
             $s = $ship_entries[$hull_id];
           }
           else {
+            /* Excluded. */
+            if (filtered("ranked", $format, $formats)) continue;
+            /* One entry per racer per ship. */
+            if ($competitor_hull_entries[$name][$hull_id]++ && filtered("ships", $format, $formats)) continue;
+            /* One entry per racer. */
+            if ((array_key_exists($name, $excluded_competitors) || array_key_exists($name, $competitor_entries)) && filtered("competitors", $format, $formats)) continue;
             $r = (array_key_exists($name, $excluded_competitors)) ? 2 : 1;
             $excluded_competitors[$name] = 1;
           }
-          show_entry($entry, $allotted_time, $p, $r, $s, $n++, $type, $prize_name);
+          show_entry($format, $entry, $allotted_time, $p, $r, $s, $n++, $type, $prize_name);
         }
         entry_footer($race, $type);
         echo "</div>\n";