""" Caribbean Stud Poker simulator; see http://thewizardofodds.com/ for rules and analysis """from random import *;from simlog import *;from casino import *;from simulator import *;from cards import *;class CommandFold( Command ):	def __init__( self ):		Command.__init__( self, "fold" );	def do( self, game ):		pass;class CaribPokerTable( GameTable ):	"CaribPoker Table: Keeps all bets"	def __init__( self ):		GameTable.__init__( self );		self.bets = {			"ante":				Bet( "ante", { 0: (1,1) } ),			#"fold":				Bet( "fold",{ 0:(1,1) } ),			"raise":			Bet( "raise", { 0:(1,1), "2pair":(2,1), "3kind":(3,1), 										"straight":(4,1), "flush":(5,1), "fullhouse":(7,1),										"4kind":(20,1), "straightflush":(50,1), "royalflush":(100,1) 										} )			};	def __str__( self ):		return string.join( map( lambda x: '%s %s'%x, self.bets.items() ), ", " );class CaribPokerGame ( CasinoGame ):	"The CaribPoker Game - contains a CaribPokerTable"	def __init__( self ):		CasinoGame.__init__( self );		self.table= CaribPokerTable();		self.shoe= PokerShoe( 6 );		self.shoe.shuffle().burn();		self.dealerCards= PokerHand();		self.playerCards= PokerHand();	def seatPlayer( self, player ):		self.player= player;	def state( self ):		return (self.dealerCards.card(0),self.playerCards);	def stateStr( self ):		return "showing:%s; player:%s" % ( self.dealerCards.card(0), str(self.playerCards) );	def place( self, bet, amount ):		self.log.msg( "game.place", bet, str(amount) );		p= self.table.place( bet, amount );		return p;	def working( self, bet ):		return self.table.working( bet );	def payout( self ):		"Basic CaribPoker payout"		self.log.msg( "game.payout", "dealer:" + str(self.dealerCards), "player:" + str(self.playerCards) );		(dHand,dRank,dHighCard)= self.dealerCards.hand();		if( dHand == "stiff" ):			self.table.win( "ante", 0 );			self.table.push( "raise" );		else:			(pHand,pRank,pHighCard)= self.playerCards.hand();			if( dRank > pRank ):				self.table.lose( "ante" );				self.table.lose( "raise" );			elif( dRank < pRank ):				self.table.win( "ante", 0 );				self.table.win( "raise", pHand );			else:	# same ranked hands, must compare scoring cards				if( dHighCard.rank > pHighCard.rank ):					self.table.lose( "ante" );					self.table.lose( "raise" );				elif( dHighCard.rank < pHighCard.rank ):					self.table.win( "ante", 0 );					self.table.win( "raise", pHand );				else:					self.log.msg( "game.payout.push", "dealer:" + str(self.dealerCards), 							str(self.dealerCards.hand()), 							"player:" + str(self.playerCards),							str(self.playerCards.hand()) );					self.table.push( "ante" );					self.table.push( "raise" );		for b in self.table.bets.keys():			self.table.lose( b );	def play( self ):		"play 1 round of CaribPoker"		self.table.clearAll(self.player);		self.dealerCards.reset();		self.playerCards.reset();		cmd= self.player.startRound( self );		self.log.msg( "game.start", str(cmd) );		cmd.do( self );				for i in range(5):			self.dealerCards.addCard( self.shoe.next() );			self.playerCards.addCard( self.shoe.next() );				self.log.msg( "game.dealer", str(self.dealerCards.card(0)) );		cmd= self.player.inRound( self );		self.log.msg( "game.inround", str(cmd) );		cmd.do( self );		self.log.msg( "game.bets", str(self.table) );		if( cmd.name == "fold" ): 			self.log.msg( "game.fold", self.stateStr() );			#self.table.bets["fold"].clear();			self.table.bets["ante"].lose();		elif( cmd.name == "raise" ):			self.log.msg( "game.raise", self.stateStr() );		else:			self.log.msg( "game.betError", str(self.table), self.stateStr() );		# resolve bets		if( self.table.working( "ante" ) ):				self.payout();		self.player.endRound( self );class CaribPokerPlayer ( Player ):	"raise on any pair"	def __init__( self, limit ):		Player.__init__( self, limit );	def startRound( self, game ):		"Place start-of-round bet"		Player.startRound( self, game );		return CommandBet( "ante", 1 );	def inRound( self, game ):		"raise or fold"		Player.inRound( self, game );		(dealer,hand)= game.state();		(name,rank,card)= hand.hand();		if( rank >= 2 ):	# pair			self.log.msg( "player.raise", str(hand) );			return CommandBet( "raise", 2 );		else:			self.log.msg( "player.fold", str(hand) );			return CommandFold();			class AKCaribPokerPlayer ( CaribPokerPlayer ):	"raise on any ace/king"	def __init__( self, limit ):		CaribPokerPlayer.__init__( self, limit );	def inRound( self, game ):		"raise or fold"		Player.inRound( self, game );		(dealer,hand)= game.state();		(name,rank,card)= hand.hand();		if( rank >= 1 ):	# ace/king			self.log.msg( "player.raise", str(hand) );			return CommandBet( "raise", 2 );		else:			self.log.msg( "player.fold", str(hand) );			return CommandFold();			class AKJCaribPokerPlayer ( CaribPokerPlayer ):	"raise on any ace/king/jack/8/3"	def __init__( self, limit ):		CaribPokerPlayer.__init__( self, limit );	def inRound( self, game ):		"raise or fold"		Player.inRound( self, game );		(dealer,hand)= game.state();		(name,rank,card)= hand.hand();		if( rank > 1 ):		# pair or better!			self.log.msg( "player.raise", str(hand) );			return CommandBet( "raise", 2 );		elif( rank == 0 ): 	# stiff			self.log.msg( "player.fold", str(hand) );			return CommandFold();		else:	# ace/king			if( hand.cards[3].rank > 11 ):				self.log.msg( "player.raise", str(hand) );				return CommandBet( "raise", 2 );			elif( hand.cards[3].rank < 11 ):				self.log.msg( "player.fold", str(hand) );				return CommandFold();			else:				if( hand.cards[2].rank > 8 ):					self.log.msg( "player.raise", str(hand) );					return CommandBet( "raise", 2 );				elif( hand.cards[2].rank < 8 ):					self.log.msg( "player.fold", str(hand) );					return CommandFold();				else:					if( hand.cards[1].rank > 3 ):						self.log.msg( "player.raise", str(hand) );						return CommandBet( "raise", 2 );					else:						self.log.msg( "player.fold", str(hand) );						return CommandFold();			class WizOddsCaribPokerPlayer ( CaribPokerPlayer ):	"Wiz.Odds 3 rules"	def __init__( self, limit ):		CaribPokerPlayer.__init__( self, limit );	def inRound( self, game ):		"raise or fold"		Player.inRound( self, game );		(dealer,hand)= game.state();		(name,rank,card)= hand.hand();		if( rank > 1 ):		# pair or better!			self.log.msg( "player.raise", str(hand) );			return CommandBet( "raise", 2 );		elif( rank == 0 ): 	# stiff			self.log.msg( "player.fold", str(hand) );			return CommandFold();		else:	# ace/king			# raise if dealer's card is 2-queen and our hand has matching card			if( dealer.rank in [2,3,4,5,6,7,8,9,10,11,12] ):				if( hand.hasRank( dealer.rank ) != None ):					self.log.msg( "player.raise", str(hand) );					return CommandBet( "raise", 2 );				else:					self.log.msg( "player.fold", str(hand) );					return CommandFold();			# raise if dealer's card is A or king, and our hand has queen or jack			elif( dealer.rank in [ 1, 13 ] ):				if( hand.hasRank( 12 ) != None or hand.hasRank( 11 ) != None ):					self.log.msg( "player.raise", str(hand) );					return CommandBet( "raise", 2 );				else:					self.log.msg( "player.fold", str(hand) );					return CommandFold();			# raise if our hand has A-K-Q and 4th highest card beats dealer's card			elif( hand[2].rank == 12 and hank[3].rank > dealer.rank ):				self.log.msg( "player.raise", str(hand) );				return CommandBet( "raise", 2 );			else:				self.log.msg( "player.fold", str(hand) );				return CommandFold();class CaribPokerPlayerFactory ( PlayerFactory ):	def __init__( self ):		PlayerFactory.__init__( self );	def newPlayer( self, name ):		if( name == "simple" ): return CaribPokerPlayer( 100 );		if( name == "wizodds" ): return WizOddsCaribPokerPlayer( 100 );		if( name == "aceking" ): return AKCaribPokerPlayer( 100 );		if( name == "acekingjack" ): return AKJCaribPokerPlayer( 100 );		else: print "unknown", name;def main():	#(log,n)= ( Simlog().instance().summary(), 100 );	(log,n)= ( Simlog().instance().detail(), 1 );	#(log,n)= ( Simlog().instance().watch(["game.payout.push"]), 10 );	a= Analyzer();	s= Simulator( CaribPokerPlayerFactory().playerSet( ["simple","aceking","acekingjack","wizodds"] ), CaribPokerGame(), a );	s.generate( n, 100 );	a.report();if( __name__ == "__main__" ):	main();