Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- * Bart Brinkman <[email protected]> wrote this code. As long as you
- * retain this notice you can do whatever you want with this stuff. If we meet
- * some day, and you think this stuff is worth it, you can buy me a beer in return.
- */
- class Player
- {
- public $name;
- public $results = array();
- public function __construct($name)
- {
- $this->name = $name;
- }
- public function getPoints()
- {
- $points = 0;
- foreach($this->results as $result) {
- $points += $result->points;
- }
- return $points;
- }
- public function getPointsUntilRound($roundNumber)
- {
- $points = 0;
- for ($i = 0; $i < $roundNumber; $i ++) {
- if (isset($this->results[$i])) {
- $points += $this->results[$i]->points;
- }
- }
- return $points;
- }
- public function hasBye()
- {
- foreach($this->results as $result) {
- if (is_a($result, 'Bye')) return true;
- }
- return false;
- }
- public function hasPlayedAgainst(Player $player) {
- foreach($this->results as $result) {
- if ($result->against === $player) return true;
- }
- return false;
- }
- }
- class Competition
- {
- public $players = array();
- public $rounds = array();
- public function __construct($players)
- {
- $this->players = $players;
- }
- public function getNumberOfRounds()
- {
- return (int) log(count($this->players), 2);
- }
- }
- class Pair
- {
- public $player1;
- public $player2;
- public function __construct($player1, $player2)
- {
- $this->player1 = $player1;
- $this->player2 = $player2;
- }
- }
- class Round
- {
- public $competition;
- public $pairs = array();
- public function __construct(Competition $competition)
- {
- $this->competition = $competition;
- }
- public function pair($noRulesRandom)
- {
- $players = $this->competition->players;
- if ($noRulesRandom) {
- shuffle($players);
- while (count($players) > 0) {
- $player1 = array_shift($players);
- $player2 = array_pop($players);
- $this->pairs[] = new Pair($player1, $player2);
- }
- }
- else {
- while (count($players) > 0) {
- // sort players by ranking
- usort($players, function($a, $b) {
- if ($a->getPoints() == $b->getPoints()) return 0;
- return ($a->getPoints() > $b->getPoints()) ? -1 : 1;
- });
- // make sure the last Player (in an odd numbered group) doesn't have a buy (see next section why)
- // NOTE following section might mess with equally ranked players
- if (count($players) & 1) { // check only of odd number of players
- $cond = false;
- while (!$cond) {
- $lastPlayer = end($players);
- if ($lastPlayer->hasBye()) {
- array_unshift($players, array_pop($players)); // move last element to top
- }
- else $cond = true;
- }
- }
- // pair players and make sure they haven't played against eachother before
- $player1 = array_shift($players);
- $player2 = array_shift($players); // will return null if array was empty (odd number of elements only)
- if (is_a($player2, 'Player')) {
- while ($player1->hasPlayedAgainst($player2)) {
- $players[] = $player2;
- $player2 = array_shift($players);
- }
- }
- $this->pairs[] = new Pair($player1, $player2);
- }
- }
- }
- }
- abstract class Result {
- public $points;
- public $against;
- }
- class Win extends Result
- {
- public $points = 3;
- public function __construct(Player $player) {
- $this->against = $player;
- }
- }
- class Tie extends Result
- {
- public $points = 1;
- public function __construct(Player $player) {
- $this->against = $player;
- }
- }
- class Loss extends Result
- {
- public $points = 0;
- public function __construct(Player $player) {
- $this->against = $player;
- }
- }
- class Bye extends Result
- {
- public $points = 3;
- }
- // lifecycle simulation starts here, replace with persistent storage or something to that effect
- class MockCompetition extends Competition
- {
- public function run()
- {
- for ($i = 1; $i <= $this->getNumberOfRounds(); $i ++) {
- $round = new MockRound($this);
- $round->pair($i == 1 ? true : false);
- $round->play();
- $this->rounds[] = $round;
- }
- }
- }
- class MockRound extends Round
- {
- public function __construct(Competition $competition)
- {
- parent::__construct($competition);
- }
- public function play()
- {
- foreach($this->pairs as $pair) {
- $player1 = $pair->player1;
- $player2 = $pair->player2;
- $decision = rand(1, 3);
- if ($player2 == null) $decision = 4;
- if ($player1 == null) $decision = 5; // not sure if needed, trace Round::pair to be sure
- switch($decision) {
- case 1:
- $player1->results[] = new Win($player2);
- $player2->results[] = new Loss($player1);
- break;
- case 2:
- $player1->results[] = new Loss($player2);
- $player2->results[] = new Win($player1);
- break;
- case 3:
- $player1->results[] = new Tie($player2);
- $player2->results[] = new Tie($player1);
- break;
- case 4:
- $player1->results[] = new Bye;
- break;
- case 5:
- $player2->results[] = new Bye;
- break;
- }
- }
- }
- }
- // start
- $players = array(
- new Player('Luis'), //1
- new Player('Ian'), //2
- new Player('Arman'), //3
- new Player('Jakob'), //4
- new Player('Murad'), //5
- new Player('Samir'), //6
- new Player('Alexander'), //7
- new Player('Mohamed'), //8
- new Player('Arthur'), //9
- new Player('Lars'), //10
- new Player('Hugo'), //11
- new Player('Mehdi'), //12
- new Player('Adjin'), //13
- new Player('Ayoub'), //14
- new Player('Louis'), //15
- //new Player('Mathis'), //16
- );
- $competition = new MockCompetition($players);
- $competition->run();
- // output results (note that Competition::$rounds and Player::$results array keys match up)
- foreach($competition->rounds as $roundNumber => $round) {
- echo '<h2>Round ' . ($roundNumber + 1) . '</h2>';
- foreach($round->pairs as $pair) {
- echo '<ul>';
- echo '<li>' . $pair->player1->name . ' (' . $pair->player1->getPointsUntilRound($roundNumber) . ') (<em>' . get_class($pair->player1->results[$roundNumber]) . '</em>)</li>';
- echo $pair->player2 == null ? '' : '<li>' . $pair->player2->name . ' (' . $pair->player2->getPointsUntilRound($roundNumber) . ') (<em>' . get_class($pair->player2->results[$roundNumber]) . '</em>)</li>';
- echo '</ul>';
- }
- }
- usort($players, function($a, $b) {
- if ($a->getPoints() == $b->getPoints()) return 0;
- return ($a->getPoints() > $b->getPoints()) ? -1 : 1;
- });
- echo '<h2>Results</h2>';
- foreach($players as $player) {
- echo '<li>' . $player->name . ': ' . $player->getPoints() . '</li>';
- }
Advertisement
Add Comment
Please, Sign In to add comment