Created
December 10, 2015 08:10
-
-
Save NikitaObukhov/b58a8a5a74135a2431a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Game { | |
private $doors; | |
private $winner; | |
public function __construct() { | |
$this->doors = array(0,0,0); | |
$win = rand(0, 2); | |
$this->doors[$win] = 1; | |
} | |
public function playFor(Player $player) { | |
$this->winner = null; | |
$choice = $player->chooseDoor($this->doors); | |
$door = $this->doors[$choice]; | |
for($i=0;$i<count($this->doors);$i++) { | |
if (1 !== $this->doors[$i] && $i !== $choice) { | |
$opened = $i; | |
} | |
} | |
if ($player->wantsToChangeHisChoice()) { | |
$new_doors = $this->doors; | |
$new_choice = $player->chooseNewDoor($this->doors, $opened); | |
$door = $new_doors[$new_choice]; | |
} | |
if (1 === $door) { | |
$this->winner = $player; | |
} | |
} | |
public function getWinner() { | |
return $this->winner; | |
} | |
} | |
interface Strategy { | |
public function shouldChangeChoice(); | |
} | |
class AlwaysChangeStrategy implements Strategy { | |
public function shouldChangeChoice() { | |
return true; | |
} | |
} | |
class NeverChangeStrategy implements Strategy { | |
public function shouldChangeChoice() { | |
return false; | |
} | |
} | |
class MaybeChangeStrategy implements Strategy { | |
private $probability; | |
public function __construct($probability = 0.5) { | |
$this->probability = $probability; | |
} | |
public function shouldChangeChoice() { | |
if (mt_rand(1, 1000) < $this->probability * 1000) { | |
return true; | |
} | |
return false; | |
} | |
} | |
class Player { | |
protected $name; | |
protected $strategy; | |
protected $money; | |
protected $choice; | |
public function __construct($name, Strategy $strategy, $money = 0) { | |
$this->name = $name; | |
$this->strategy = $strategy; | |
$this->money = $money; | |
} | |
public function chooseDoor(array $doors) { | |
$this->choice = rand(0, count($doors) -1); | |
return $this->choice; | |
} | |
public function chooseNewDoor(array $doors, $except) { | |
for($k=0;$k<count($doors);$k++) { | |
if ($k !== $this->choice && $k !== $except) { | |
return $k; | |
} | |
} | |
} | |
public function wantsToChangeHisChoice() { | |
return $this->strategy->shouldChangeChoice(); | |
} | |
public function getMoney() { | |
$money = $this->money; | |
$this->money = 0; | |
return $money; | |
} | |
public function getName() { | |
return $this->name; | |
} | |
public function giveMoney($money) { | |
$this->money = $money; | |
} | |
} | |
class Bouncer { | |
public function kickPlayersAss(Player $player) { | |
print sprintf('Kicked %s\'s ass<br/>', $player->getName()); | |
} | |
} | |
class Casino { | |
private $bouncer; | |
private $players; | |
private $game; | |
private $bank; | |
private $bet; | |
private $revenue; | |
public function __construct(Bouncer $bouncer, array $players, Game $game, $bet = 10) { | |
$this->bouncer = $bouncer; | |
$this->players = $players; | |
$this->game = $game; | |
$this->bank = new \SplObjectStorage(); | |
$this->bet = $bet; | |
foreach($this->players as $player) { | |
$this->bank[$player] = $player->getMoney(); | |
} | |
$this->revenue = 0; | |
} | |
public function play() { | |
$loosers = $winners = array(); | |
$bank = 0; | |
foreach($this->players as $key => $player) { | |
if ($this->bank[$player] >= $this->bet) { | |
$bank += $this->bet; | |
$this->bank[$player] -= $this->bet; | |
} | |
else { | |
$this->bouncer->kickPlayersAss($player); | |
unset($this->players[$key]); | |
continue; | |
} | |
$this->game->playFor($player); | |
if ($player === $this->game->getWinner()) { | |
$winners[] = $player; | |
} | |
else { | |
$loosers[] = $player; | |
} | |
} | |
if ($winners) { | |
$win = $bank / count($winners); | |
foreach($winners as $winner) { | |
$this->bank[$winner] += $win; | |
} | |
} | |
else { | |
$this->revenue += $bank; | |
} | |
} | |
public function getBank() { | |
return $this->bank; | |
} | |
public function getRevenue() { | |
return $this->revenue; | |
} | |
} | |
$n = 10000; | |
$players = array(); | |
$nikita = new Player('Nikita', new AlwaysChangeStrategy(), 1000); | |
$olga = new Player('Olga', new NeverChangeStrategy(), 1000); | |
$players[] = $nikita; | |
$players[] = $olga; | |
for($k=0;$k<10;$k++) { | |
$players[] = new Player('Robot'.$k, new MaybeChangeStrategy(), 1000); | |
} | |
$wins = 0; | |
$looses = 0; | |
$casino = new Casino(new Bouncer(), $players, new Game(), 10); | |
while($n > 0) { | |
$casino->play(); | |
--$n; | |
} | |
$bank = $casino->getBank(); | |
foreach($bank as $player) { | |
var_dump($player->getName() .'__'.$bank[$player]); | |
} | |
var_dump($casino->getRevenue()); | |
die; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment