...

View Full Version : Resolved Blackjack



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.

PappaJohn
01-30-2010, 04:43 AM
Don't take this as criticism, but it's your logic that's faulty.

You have to add the values of all cards ignoring any Aces to get a subtotal, then evaluate against the number of aces that were dealt.

So, in your loop, record an ace in a separate variable (a simple counter will do) but otherwise ignore it's value. Then after the loop, check to see if any aces were dealt and evaluate each of them in turn.


Unless, of course, you're dealing with splitting aces - then the logic is a bit more involved

wldrumstcs
01-30-2010, 04:57 AM
Yes. I do have splitting in my blackjack (however, it's limited to only splitting once right now). BTW, I take no offense at all. I'd say 80% of my mistakes are logic mistakes. My question is how to implement the last part of your advice "check to see if any aces were dealt and evaluate each of them in turn." Say you have 3 aces. If you have an ace and making its value "11" doesn't bust, then you add it as an "11." When you get to the next two, you obviously would have to make them "1"s. However, this might make you bust, so you may need to go back to the first Ace and make it a 1 to keep from busting. What would the pseudocode be to do this logic? It's driving me nuts!! The saddest part is I have a BS in math and CS, but I cannot for the life of me get this to work. Very annoying.

wldrumstcs
01-30-2010, 05:03 AM
NEVERMIND. I figured it out. Thanks for your time, though!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum