Skip to content

Instantly share code, notes, and snippets.

@NikitaObukhov
Created December 10, 2015 08:10
Show Gist options
  • Save NikitaObukhov/b58a8a5a74135a2431a8 to your computer and use it in GitHub Desktop.
Save NikitaObukhov/b58a8a5a74135a2431a8 to your computer and use it in GitHub Desktop.
<?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