You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
6.8 KiB
293 lines
6.8 KiB
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
#include "player.h"
|
|
#include "defines.h"
|
|
|
|
|
|
// ================================================================
|
|
// class Player
|
|
|
|
|
|
PokerPlayer::PokerPlayer()
|
|
: m_hand()
|
|
{
|
|
m_name = "Player";
|
|
m_isHuman = false;
|
|
|
|
m_money = START_MONEY;
|
|
currentBet = 0;
|
|
|
|
isOut = false;
|
|
// random.setSeed(0);
|
|
}
|
|
|
|
|
|
PokerPlayer::~PokerPlayer()
|
|
{
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------------
|
|
|
|
|
|
void PokerPlayer::giveCardsBack()
|
|
{
|
|
m_hand.clear();
|
|
}
|
|
|
|
|
|
void PokerPlayer::giveCardBack(int cardNr)
|
|
{
|
|
m_hand.clear(cardNr);
|
|
}
|
|
|
|
|
|
/* Set skip[i] to true if the corresponding card should *not* be
|
|
* exchanged.
|
|
*/
|
|
|
|
void PokerPlayer::exchangeCards(bool skip[])
|
|
{
|
|
//TODO: improve!
|
|
// this is still a VERY simple method!
|
|
|
|
m_hand.analyze();
|
|
for (int i = 0; i < PokerHandSize; i++) {
|
|
skip[i] = m_hand.getFoundCard(i);
|
|
}
|
|
}
|
|
|
|
|
|
/* Prepare the player for a new round.
|
|
*/
|
|
|
|
void PokerPlayer::newRound()
|
|
{
|
|
giveCardsBack();
|
|
|
|
currentBet = 0;
|
|
isOut = false;
|
|
}
|
|
|
|
|
|
int PokerPlayer::bet(int origBet, bool mayRaise)
|
|
{
|
|
// NOT useable for (status == continueBet) !!!
|
|
// needs a rewrite for games with > 2 players
|
|
int bet = origBet;
|
|
|
|
// first bet minBet
|
|
currentBet = minBet;
|
|
m_money -= currentBet;
|
|
bet -= currentBet;
|
|
int newBet = bet; // bet at least the old bet
|
|
|
|
if (bet > getCash())// we don't have the money :-(
|
|
return 0;
|
|
|
|
// calculate the chances and bet any value
|
|
int chance = sortedResult();
|
|
|
|
if (chance < 350) { // 3 of a kind or better!!
|
|
newBet = maxBet - (int)random.getLong(maxBet /2);//we subtract a
|
|
// random number to hide our cards (every player would
|
|
// know we have good cards if we would bet maxBet)
|
|
}
|
|
else if (chance < 400) { // 2 pairs
|
|
newBet = bet + (int)random.getLong(maxBet /2 + origBet);
|
|
if (newBet > maxBet)
|
|
newBet = maxBet;
|
|
}
|
|
else if (chance < 500) { // one pair
|
|
newBet = bet + (int)random.getLong(maxBet /4 + 1);
|
|
if (newBet > getCash() - 2 * minBet)
|
|
newBet = bet;
|
|
if (bet >= getCash() /3)
|
|
newBet = 0;
|
|
}
|
|
else if (chance < 506) { // best card is at least a ten
|
|
newBet = bet;
|
|
if (bet >= getCash() /3)
|
|
newBet = 0;
|
|
}
|
|
else { // bad cards
|
|
if (getCash() - bet >= bet) {// we would still have some money
|
|
newBet = bet;
|
|
if (bet >= getCash() /4)
|
|
newBet = 0;
|
|
}
|
|
else
|
|
newBet = 0;
|
|
}
|
|
|
|
// and now a final re-check
|
|
if (newBet > bet) {
|
|
if (random.getLong(20) == 0)
|
|
newBet = bet;
|
|
else if (random.getLong(30) <= 1)
|
|
newBet = bet + (newBet - bet) /2;
|
|
}
|
|
|
|
if (newBet > getCash())
|
|
newBet = bet; // maybe raise only a little bit but by now just do not raise
|
|
|
|
if (!mayRaise && newBet > bet)
|
|
newBet = bet;
|
|
|
|
if (!changeBet(newBet))
|
|
return 0; // BIG error
|
|
|
|
return currentBet;
|
|
}
|
|
|
|
|
|
int PokerPlayer::raise(int origRaise)
|
|
{
|
|
// NOT useable for (status == continueRaise) !!!
|
|
// needs a rewrite for games with > 2 players
|
|
int raise = origRaise - getCurrentBet();
|
|
int newRaise = raise;
|
|
|
|
if (newRaise > getCash())// we don't have the money :-(
|
|
return 0;
|
|
|
|
// Calculate the chances and bet any value.
|
|
int chance = sortedResult();
|
|
|
|
if (chance < 350) { // 3 of a kind or better!!
|
|
newRaise = maxBet - (int)random.getLong(maxBet - maxBet /2);
|
|
// we subtract a random number to hide our cards
|
|
// (every player would know we have good cards if
|
|
// we would bet maxBet)
|
|
}
|
|
else if (chance < 400) { // 2 pairs
|
|
newRaise = raise + (int)random.getLong(maxBet /2 + origRaise + 10);
|
|
if (newRaise > maxBet)
|
|
newRaise = maxBet;
|
|
}
|
|
else if (chance < 500) { // one pair
|
|
newRaise = raise + (int)random.getLong(maxBet /4 + 1);
|
|
if (newRaise > getCash() - 2 * minBet)
|
|
newRaise = raise;
|
|
if (raise >= getCash() /2)
|
|
newRaise = 0;
|
|
}
|
|
else if (chance < 506) { // best card is at least a ten
|
|
newRaise = raise;
|
|
if (raise >= getCash() /2)
|
|
newRaise = 0;
|
|
}
|
|
else { // bad cards
|
|
if (getCash() - raise >= raise && raise <= minBet * 2) { // we would still have some money
|
|
if (raise > getCash() /2)
|
|
newRaise = 0;
|
|
else
|
|
newRaise = raise;
|
|
}
|
|
else
|
|
newRaise = 0;
|
|
}
|
|
|
|
// And now a final re-check.
|
|
if (newRaise > raise) {
|
|
if (random.getLong(20) == 0)
|
|
newRaise = raise;
|
|
else if (random.getLong(30) <= 1)
|
|
newRaise = raise + (newRaise - raise) /2;
|
|
}
|
|
|
|
if (newRaise > getCash())
|
|
newRaise = raise; // maybe raise only a little bit but by now just do not raise
|
|
|
|
if (!changeBet(newRaise))
|
|
return 0; // BIG error
|
|
|
|
return currentBet;
|
|
}
|
|
|
|
|
|
bool PokerPlayer::changeBet(int betChange)
|
|
{
|
|
if (currentBet + betChange >= 0 && getCash() - betChange >= 0) {
|
|
setCash(getCash() - betChange);
|
|
currentBet += betChange;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
int PokerPlayer::sortedResult()
|
|
{
|
|
PokerHandType result = m_hand.analyze();
|
|
|
|
//Ok, the result produced by testHand() is a little bit... uncomfortable
|
|
//so lets sort it for use in displayWinner_Computer()
|
|
//additionally we extend the values e.g. by bestCard and so on
|
|
|
|
int newResult = m_hand.getCardScore();
|
|
|
|
// FIXME: Change this so that scores are higher for better hands.
|
|
// Don't forget to change m_hand.getCardScore() as well.
|
|
switch (result) {
|
|
case RoyalFlush:
|
|
newResult += 0; // the royal flush is the best you can get
|
|
break;
|
|
case StraightFlush:
|
|
newResult += 50; // straight flush
|
|
break;
|
|
case FourOfAKind:
|
|
newResult += 100; // 4 of a kind
|
|
break;
|
|
case FullHouse:
|
|
newResult += 150; // full house
|
|
break;
|
|
case Flush:
|
|
newResult += 200; // flush
|
|
break;
|
|
case Straight:
|
|
newResult += 250; // straight
|
|
break;
|
|
case ThreeOfAKind:
|
|
newResult += 300; // 3 of a kind
|
|
break;
|
|
case TwoPairs:
|
|
newResult += 350; // two pairs
|
|
break;
|
|
case Pair:
|
|
newResult += 400; // one pair
|
|
break;
|
|
case HighCard:
|
|
{
|
|
CardValue bestCard = m_hand.findNextBest(ROOF, false);
|
|
newResult = 500 + ((int) H_ACE - (int) bestCard);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// Shouldn't get here.
|
|
assert(0);
|
|
}
|
|
|
|
return newResult;
|
|
// The lowest newResult is now the best.
|
|
}
|