<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<link rel="stylesheet" href="perch.css" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="Itsacon" />
<meta name="generator" content="Notepad++, Vim" />
<meta name="robots" content="noindex,nofollow" />

<link rel="shortcut icon" href="IIP.png" />
<title>TheDailyWTF - Knock me off my perch</title>
</head>
<body>

<?php

echo "<div>\n<form method=\"post\" action=\"".$_SERVER['PHP_SELF']."\">\n";
echo 
"<input type=\"text\" name=\"tables\" value=\"".(isset($_POST['tables']) ? $_POST['tables'] : '4')."\" /> Number of tables<br />\n";
echo 
"<input type=\"text\" name=\"cash\" value=\"".(isset($_POST['cash']) ? $_POST['cash'] : '10')."\" /> Starting Cash<br />\n";
echo 
"<input type=\"text\" name=\"target\" value=\"".(isset($_POST['target']) ? $_POST['target'] : '400')."\" /> Target<br />\n";
echo 
"<input type=\"submit\" name=\"submit\" value=\"Go\" />\n</form>\n</div>\n";

if(isset(
$_POST['submit']))
{
    
$run = new perch(intval($_POST['cash']), intval($_POST['target']), intval($_POST['tables']));
    echo 
"<div>\n";
    
$run->go();
    echo 
"</div>\n";
}

class 
spinResult
{
    protected 
$colour;
    protected 
$value;
    public function 
__construct($colour$value)
    {
        
$this->colour $colour;
        
$this->value $value;
    }
    
    public function 
getColour()
    {
        return 
$this->colour;
    }
    
    public function 
getValue()
    {
        return 
$this->value;
    }
}

abstract class 
rouletteWheel
{
    private 
$wheelValues;
    private 
$wheelColours;
    
    final public function 
__construct()
    {
        
$this->wheelValues $this->initFieldValues();
        
$this->wheelColours $this->initFieldColours();
        
        
#####    Sanity check
        
assert(count($this->wheelColours) == count($this->wheelValues));
    }
    
    abstract protected function 
initFieldValues();
    
    abstract protected function 
initFieldColours();
    
    final public function 
getFieldCount()
    {
        return 
count($this->wheelValues);
    }
    
    final public function 
getFieldValue($index)
    {
        if(
$index || $index count($this->wheelValues))
        {
            throw new 
Exception("Illegal index");
        }
        else
        {
            return 
$this->wheelValues[$index];
        }
    }
    
    final public function 
getFieldColour($index)
    {
        if(
$index || $index count($this->wheelColours))
        {
            throw new 
Exception("Illegal index");
        }
        else
        {
            return 
$this->wheelColours[$index];
        }
    }
}

class 
americanWheel extends rouletteWheel
{
    protected function 
initFieldValues()
    {
        return array(
        
'00',
        
'2',
        
'14',
        
'35',
        
'23',
        
'4',
        
'16',
        
'33',
        
'21',
        
'6',
        
'18',
        
'31',
        
'19',
        
'8',
        
'12',
        
'29',
        
'25',
        
'10',
        
'27',
        
'0',
        
'1',
        
'13',
        
'36',
        
'24',
        
'3',
        
'15',
        
'34',
        
'22',
        
'5',
        
'17',
        
'32',
        
'20',
        
'7',
        
'11',
        
'30',
        
'26',
        
'9',
        
'28');
    }
    
    protected function 
initFieldColours()
    {
        return array(
        
'g',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'g',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b',
        
'r',
        
'b');
    }    

}

class 
rouletteTable
{
    protected 
$wheel;
    public function 
__construct($type 'american')
    {
        switch(
$type)
        {
            case 
'american':
            default:
                
$this->wheel = new americanWheel();
        }
    }
    
    public function 
spin()
    {
        
$field mt_rand(0, ($this->wheel->getFieldCount() - 1));
        return new 
spinResult($this->wheel->getFieldColour($field), $this->wheel->getFieldValue($field));
    }
    
    
}
    

class 
casino
{
    private 
$tables = array();
    private 
$lastResults = array();
    
    public function 
__construct($tables$country 'american')
    {
        for(
$i 0$i $tables$i++)
        {
            
$this->tables[$i] = new rouletteTable($country);
        }
    }
    
    public function 
getTableCount()
    {
        return 
count($this->tables);
    }
    
    public function 
play()
    {
        for(
$i 0$i count($this->tables); $i++)
        {
            
$this->lastResults[$i] = $this->tables[$i]->spin();
        }
    }
    
    public function 
getLastResult($table)
    {
        if(
$table || $table count($this->lastResults))
        {
            throw new 
Exception("Illegal table");
        }
        else
        {
            return 
$this->lastResults[$table];
        }
    }
}

class 
perch
{
    private 
$tableHistory = array();
    private 
$casino;
    private 
$cash;
    private 
$target;
    private 
$roundsPlayed;
    private 
$bets = array();
    private 
$betColours = array();
    private 
$winnings = array();
    
    public function 
__construct($cash$target$tables 4$country 'american')
    {
        
$this->casino = new Casino($tables$country);
        for(
$i 0$i $tables$i++)
        {
            
$this->tableHistory[$i] = array();
            
$this->bets[$i] = 0;
            
$this->betColours[$i] = '';
            
$this->winnings[$i] = 0;
        }
        
$this->cash $cash;
        
$this->target $target;
    }
    
    public function 
go()
    {
        echo 
"<table>\n<tr><th rowspan=\"2\">Round</th>";
        for(
$i 0$i $this->casino->getTableCount(); $i++)
        {
            echo 
"<th colspan = 3>Table ".($i 1)."</th>";
        }
        echo 
"<th rowspan=\"2\">Cash</th></tr>\n<tr>";
        
        for(
$i 0$i $this->casino->getTableCount(); $i++)
        {
            echo 
"<th>Bet</th><th>Result</th><th>Winnings</th>";
        }
        echo 
"</tr>\n";
        
        for(
$this->roundsPlayed 0$this->cash >= 10 && $this->cash $this->target$this->roundsPlayed++)
        {
            
$this->applyLogic();
            
            
$this->playRound();
            
            
$this->calculateWinnings();
            
            
$this->printRound();
        }

        echo 
"</table>\n";
        
        if(
$this->cash 10)
        {
            echo 
"<p>You're broke.</p>\n";
        }
        elseif(
$this->cash >= $this->target)
        {
            echo 
"<p>You won!</p>\n";
        }
    
    }
    
    private function 
applyLogic()
    {
        if(
$this->roundsPlayed >= 4)
        {
            for(
$i 0$i $this->casino->getTableCount(); $i++)
            {
                if(
$this->bets[$i] == 0)
                {
                    
$streakLength 4;
                    
$bet 10;
                }
                elseif(
$this->bets[$i] == 10)
                {
                    
$streakLength 5;
                    
$bet 15;
                }
                else
                {
                    
$this->bets[$i] = 0;
                    
$this->betColours[$i] = '';
                    continue;
                }
                
                if(
$this->cash >= $bet)
                {

                    
$lastColour $this->tableHistory[$i][$this->roundsPlayed 1]->getColour();
                    
$streak true;
                    for(
$j = ($this->roundsPlayed $streakLength); $j < ($this->roundsPlayed 1); $j++)
                    {
                        if(
$this->tableHistory[$i][$j]->getColour() != $lastColour)
                        {
                            
$streak false;
                            break;
                        }
                    }
                    if(
$streak)
                    {
                        if(
$lastColour == 'r')
                        {
                            
$this->betColours[$i] = 'b';
                        }
                        elseif(
$lastColour == 'b')
                        {
                            
$this->betColours[$i] = 'r';
                        }
                        else
                        {
                            
$this->betColours[$i] = '';
                            
$bet 0;
                        }
                        
$this->bets[$i] = $bet;
                        
$this->cash -= $bet;
                    }
                    else
                    {
                        
$this->bets[$i] = 0;
                        
$this->betColours[$i] = '';
                    }
                }
                else
                {
                    
$this->bets[$i] = 0;
                    
$this->betColours[$i] = '';
                }
            }
        }
    }
    
    private function 
playRound()
    {
        
$this->casino->play();
            
        for(
$i 0$i $this->casino->getTableCount(); $i++)
        {
            
$this->tableHistory[$i][$this->roundsPlayed] = $this->casino->getLastResult($i);
        }
    }
    
    private function 
calculateWinnings()
    {
        for(
$i 0$i $this->casino->getTableCount(); $i++)
        {
            if(
$this->tableHistory[$i][$this->roundsPlayed]->getColour() == $this->betColours[$i])
            {
                
$this->winnings[$i] = $this->bets[$i];
                
$this->cash += ($this->bets[$i] * 2);
            }
            else
            {
                
$this->winnings[$i] = 0;
            }
        }
    }
    
    private function 
printRound()
    {
        echo 
"<tr><td>".($this->roundsPlayed 1)."</td>";
        for(
$i 0$i $this->casino->getTableCount(); $i++)
        {
            echo 
"<td".$this->colourClass($this->betColours[$i]).">\$".$this->bets[$i]."</td>";
            echo 
"<td".$this->colourClass($this->tableHistory[$i][$this->roundsPlayed]->getColour()).">".$this->tableHistory[$i][$this->roundsPlayed]->getValue()."</td>";
            echo 
"<td>".$this->winnings[$i]."</td>";
        }
        echo 
"<td>".$this->cash."</td></tr>\n";
    }
            
    private function 
colourClass($colour)
    {
        switch(
$colour)
        {
            case 
'r':
                return 
" class=\"red\"";
                break;
            case 
'b';
                return 
" class=\"black\"";
                break;
            case 
'g';
                return 
" class=\"green\"";
                break;
            case 
'':
            default:
                return 
"";
        }
    }
}