wldrumstcs
01-30-2010, 04:24 AM
Folks I am going crazy. I developed an object oriented PHP Blackjack program, and I am having trouble with part of my code that determines whether or not we should treat an Ace as an "11" or a "1" (for those who don't know, in Blackjack, you are trying to get closest to 21 by adding up your cards' values. 10s, Jacks, Queens, and Kings all have a value of 10, and Aces have a value of either 1 or 11). Below is some of my code for my card object.
<?php
class card
{
private $suit;
private $number;
private $value;
function __construct($number, $suit, $value)
{
$this->suit = $suit;
$this->number = $number;
$this->value = $value;
}
public function getsuit()
{
return $this->suit;
}
public function getNumber()
{
return $this->number;
}
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function trueNumber()
{
if($this->getNumber() == "11")
return "J";
elseif($this->getNumber() == "12")
return "Q";
elseif($this->getNumber() == "13")
return "K";
elseif($this->getNumber() == "14")
return "A";
else
return $this->getNumber();
}
}
?>
Here is the class setup for my deck object:
class deck
{
public $deck = array();
public $playerHand = array();
public $secondPlayerHand = array();
public $dealerHand = array();
public $error;
public $redeal_link;
public $isSplitting;
public $betOnHand1;
public $betOnHand2;
// lots of functions
}
Finally, here is the relevant part of my code to determine whether or not we think of each Ace as a "1" or an "11." My thinking behind this was create the $sum of your cards' value MINUS the Aces. Then, add all the aces' towards the $sum (all with a value of "11"). Then, go through those aces and set some to a value of "1" if the total $sum is greater than 21. Here is that code:
// note that the parameter $whichDeck is used in a later, irrelevant part of this code
// $this->playerHand is the users hand. It's an array.
// getValue() gets the cards value (1-11).
// trueNumber() returns the actual card (ie a 7, Jack, Queen, Ace, etc.)
public function getCurrSum($whichDeck)
{
$sum = 0;
for($i=0;$i<count($this->playerHand);$i++)
{
if($this->playerHand[$i]->trueNumber() != "A") // not an ace
{
$sum += $this->playerHand[$i]->getValue();
}
else // it's an ace. This is the dumb part of the algorithm. To make things easy, we first just treat all Aces as 11s unless that would make the $sum > 21
{
if(($sum+11) > 21) // treat Ace as a 1
{
$this->playerHand[$i]->setValue(1);
$sum += $this->playerHand[$i]->getValue();
}
else
{
$sum += 11;
}
}
}
$i=0;
while($sum > 21 && ($i != count($this->playerHand)-1)) // used to determine what we do with all the aces' values
{
if($this->playerHand[$i]->trueNumber() == "A")
{
$sum -= $this->playerHand[$i]->getValue(); //
$this->playerHand[$i]->setValue(1);
$sum += $this->playerHand[$i]->getValue();
}
$i++;
}
return $sum;
}
The problem with my code is that it will think I have a $sum > 21 if I am dealt something like "Ace, 6, 7" because it is still treating the Ace as an "11." Really, though, it should be set to a "1", which means that $sum SHOULD BE 14.
<?php
class card
{
private $suit;
private $number;
private $value;
function __construct($number, $suit, $value)
{
$this->suit = $suit;
$this->number = $number;
$this->value = $value;
}
public function getsuit()
{
return $this->suit;
}
public function getNumber()
{
return $this->number;
}
public function getValue()
{
return $this->value;
}
public function setValue($value)
{
$this->value = $value;
}
public function trueNumber()
{
if($this->getNumber() == "11")
return "J";
elseif($this->getNumber() == "12")
return "Q";
elseif($this->getNumber() == "13")
return "K";
elseif($this->getNumber() == "14")
return "A";
else
return $this->getNumber();
}
}
?>
Here is the class setup for my deck object:
class deck
{
public $deck = array();
public $playerHand = array();
public $secondPlayerHand = array();
public $dealerHand = array();
public $error;
public $redeal_link;
public $isSplitting;
public $betOnHand1;
public $betOnHand2;
// lots of functions
}
Finally, here is the relevant part of my code to determine whether or not we think of each Ace as a "1" or an "11." My thinking behind this was create the $sum of your cards' value MINUS the Aces. Then, add all the aces' towards the $sum (all with a value of "11"). Then, go through those aces and set some to a value of "1" if the total $sum is greater than 21. Here is that code:
// note that the parameter $whichDeck is used in a later, irrelevant part of this code
// $this->playerHand is the users hand. It's an array.
// getValue() gets the cards value (1-11).
// trueNumber() returns the actual card (ie a 7, Jack, Queen, Ace, etc.)
public function getCurrSum($whichDeck)
{
$sum = 0;
for($i=0;$i<count($this->playerHand);$i++)
{
if($this->playerHand[$i]->trueNumber() != "A") // not an ace
{
$sum += $this->playerHand[$i]->getValue();
}
else // it's an ace. This is the dumb part of the algorithm. To make things easy, we first just treat all Aces as 11s unless that would make the $sum > 21
{
if(($sum+11) > 21) // treat Ace as a 1
{
$this->playerHand[$i]->setValue(1);
$sum += $this->playerHand[$i]->getValue();
}
else
{
$sum += 11;
}
}
}
$i=0;
while($sum > 21 && ($i != count($this->playerHand)-1)) // used to determine what we do with all the aces' values
{
if($this->playerHand[$i]->trueNumber() == "A")
{
$sum -= $this->playerHand[$i]->getValue(); //
$this->playerHand[$i]->setValue(1);
$sum += $this->playerHand[$i]->getValue();
}
$i++;
}
return $sum;
}
The problem with my code is that it will think I have a $sum > 21 if I am dealt something like "Ace, 6, 7" because it is still treating the Ace as an "11." Really, though, it should be set to a "1", which means that $sum SHOULD BE 14.