Russian BS - Submissions accepted until October 13th

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite
2












The ChatRoom is here



I love playing the card game BS, but sometimes, it just doesn't have enough oomph for my short attention span. Instead, let's play some Russian BS.



Rules



Here is a quick guide to the rules.



  • The game begins with a random player declaring the card type of the round (out of 14 options: A,2,3...10,J,Q,K,j where the j stands for joker)

  • The same player starts the round, placing down as many cards as he or she wants, which all have to be of the declared card type.

  • Any player can call BS on the play. If multiple players call BS, the player closest to the player who put down the cards to the right will be the one to call BS

  • If BS is called on the play, then the cards played there are checked by the moderator. If the cards were indeed valid (i.e., all of the declared type or jokers), the player who called BS will take all of the cards played in the round. Otherwise, the player who played the invalid cards will take all of them.

  • If no BS is called, the next player is up to play, and must also play the declared card type.

  • We also allow players to pass their turn if they don't wish to play. However, if they pass, they are not allowed to play for the rest of the round (although they can call BS)

  • If every player passes, then the round ends, and the player who played the last cards will start the next round by declaring the card type.

  • If BS is called, the player who played the cards will start the next round and declare if he played valid cards, else the player who called BS will start.

  • The player who has no cards at the end of the game wins.

I like these rules because they don't force you to lie, but usually, players tend to lie more than in the original version of BS



Challenge



This challenge will be a king-of-the-hill challenge, with submissions providing bots to play the game. The bots will be written in Python 3, although I'll try my best to accommodate all submissions.



The submissions should consist of the following three functions:



CallBS - determines whether you seek to call BS or not on a play
PlayCards - determines what cards you want to play
StartRound - determines what the declared type of the round is, if you are chosen to pick it.


The submitted functions should be named such that their names are ***_CallBS, ***_PlayCards, and ***_StartRound, where *** is the name of your bot.



Below are example functions that describe the inputs and outputs:



def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
'''This function will output True if the bot seeks to call BS on the
current move, or False if not. The parameters are
- self: class variable
- pos: int - how many positions away you are to the right of the player (Note: if
your function got called, that means everyone to your left before the player decided
not to call BS)
- player: str - holds the name of the bot who just played cards
- handSize: int - how many cards playing bot holds
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numCards: int - number of cards just played by player
- numPile: int - number of cards in the pile (not including played cards this turn)
'''
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
'''This function will output a sublist of the hand of the bot to play this turn, or None to pass.
The parameters are
- self: class variable
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numPile: int - number of cards in the pile
- stillPlaying: list of str - players who haven't passed this round
'''
return self.hand[:]
def example_StartRound(self):
'''This function will output a string representing the card that will be played for the coming round (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
The parameters are
- self: class variable
'''
return 'A'


In addition, you will be provided with the following utilities



self.obj - A blank object for your usage to store knowledge between calls
self.hand: list of card objects - Your current hand in card objects (calling card.val gives you the str value of the card)
self.numBots: int - number of competitors you have
self.getRandom(): function - outputs a random number from 0 to 1.


If you want to use any sort of randomness, you must use the self.getRandom() function provided. You may not edit any of these objects except for self.obj



Parameters and more Rules



  • The cards in this game (you'll see the class that the cards belong to in the controller below) don't have a suit since suits don't matter to this game.

  • The number of cards in the game will be 14*number of bots (numBots of each type of card)

  • In the output of PlayCards, you must output cards that are in your hand. The program will not like you otherwise. You also must output card objects, not strings.

  • You may take at most 10 ms on average over 5 turns for StartRound, 50 ms averaged over 5 turns for PlayCards, and 20 ms averaged over 5 turns for CallBS.

Controller



In this Controller, you add your functions to the top of the program, then add a tuple of all three functions, in the order of (CallBS, PlayCards, StartRound) to the list BotParams. The Controller should take it from there.



Below is the controller with the example bot from earlier. This bot will not be participating, nor will any bots that obviously aren't aiming the win the competition.



import random as rn
rn.seed(12321)#Subject to change

def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
return self.hand[:]
def example_StartRound(self):
return 'A'

#This is how you add your bot to the competition. Add the tuple of all three of your functions to BotParams
BotParams = [(example_CallBS,example_PlayCards,example_StartRound)]

#This is the controller
class Obj:
pass
class card:
def __init__(self, val):
self.val=val
def __eq__(self,other):
return (self.val==other or self.val=='j')
def __str__(self):
return self.val
class BSgame:
def __init__(self,BotParams):
self.numBots = len(BotParams)
self.AllCards = ['A','J','Q','K','j']+[str(i) for i in range(2,11)]
x=[card(j) for j in self.AllCards*self.numBots]
rn.shuffle(x)
self.hands = [x[14*i:14*i+14] for i in range(self.numBots)]
rn.shuffle(BotParams)
self.BotList = [BSBot(self.hands[i],len(BotParams),*BotParams[i]) for i in range(self.numBots)]
self.play =
self.pile =
self.isRound = False
self.isTurn = 0
self.currCard = None
self.winner=None
self.GameSummary = [str(i) for i in self.BotList]
def results(self):
print("The winner is "+self.winner)
print("Final Standings:")
for i in self.BotList:
print(i)
def checkBS(self, caller):
if min([i==self.currCard for i in self.play]):
self.BotList[caller].hand.extend(self.pile)
self.BotList[caller].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS but was wrong!")
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
else:
self.BotList[self.isTurn].hand.extend(self.pile)
self.BotList[self.isTurn].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS and was right!")
self.isTurn=caller
self.isRound=False
self.pile=
def isBS(self):
for i in range(1,self.numBots):
if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):
self.checkBS(i)
break
if self.isRound:
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
self.pile.extend(self.play)
def startRound(self):
self.currCard = self.BotList[self.isTurn].startRound()
for i in self.BotList:
i.inRound = True
self.isRound=True
self.GameSummary.append(self.BotList[self.isTurn].name+" started the round by picking "+self.currCard+" for the round.")
def __iter__(self):
return self
def __next__(self):
if not self.isRound:
self.startRound()
passList = [i.name for i in self.BotList if i.inRound]
self.play =self.BotList[self.isTurn].playCards(self.currCard,len(self.pile),passList)
if self.play == None:
self.BotList[self.isTurn].inRound=False
self.GameSummary.append(self.BotList[self.isTurn].name+" passed its turn.")
else:
try:
for i in self.play:
self.BotList[self.isTurn].hand.remove(i)
except:
raise Exception("You can't play a card you don't have, you dimwit")
self.GameSummary.append(self.BotList[self.isTurn].name+" played "+",".join(i.val for i in self.play)+".")
self.isBS()
if self.winner!=None:
raise StopIteration
if set(passList)!=False:
while True:
self.isTurn=(self.isTurn+1)%self.numBots
if self.BotList[self.isTurn].inRound:
break
else:
self.GameSummary.append("Everyone passed. "+self.BotList[self.isTurn].name+" starts the next round.")
self.isRound=False
return(None)
class BSBot:
def __init__(self,myHand,numBots,CallBS,PlayCards,StartRound):
self.obj=Obj()
self.hand = myHand
self.numBots = numBots
self.name = CallBS.__name__.split('_')[0]
self.callBS = lambda pos, player, handSize, currCard, numCards, numPile: CallBS(self,pos,player, handSize, currCard, numCards, numPile)
self.playCards = lambda currCard, numPile, stillPlaying: PlayCards(self,currCard, numPile, stillPlaying)
self.startRound= lambda:StartRound(self)
def __str__(self):
if self.hand==:
return(self.name+': WINNER!')
return(self.name+": "+", ".join(str(i) for i in self.hand))
def getRandom(self):
return rn.random()
Mod = BSgame(BotParams)
for i in Mod:
pass
Mod.results()


Additionally, if you want to see a summary of the game, type in the following command at the end of the program:



print("n".join(Mod.GameSummary))









share|improve this question





















  • Is self.numBots including yourself or not?
    – Quintec
    Sep 21 at 20:39






  • 3




    I thought this was going to be a pre-US midterm election social media analysis challenge.
    – ngm
    Sep 21 at 20:59










  • @Quintec yes and ngm, lmaooo
    – Rushabh Mehta
    Sep 21 at 21:26










  • In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
    – Spitemaster
    Sep 22 at 13:05











  • Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
    – Spitemaster
    Sep 22 at 13:13














up vote
2
down vote

favorite
2












The ChatRoom is here



I love playing the card game BS, but sometimes, it just doesn't have enough oomph for my short attention span. Instead, let's play some Russian BS.



Rules



Here is a quick guide to the rules.



  • The game begins with a random player declaring the card type of the round (out of 14 options: A,2,3...10,J,Q,K,j where the j stands for joker)

  • The same player starts the round, placing down as many cards as he or she wants, which all have to be of the declared card type.

  • Any player can call BS on the play. If multiple players call BS, the player closest to the player who put down the cards to the right will be the one to call BS

  • If BS is called on the play, then the cards played there are checked by the moderator. If the cards were indeed valid (i.e., all of the declared type or jokers), the player who called BS will take all of the cards played in the round. Otherwise, the player who played the invalid cards will take all of them.

  • If no BS is called, the next player is up to play, and must also play the declared card type.

  • We also allow players to pass their turn if they don't wish to play. However, if they pass, they are not allowed to play for the rest of the round (although they can call BS)

  • If every player passes, then the round ends, and the player who played the last cards will start the next round by declaring the card type.

  • If BS is called, the player who played the cards will start the next round and declare if he played valid cards, else the player who called BS will start.

  • The player who has no cards at the end of the game wins.

I like these rules because they don't force you to lie, but usually, players tend to lie more than in the original version of BS



Challenge



This challenge will be a king-of-the-hill challenge, with submissions providing bots to play the game. The bots will be written in Python 3, although I'll try my best to accommodate all submissions.



The submissions should consist of the following three functions:



CallBS - determines whether you seek to call BS or not on a play
PlayCards - determines what cards you want to play
StartRound - determines what the declared type of the round is, if you are chosen to pick it.


The submitted functions should be named such that their names are ***_CallBS, ***_PlayCards, and ***_StartRound, where *** is the name of your bot.



Below are example functions that describe the inputs and outputs:



def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
'''This function will output True if the bot seeks to call BS on the
current move, or False if not. The parameters are
- self: class variable
- pos: int - how many positions away you are to the right of the player (Note: if
your function got called, that means everyone to your left before the player decided
not to call BS)
- player: str - holds the name of the bot who just played cards
- handSize: int - how many cards playing bot holds
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numCards: int - number of cards just played by player
- numPile: int - number of cards in the pile (not including played cards this turn)
'''
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
'''This function will output a sublist of the hand of the bot to play this turn, or None to pass.
The parameters are
- self: class variable
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numPile: int - number of cards in the pile
- stillPlaying: list of str - players who haven't passed this round
'''
return self.hand[:]
def example_StartRound(self):
'''This function will output a string representing the card that will be played for the coming round (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
The parameters are
- self: class variable
'''
return 'A'


In addition, you will be provided with the following utilities



self.obj - A blank object for your usage to store knowledge between calls
self.hand: list of card objects - Your current hand in card objects (calling card.val gives you the str value of the card)
self.numBots: int - number of competitors you have
self.getRandom(): function - outputs a random number from 0 to 1.


If you want to use any sort of randomness, you must use the self.getRandom() function provided. You may not edit any of these objects except for self.obj



Parameters and more Rules



  • The cards in this game (you'll see the class that the cards belong to in the controller below) don't have a suit since suits don't matter to this game.

  • The number of cards in the game will be 14*number of bots (numBots of each type of card)

  • In the output of PlayCards, you must output cards that are in your hand. The program will not like you otherwise. You also must output card objects, not strings.

  • You may take at most 10 ms on average over 5 turns for StartRound, 50 ms averaged over 5 turns for PlayCards, and 20 ms averaged over 5 turns for CallBS.

Controller



In this Controller, you add your functions to the top of the program, then add a tuple of all three functions, in the order of (CallBS, PlayCards, StartRound) to the list BotParams. The Controller should take it from there.



Below is the controller with the example bot from earlier. This bot will not be participating, nor will any bots that obviously aren't aiming the win the competition.



import random as rn
rn.seed(12321)#Subject to change

def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
return self.hand[:]
def example_StartRound(self):
return 'A'

#This is how you add your bot to the competition. Add the tuple of all three of your functions to BotParams
BotParams = [(example_CallBS,example_PlayCards,example_StartRound)]

#This is the controller
class Obj:
pass
class card:
def __init__(self, val):
self.val=val
def __eq__(self,other):
return (self.val==other or self.val=='j')
def __str__(self):
return self.val
class BSgame:
def __init__(self,BotParams):
self.numBots = len(BotParams)
self.AllCards = ['A','J','Q','K','j']+[str(i) for i in range(2,11)]
x=[card(j) for j in self.AllCards*self.numBots]
rn.shuffle(x)
self.hands = [x[14*i:14*i+14] for i in range(self.numBots)]
rn.shuffle(BotParams)
self.BotList = [BSBot(self.hands[i],len(BotParams),*BotParams[i]) for i in range(self.numBots)]
self.play =
self.pile =
self.isRound = False
self.isTurn = 0
self.currCard = None
self.winner=None
self.GameSummary = [str(i) for i in self.BotList]
def results(self):
print("The winner is "+self.winner)
print("Final Standings:")
for i in self.BotList:
print(i)
def checkBS(self, caller):
if min([i==self.currCard for i in self.play]):
self.BotList[caller].hand.extend(self.pile)
self.BotList[caller].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS but was wrong!")
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
else:
self.BotList[self.isTurn].hand.extend(self.pile)
self.BotList[self.isTurn].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS and was right!")
self.isTurn=caller
self.isRound=False
self.pile=
def isBS(self):
for i in range(1,self.numBots):
if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):
self.checkBS(i)
break
if self.isRound:
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
self.pile.extend(self.play)
def startRound(self):
self.currCard = self.BotList[self.isTurn].startRound()
for i in self.BotList:
i.inRound = True
self.isRound=True
self.GameSummary.append(self.BotList[self.isTurn].name+" started the round by picking "+self.currCard+" for the round.")
def __iter__(self):
return self
def __next__(self):
if not self.isRound:
self.startRound()
passList = [i.name for i in self.BotList if i.inRound]
self.play =self.BotList[self.isTurn].playCards(self.currCard,len(self.pile),passList)
if self.play == None:
self.BotList[self.isTurn].inRound=False
self.GameSummary.append(self.BotList[self.isTurn].name+" passed its turn.")
else:
try:
for i in self.play:
self.BotList[self.isTurn].hand.remove(i)
except:
raise Exception("You can't play a card you don't have, you dimwit")
self.GameSummary.append(self.BotList[self.isTurn].name+" played "+",".join(i.val for i in self.play)+".")
self.isBS()
if self.winner!=None:
raise StopIteration
if set(passList)!=False:
while True:
self.isTurn=(self.isTurn+1)%self.numBots
if self.BotList[self.isTurn].inRound:
break
else:
self.GameSummary.append("Everyone passed. "+self.BotList[self.isTurn].name+" starts the next round.")
self.isRound=False
return(None)
class BSBot:
def __init__(self,myHand,numBots,CallBS,PlayCards,StartRound):
self.obj=Obj()
self.hand = myHand
self.numBots = numBots
self.name = CallBS.__name__.split('_')[0]
self.callBS = lambda pos, player, handSize, currCard, numCards, numPile: CallBS(self,pos,player, handSize, currCard, numCards, numPile)
self.playCards = lambda currCard, numPile, stillPlaying: PlayCards(self,currCard, numPile, stillPlaying)
self.startRound= lambda:StartRound(self)
def __str__(self):
if self.hand==:
return(self.name+': WINNER!')
return(self.name+": "+", ".join(str(i) for i in self.hand))
def getRandom(self):
return rn.random()
Mod = BSgame(BotParams)
for i in Mod:
pass
Mod.results()


Additionally, if you want to see a summary of the game, type in the following command at the end of the program:



print("n".join(Mod.GameSummary))









share|improve this question





















  • Is self.numBots including yourself or not?
    – Quintec
    Sep 21 at 20:39






  • 3




    I thought this was going to be a pre-US midterm election social media analysis challenge.
    – ngm
    Sep 21 at 20:59










  • @Quintec yes and ngm, lmaooo
    – Rushabh Mehta
    Sep 21 at 21:26










  • In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
    – Spitemaster
    Sep 22 at 13:05











  • Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
    – Spitemaster
    Sep 22 at 13:13












up vote
2
down vote

favorite
2









up vote
2
down vote

favorite
2






2





The ChatRoom is here



I love playing the card game BS, but sometimes, it just doesn't have enough oomph for my short attention span. Instead, let's play some Russian BS.



Rules



Here is a quick guide to the rules.



  • The game begins with a random player declaring the card type of the round (out of 14 options: A,2,3...10,J,Q,K,j where the j stands for joker)

  • The same player starts the round, placing down as many cards as he or she wants, which all have to be of the declared card type.

  • Any player can call BS on the play. If multiple players call BS, the player closest to the player who put down the cards to the right will be the one to call BS

  • If BS is called on the play, then the cards played there are checked by the moderator. If the cards were indeed valid (i.e., all of the declared type or jokers), the player who called BS will take all of the cards played in the round. Otherwise, the player who played the invalid cards will take all of them.

  • If no BS is called, the next player is up to play, and must also play the declared card type.

  • We also allow players to pass their turn if they don't wish to play. However, if they pass, they are not allowed to play for the rest of the round (although they can call BS)

  • If every player passes, then the round ends, and the player who played the last cards will start the next round by declaring the card type.

  • If BS is called, the player who played the cards will start the next round and declare if he played valid cards, else the player who called BS will start.

  • The player who has no cards at the end of the game wins.

I like these rules because they don't force you to lie, but usually, players tend to lie more than in the original version of BS



Challenge



This challenge will be a king-of-the-hill challenge, with submissions providing bots to play the game. The bots will be written in Python 3, although I'll try my best to accommodate all submissions.



The submissions should consist of the following three functions:



CallBS - determines whether you seek to call BS or not on a play
PlayCards - determines what cards you want to play
StartRound - determines what the declared type of the round is, if you are chosen to pick it.


The submitted functions should be named such that their names are ***_CallBS, ***_PlayCards, and ***_StartRound, where *** is the name of your bot.



Below are example functions that describe the inputs and outputs:



def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
'''This function will output True if the bot seeks to call BS on the
current move, or False if not. The parameters are
- self: class variable
- pos: int - how many positions away you are to the right of the player (Note: if
your function got called, that means everyone to your left before the player decided
not to call BS)
- player: str - holds the name of the bot who just played cards
- handSize: int - how many cards playing bot holds
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numCards: int - number of cards just played by player
- numPile: int - number of cards in the pile (not including played cards this turn)
'''
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
'''This function will output a sublist of the hand of the bot to play this turn, or None to pass.
The parameters are
- self: class variable
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numPile: int - number of cards in the pile
- stillPlaying: list of str - players who haven't passed this round
'''
return self.hand[:]
def example_StartRound(self):
'''This function will output a string representing the card that will be played for the coming round (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
The parameters are
- self: class variable
'''
return 'A'


In addition, you will be provided with the following utilities



self.obj - A blank object for your usage to store knowledge between calls
self.hand: list of card objects - Your current hand in card objects (calling card.val gives you the str value of the card)
self.numBots: int - number of competitors you have
self.getRandom(): function - outputs a random number from 0 to 1.


If you want to use any sort of randomness, you must use the self.getRandom() function provided. You may not edit any of these objects except for self.obj



Parameters and more Rules



  • The cards in this game (you'll see the class that the cards belong to in the controller below) don't have a suit since suits don't matter to this game.

  • The number of cards in the game will be 14*number of bots (numBots of each type of card)

  • In the output of PlayCards, you must output cards that are in your hand. The program will not like you otherwise. You also must output card objects, not strings.

  • You may take at most 10 ms on average over 5 turns for StartRound, 50 ms averaged over 5 turns for PlayCards, and 20 ms averaged over 5 turns for CallBS.

Controller



In this Controller, you add your functions to the top of the program, then add a tuple of all three functions, in the order of (CallBS, PlayCards, StartRound) to the list BotParams. The Controller should take it from there.



Below is the controller with the example bot from earlier. This bot will not be participating, nor will any bots that obviously aren't aiming the win the competition.



import random as rn
rn.seed(12321)#Subject to change

def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
return self.hand[:]
def example_StartRound(self):
return 'A'

#This is how you add your bot to the competition. Add the tuple of all three of your functions to BotParams
BotParams = [(example_CallBS,example_PlayCards,example_StartRound)]

#This is the controller
class Obj:
pass
class card:
def __init__(self, val):
self.val=val
def __eq__(self,other):
return (self.val==other or self.val=='j')
def __str__(self):
return self.val
class BSgame:
def __init__(self,BotParams):
self.numBots = len(BotParams)
self.AllCards = ['A','J','Q','K','j']+[str(i) for i in range(2,11)]
x=[card(j) for j in self.AllCards*self.numBots]
rn.shuffle(x)
self.hands = [x[14*i:14*i+14] for i in range(self.numBots)]
rn.shuffle(BotParams)
self.BotList = [BSBot(self.hands[i],len(BotParams),*BotParams[i]) for i in range(self.numBots)]
self.play =
self.pile =
self.isRound = False
self.isTurn = 0
self.currCard = None
self.winner=None
self.GameSummary = [str(i) for i in self.BotList]
def results(self):
print("The winner is "+self.winner)
print("Final Standings:")
for i in self.BotList:
print(i)
def checkBS(self, caller):
if min([i==self.currCard for i in self.play]):
self.BotList[caller].hand.extend(self.pile)
self.BotList[caller].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS but was wrong!")
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
else:
self.BotList[self.isTurn].hand.extend(self.pile)
self.BotList[self.isTurn].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS and was right!")
self.isTurn=caller
self.isRound=False
self.pile=
def isBS(self):
for i in range(1,self.numBots):
if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):
self.checkBS(i)
break
if self.isRound:
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
self.pile.extend(self.play)
def startRound(self):
self.currCard = self.BotList[self.isTurn].startRound()
for i in self.BotList:
i.inRound = True
self.isRound=True
self.GameSummary.append(self.BotList[self.isTurn].name+" started the round by picking "+self.currCard+" for the round.")
def __iter__(self):
return self
def __next__(self):
if not self.isRound:
self.startRound()
passList = [i.name for i in self.BotList if i.inRound]
self.play =self.BotList[self.isTurn].playCards(self.currCard,len(self.pile),passList)
if self.play == None:
self.BotList[self.isTurn].inRound=False
self.GameSummary.append(self.BotList[self.isTurn].name+" passed its turn.")
else:
try:
for i in self.play:
self.BotList[self.isTurn].hand.remove(i)
except:
raise Exception("You can't play a card you don't have, you dimwit")
self.GameSummary.append(self.BotList[self.isTurn].name+" played "+",".join(i.val for i in self.play)+".")
self.isBS()
if self.winner!=None:
raise StopIteration
if set(passList)!=False:
while True:
self.isTurn=(self.isTurn+1)%self.numBots
if self.BotList[self.isTurn].inRound:
break
else:
self.GameSummary.append("Everyone passed. "+self.BotList[self.isTurn].name+" starts the next round.")
self.isRound=False
return(None)
class BSBot:
def __init__(self,myHand,numBots,CallBS,PlayCards,StartRound):
self.obj=Obj()
self.hand = myHand
self.numBots = numBots
self.name = CallBS.__name__.split('_')[0]
self.callBS = lambda pos, player, handSize, currCard, numCards, numPile: CallBS(self,pos,player, handSize, currCard, numCards, numPile)
self.playCards = lambda currCard, numPile, stillPlaying: PlayCards(self,currCard, numPile, stillPlaying)
self.startRound= lambda:StartRound(self)
def __str__(self):
if self.hand==:
return(self.name+': WINNER!')
return(self.name+": "+", ".join(str(i) for i in self.hand))
def getRandom(self):
return rn.random()
Mod = BSgame(BotParams)
for i in Mod:
pass
Mod.results()


Additionally, if you want to see a summary of the game, type in the following command at the end of the program:



print("n".join(Mod.GameSummary))









share|improve this question













The ChatRoom is here



I love playing the card game BS, but sometimes, it just doesn't have enough oomph for my short attention span. Instead, let's play some Russian BS.



Rules



Here is a quick guide to the rules.



  • The game begins with a random player declaring the card type of the round (out of 14 options: A,2,3...10,J,Q,K,j where the j stands for joker)

  • The same player starts the round, placing down as many cards as he or she wants, which all have to be of the declared card type.

  • Any player can call BS on the play. If multiple players call BS, the player closest to the player who put down the cards to the right will be the one to call BS

  • If BS is called on the play, then the cards played there are checked by the moderator. If the cards were indeed valid (i.e., all of the declared type or jokers), the player who called BS will take all of the cards played in the round. Otherwise, the player who played the invalid cards will take all of them.

  • If no BS is called, the next player is up to play, and must also play the declared card type.

  • We also allow players to pass their turn if they don't wish to play. However, if they pass, they are not allowed to play for the rest of the round (although they can call BS)

  • If every player passes, then the round ends, and the player who played the last cards will start the next round by declaring the card type.

  • If BS is called, the player who played the cards will start the next round and declare if he played valid cards, else the player who called BS will start.

  • The player who has no cards at the end of the game wins.

I like these rules because they don't force you to lie, but usually, players tend to lie more than in the original version of BS



Challenge



This challenge will be a king-of-the-hill challenge, with submissions providing bots to play the game. The bots will be written in Python 3, although I'll try my best to accommodate all submissions.



The submissions should consist of the following three functions:



CallBS - determines whether you seek to call BS or not on a play
PlayCards - determines what cards you want to play
StartRound - determines what the declared type of the round is, if you are chosen to pick it.


The submitted functions should be named such that their names are ***_CallBS, ***_PlayCards, and ***_StartRound, where *** is the name of your bot.



Below are example functions that describe the inputs and outputs:



def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
'''This function will output True if the bot seeks to call BS on the
current move, or False if not. The parameters are
- self: class variable
- pos: int - how many positions away you are to the right of the player (Note: if
your function got called, that means everyone to your left before the player decided
not to call BS)
- player: str - holds the name of the bot who just played cards
- handSize: int - how many cards playing bot holds
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numCards: int - number of cards just played by player
- numPile: int - number of cards in the pile (not including played cards this turn)
'''
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
'''This function will output a sublist of the hand of the bot to play this turn, or None to pass.
The parameters are
- self: class variable
- currCard: str - current card in play (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
- numPile: int - number of cards in the pile
- stillPlaying: list of str - players who haven't passed this round
'''
return self.hand[:]
def example_StartRound(self):
'''This function will output a string representing the card that will be played for the coming round (One of A,2,3,4,5,6,7,8,9,10,J,Q,K,j)
The parameters are
- self: class variable
'''
return 'A'


In addition, you will be provided with the following utilities



self.obj - A blank object for your usage to store knowledge between calls
self.hand: list of card objects - Your current hand in card objects (calling card.val gives you the str value of the card)
self.numBots: int - number of competitors you have
self.getRandom(): function - outputs a random number from 0 to 1.


If you want to use any sort of randomness, you must use the self.getRandom() function provided. You may not edit any of these objects except for self.obj



Parameters and more Rules



  • The cards in this game (you'll see the class that the cards belong to in the controller below) don't have a suit since suits don't matter to this game.

  • The number of cards in the game will be 14*number of bots (numBots of each type of card)

  • In the output of PlayCards, you must output cards that are in your hand. The program will not like you otherwise. You also must output card objects, not strings.

  • You may take at most 10 ms on average over 5 turns for StartRound, 50 ms averaged over 5 turns for PlayCards, and 20 ms averaged over 5 turns for CallBS.

Controller



In this Controller, you add your functions to the top of the program, then add a tuple of all three functions, in the order of (CallBS, PlayCards, StartRound) to the list BotParams. The Controller should take it from there.



Below is the controller with the example bot from earlier. This bot will not be participating, nor will any bots that obviously aren't aiming the win the competition.



import random as rn
rn.seed(12321)#Subject to change

def example_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
return True
def example_PlayCards(self,currCard,numPile,stillPlaying):
return self.hand[:]
def example_StartRound(self):
return 'A'

#This is how you add your bot to the competition. Add the tuple of all three of your functions to BotParams
BotParams = [(example_CallBS,example_PlayCards,example_StartRound)]

#This is the controller
class Obj:
pass
class card:
def __init__(self, val):
self.val=val
def __eq__(self,other):
return (self.val==other or self.val=='j')
def __str__(self):
return self.val
class BSgame:
def __init__(self,BotParams):
self.numBots = len(BotParams)
self.AllCards = ['A','J','Q','K','j']+[str(i) for i in range(2,11)]
x=[card(j) for j in self.AllCards*self.numBots]
rn.shuffle(x)
self.hands = [x[14*i:14*i+14] for i in range(self.numBots)]
rn.shuffle(BotParams)
self.BotList = [BSBot(self.hands[i],len(BotParams),*BotParams[i]) for i in range(self.numBots)]
self.play =
self.pile =
self.isRound = False
self.isTurn = 0
self.currCard = None
self.winner=None
self.GameSummary = [str(i) for i in self.BotList]
def results(self):
print("The winner is "+self.winner)
print("Final Standings:")
for i in self.BotList:
print(i)
def checkBS(self, caller):
if min([i==self.currCard for i in self.play]):
self.BotList[caller].hand.extend(self.pile)
self.BotList[caller].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS but was wrong!")
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
else:
self.BotList[self.isTurn].hand.extend(self.pile)
self.BotList[self.isTurn].hand.extend(self.play)
self.GameSummary.append(self.BotList[caller].name+" called BS and was right!")
self.isTurn=caller
self.isRound=False
self.pile=
def isBS(self):
for i in range(1,self.numBots):
if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):
self.checkBS(i)
break
if self.isRound:
if self.BotList[self.isTurn].hand==:
self.winner=self.BotList[self.isTurn].name
self.GameSummary.append(self.BotList[self.isTurn].name+" has won the game!")
self.pile.extend(self.play)
def startRound(self):
self.currCard = self.BotList[self.isTurn].startRound()
for i in self.BotList:
i.inRound = True
self.isRound=True
self.GameSummary.append(self.BotList[self.isTurn].name+" started the round by picking "+self.currCard+" for the round.")
def __iter__(self):
return self
def __next__(self):
if not self.isRound:
self.startRound()
passList = [i.name for i in self.BotList if i.inRound]
self.play =self.BotList[self.isTurn].playCards(self.currCard,len(self.pile),passList)
if self.play == None:
self.BotList[self.isTurn].inRound=False
self.GameSummary.append(self.BotList[self.isTurn].name+" passed its turn.")
else:
try:
for i in self.play:
self.BotList[self.isTurn].hand.remove(i)
except:
raise Exception("You can't play a card you don't have, you dimwit")
self.GameSummary.append(self.BotList[self.isTurn].name+" played "+",".join(i.val for i in self.play)+".")
self.isBS()
if self.winner!=None:
raise StopIteration
if set(passList)!=False:
while True:
self.isTurn=(self.isTurn+1)%self.numBots
if self.BotList[self.isTurn].inRound:
break
else:
self.GameSummary.append("Everyone passed. "+self.BotList[self.isTurn].name+" starts the next round.")
self.isRound=False
return(None)
class BSBot:
def __init__(self,myHand,numBots,CallBS,PlayCards,StartRound):
self.obj=Obj()
self.hand = myHand
self.numBots = numBots
self.name = CallBS.__name__.split('_')[0]
self.callBS = lambda pos, player, handSize, currCard, numCards, numPile: CallBS(self,pos,player, handSize, currCard, numCards, numPile)
self.playCards = lambda currCard, numPile, stillPlaying: PlayCards(self,currCard, numPile, stillPlaying)
self.startRound= lambda:StartRound(self)
def __str__(self):
if self.hand==:
return(self.name+': WINNER!')
return(self.name+": "+", ".join(str(i) for i in self.hand))
def getRandom(self):
return rn.random()
Mod = BSgame(BotParams)
for i in Mod:
pass
Mod.results()


Additionally, if you want to see a summary of the game, type in the following command at the end of the program:



print("n".join(Mod.GameSummary))






king-of-the-hill card-games






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 21 at 19:41









Rushabh Mehta

637221




637221











  • Is self.numBots including yourself or not?
    – Quintec
    Sep 21 at 20:39






  • 3




    I thought this was going to be a pre-US midterm election social media analysis challenge.
    – ngm
    Sep 21 at 20:59










  • @Quintec yes and ngm, lmaooo
    – Rushabh Mehta
    Sep 21 at 21:26










  • In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
    – Spitemaster
    Sep 22 at 13:05











  • Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
    – Spitemaster
    Sep 22 at 13:13
















  • Is self.numBots including yourself or not?
    – Quintec
    Sep 21 at 20:39






  • 3




    I thought this was going to be a pre-US midterm election social media analysis challenge.
    – ngm
    Sep 21 at 20:59










  • @Quintec yes and ngm, lmaooo
    – Rushabh Mehta
    Sep 21 at 21:26










  • In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
    – Spitemaster
    Sep 22 at 13:05











  • Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
    – Spitemaster
    Sep 22 at 13:13















Is self.numBots including yourself or not?
– Quintec
Sep 21 at 20:39




Is self.numBots including yourself or not?
– Quintec
Sep 21 at 20:39




3




3




I thought this was going to be a pre-US midterm election social media analysis challenge.
– ngm
Sep 21 at 20:59




I thought this was going to be a pre-US midterm election social media analysis challenge.
– ngm
Sep 21 at 20:59












@Quintec yes and ngm, lmaooo
– Rushabh Mehta
Sep 21 at 21:26




@Quintec yes and ngm, lmaooo
– Rushabh Mehta
Sep 21 at 21:26












In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
– Spitemaster
Sep 22 at 13:05





In the controller, in the isBS function, "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[isTurn].hand),self.currCard,len(self.play),len(self.pile)):" should be "if self.BotList[(i+self.isTurn)%self.numBots].callBS(i,self.BotList[self.isTurn].name,len(self.BotList[self.isTurn].hand),self.currCard,len(self.play),len(self.pile)):" It's just missing a self. Apologies for the formatting; I'm not sure how to make it nicer.
– Spitemaster
Sep 22 at 13:05













Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
– Spitemaster
Sep 22 at 13:13




Also in the checkBS function, you should add a default in the min() because otherwise it throws a 'ValueError: min() arg is an empty sequence' error.
– Spitemaster
Sep 22 at 13:13










4 Answers
4






active

oldest

votes

















up vote
4
down vote













Naive Bot



def naive_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
return False
def naive_PlayCards(self,currCard,numPile,stillPlaying):
return [card(currCard)] * self.hand.count(currCard)
def naive_StartRound(self):
return self.hand[0].val


Never calls BS, never lies, and lets the game play out, while trying its best to win. Will always play all of the current card, and will start the round with the first card in its hand.






share|improve this answer


















  • 1




    naive_StartRound() should return string. Change it to self.hand[0].val
    – DobromirM
    Sep 21 at 21:53

















up vote
4
down vote













Asshole



def asshole_CallBS(self,pos,player,handSize,currCard,numCards,numPile):

if not hasattr(self.obj, "flag"):
self.obj.flag2 = False
self.obj.flag = False
if len(self.hand) < self.numBots * 14 * 1.5 / 4 and self.obj.flag:
self.obj.flag = False
if len(set(self.hand)) * self.numBots * 3.0 / 4 < len(self.hand):
self.obj.flag2 = True
if len(self.hand) < self.numBots * 14 * 3.0 / 4:
if not self.obj.flag:
self.obj.flag = True
return False
else:
return self.hand.count(currCard) * 1.0 / self.numBots > 0.75
def asshole_PlayCards(self,currCard,numPile,stillPlaying):
if not hasattr(self.obj, "flag"):
self.obj.flag2 = False
self.obj.flag = False
if not self.obj.flag:
return [card(currCard)] * self.hand.count(currCard) if len(self.hand) > self.numBots * 14 * 3.0 / 4 else self.hand
else:
if self.obj.flag2 and len(self.hand) < 3:
return self.hand
return [card(currCard)] * self.hand.count(currCard)
def asshole_StartRound(self):
if not hasattr(self.obj, "flag"):
self.obj.flag2 = False
self.obj.flag = False
card = ""
max_cards = 0
for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(","):
if self.hand.count(i) > max_cards:
max_cards = self.hand.count(i)
card = i
return card


Have you ever been that one player in BS who tries to get all the cards? No? Just me? Well, let me tell you it's just as fun. Trust me, this is a legitimate winning strategy.






share|improve this answer






















  • In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
    – DobromirM
    Sep 22 at 1:16











  • @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
    – Quintec
    Sep 22 at 1:34










  • In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
    – Spitemaster
    Sep 22 at 13:35










  • @Spitemaster thanks :) my brain is malfunctioning
    – Quintec
    Sep 22 at 13:37

















up vote
3
down vote













Moniathan



def moniathan_CallBS(self, pos, player, handSize, currCard, numCards, numPile):
if numCards > self.numBots * 0.5:
return True
if self.hand.count(currCard) == self.numBots:
return True
if self.hand.count(currCard) + numCards > self.numBots * 0.5:
return True
if numPile > self.numBots * 2:
return True
return False


def moniathan_PlayCards(self, currCard, numPile, stillPlaying):
cards = [c.val for c in self.hand]

if cards.count(currCard) > 1:
return cards.count(currCard) * [card(currCard)]

if cards.count(currCard) == 1:
if len(self.hand) > 1:
add_more = self.getRandom() > 0.75
if add_more:
return [card(currCard), [c for c in self.hand if c.val != currCard][0]]
else:
return [card(currCard)]
else:
return [card(currCard)]
else:
if self.getRandom() > 0.5:
if self.getRandom() > 0.5 and len(self.hand) > 1:
return [self.hand[0], self.hand[1]]
else:
return [self.hand[0]]
else:
return


def moniathan_StartRound(self):
return max(self.hand, key=lambda x: self.hand.count(x.val)).val


It mostly tries to play safe but sometimes it will take small risks to get ahead.






share|improve this answer






















  • if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
    – Spitemaster
    Sep 22 at 12:59











  • Yes it should be ==. Thank you!
    – DobromirM
    Sep 22 at 14:36

















up vote
2
down vote













Halfwit



def halfwit_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
# Call if I know he's lying
if numCards + self.hand.count(currCard) > self.numBots:
return True
# Call if he'd win otherwise
if handSize == 0:
return True
# Call if that would be more than half of the remaining cards, more than 3, and he's got lots of cards
if handSize > 14 and numCards > 3 and numCards + self.hand.count(currCard) > (self.numBots - numPile) / 2:
return True
return False
def halfwit_PlayCards(self,currCard,numPile,stillPlaying):
# If I have this card, play all that I've got.
if self.hand.count(currCard) > 0:
return [card(currCard)] * self.hand.count(currCard)
# If more than half of the cards of this value are allegedly already out, play nothing
if numPile * 2 >= self.numBots:
return
# Play the smallest stack I've got.
counts = [self.hand.count(i) for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")]
choice = "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")[counts.index(min([x if x != 0 else 100 for x in counts]))]
return [card(choice)] * min([x for x in counts if x != 0])
def halfwit_StartRound(self):
# Play the card I have the most of
return max(self.hand, key=lambda x: self.hand.count(x.val)).val


Halfwit always plays something - and he cheats if he doesn't have any of the right cards to play. Right now there's a few issues with the controller and with the bot and I'm not sure which is which, so I'll have to come back and fix some bugs later.






share|improve this answer




















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "200"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f172628%2frussian-bs-submissions-accepted-until-october-13th%23new-answer', 'question_page');

    );

    Post as a guest






























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    4
    down vote













    Naive Bot



    def naive_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
    return False
    def naive_PlayCards(self,currCard,numPile,stillPlaying):
    return [card(currCard)] * self.hand.count(currCard)
    def naive_StartRound(self):
    return self.hand[0].val


    Never calls BS, never lies, and lets the game play out, while trying its best to win. Will always play all of the current card, and will start the round with the first card in its hand.






    share|improve this answer


















    • 1




      naive_StartRound() should return string. Change it to self.hand[0].val
      – DobromirM
      Sep 21 at 21:53














    up vote
    4
    down vote













    Naive Bot



    def naive_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
    return False
    def naive_PlayCards(self,currCard,numPile,stillPlaying):
    return [card(currCard)] * self.hand.count(currCard)
    def naive_StartRound(self):
    return self.hand[0].val


    Never calls BS, never lies, and lets the game play out, while trying its best to win. Will always play all of the current card, and will start the round with the first card in its hand.






    share|improve this answer


















    • 1




      naive_StartRound() should return string. Change it to self.hand[0].val
      – DobromirM
      Sep 21 at 21:53












    up vote
    4
    down vote










    up vote
    4
    down vote









    Naive Bot



    def naive_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
    return False
    def naive_PlayCards(self,currCard,numPile,stillPlaying):
    return [card(currCard)] * self.hand.count(currCard)
    def naive_StartRound(self):
    return self.hand[0].val


    Never calls BS, never lies, and lets the game play out, while trying its best to win. Will always play all of the current card, and will start the round with the first card in its hand.






    share|improve this answer














    Naive Bot



    def naive_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
    return False
    def naive_PlayCards(self,currCard,numPile,stillPlaying):
    return [card(currCard)] * self.hand.count(currCard)
    def naive_StartRound(self):
    return self.hand[0].val


    Never calls BS, never lies, and lets the game play out, while trying its best to win. Will always play all of the current card, and will start the round with the first card in its hand.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 21 at 23:06

























    answered Sep 21 at 20:12









    Stephen

    7,08322993




    7,08322993







    • 1




      naive_StartRound() should return string. Change it to self.hand[0].val
      – DobromirM
      Sep 21 at 21:53












    • 1




      naive_StartRound() should return string. Change it to self.hand[0].val
      – DobromirM
      Sep 21 at 21:53







    1




    1




    naive_StartRound() should return string. Change it to self.hand[0].val
    – DobromirM
    Sep 21 at 21:53




    naive_StartRound() should return string. Change it to self.hand[0].val
    – DobromirM
    Sep 21 at 21:53










    up vote
    4
    down vote













    Asshole



    def asshole_CallBS(self,pos,player,handSize,currCard,numCards,numPile):

    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if len(self.hand) < self.numBots * 14 * 1.5 / 4 and self.obj.flag:
    self.obj.flag = False
    if len(set(self.hand)) * self.numBots * 3.0 / 4 < len(self.hand):
    self.obj.flag2 = True
    if len(self.hand) < self.numBots * 14 * 3.0 / 4:
    if not self.obj.flag:
    self.obj.flag = True
    return False
    else:
    return self.hand.count(currCard) * 1.0 / self.numBots > 0.75
    def asshole_PlayCards(self,currCard,numPile,stillPlaying):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if not self.obj.flag:
    return [card(currCard)] * self.hand.count(currCard) if len(self.hand) > self.numBots * 14 * 3.0 / 4 else self.hand
    else:
    if self.obj.flag2 and len(self.hand) < 3:
    return self.hand
    return [card(currCard)] * self.hand.count(currCard)
    def asshole_StartRound(self):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    card = ""
    max_cards = 0
    for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(","):
    if self.hand.count(i) > max_cards:
    max_cards = self.hand.count(i)
    card = i
    return card


    Have you ever been that one player in BS who tries to get all the cards? No? Just me? Well, let me tell you it's just as fun. Trust me, this is a legitimate winning strategy.






    share|improve this answer






















    • In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
      – DobromirM
      Sep 22 at 1:16











    • @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
      – Quintec
      Sep 22 at 1:34










    • In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
      – Spitemaster
      Sep 22 at 13:35










    • @Spitemaster thanks :) my brain is malfunctioning
      – Quintec
      Sep 22 at 13:37














    up vote
    4
    down vote













    Asshole



    def asshole_CallBS(self,pos,player,handSize,currCard,numCards,numPile):

    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if len(self.hand) < self.numBots * 14 * 1.5 / 4 and self.obj.flag:
    self.obj.flag = False
    if len(set(self.hand)) * self.numBots * 3.0 / 4 < len(self.hand):
    self.obj.flag2 = True
    if len(self.hand) < self.numBots * 14 * 3.0 / 4:
    if not self.obj.flag:
    self.obj.flag = True
    return False
    else:
    return self.hand.count(currCard) * 1.0 / self.numBots > 0.75
    def asshole_PlayCards(self,currCard,numPile,stillPlaying):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if not self.obj.flag:
    return [card(currCard)] * self.hand.count(currCard) if len(self.hand) > self.numBots * 14 * 3.0 / 4 else self.hand
    else:
    if self.obj.flag2 and len(self.hand) < 3:
    return self.hand
    return [card(currCard)] * self.hand.count(currCard)
    def asshole_StartRound(self):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    card = ""
    max_cards = 0
    for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(","):
    if self.hand.count(i) > max_cards:
    max_cards = self.hand.count(i)
    card = i
    return card


    Have you ever been that one player in BS who tries to get all the cards? No? Just me? Well, let me tell you it's just as fun. Trust me, this is a legitimate winning strategy.






    share|improve this answer






















    • In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
      – DobromirM
      Sep 22 at 1:16











    • @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
      – Quintec
      Sep 22 at 1:34










    • In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
      – Spitemaster
      Sep 22 at 13:35










    • @Spitemaster thanks :) my brain is malfunctioning
      – Quintec
      Sep 22 at 13:37












    up vote
    4
    down vote










    up vote
    4
    down vote









    Asshole



    def asshole_CallBS(self,pos,player,handSize,currCard,numCards,numPile):

    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if len(self.hand) < self.numBots * 14 * 1.5 / 4 and self.obj.flag:
    self.obj.flag = False
    if len(set(self.hand)) * self.numBots * 3.0 / 4 < len(self.hand):
    self.obj.flag2 = True
    if len(self.hand) < self.numBots * 14 * 3.0 / 4:
    if not self.obj.flag:
    self.obj.flag = True
    return False
    else:
    return self.hand.count(currCard) * 1.0 / self.numBots > 0.75
    def asshole_PlayCards(self,currCard,numPile,stillPlaying):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if not self.obj.flag:
    return [card(currCard)] * self.hand.count(currCard) if len(self.hand) > self.numBots * 14 * 3.0 / 4 else self.hand
    else:
    if self.obj.flag2 and len(self.hand) < 3:
    return self.hand
    return [card(currCard)] * self.hand.count(currCard)
    def asshole_StartRound(self):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    card = ""
    max_cards = 0
    for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(","):
    if self.hand.count(i) > max_cards:
    max_cards = self.hand.count(i)
    card = i
    return card


    Have you ever been that one player in BS who tries to get all the cards? No? Just me? Well, let me tell you it's just as fun. Trust me, this is a legitimate winning strategy.






    share|improve this answer














    Asshole



    def asshole_CallBS(self,pos,player,handSize,currCard,numCards,numPile):

    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if len(self.hand) < self.numBots * 14 * 1.5 / 4 and self.obj.flag:
    self.obj.flag = False
    if len(set(self.hand)) * self.numBots * 3.0 / 4 < len(self.hand):
    self.obj.flag2 = True
    if len(self.hand) < self.numBots * 14 * 3.0 / 4:
    if not self.obj.flag:
    self.obj.flag = True
    return False
    else:
    return self.hand.count(currCard) * 1.0 / self.numBots > 0.75
    def asshole_PlayCards(self,currCard,numPile,stillPlaying):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    if not self.obj.flag:
    return [card(currCard)] * self.hand.count(currCard) if len(self.hand) > self.numBots * 14 * 3.0 / 4 else self.hand
    else:
    if self.obj.flag2 and len(self.hand) < 3:
    return self.hand
    return [card(currCard)] * self.hand.count(currCard)
    def asshole_StartRound(self):
    if not hasattr(self.obj, "flag"):
    self.obj.flag2 = False
    self.obj.flag = False
    card = ""
    max_cards = 0
    for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(","):
    if self.hand.count(i) > max_cards:
    max_cards = self.hand.count(i)
    card = i
    return card


    Have you ever been that one player in BS who tries to get all the cards? No? Just me? Well, let me tell you it's just as fun. Trust me, this is a legitimate winning strategy.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 22 at 13:42

























    answered Sep 21 at 20:46









    Quintec

    763415




    763415











    • In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
      – DobromirM
      Sep 22 at 1:16











    • @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
      – Quintec
      Sep 22 at 1:34










    • In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
      – Spitemaster
      Sep 22 at 13:35










    • @Spitemaster thanks :) my brain is malfunctioning
      – Quintec
      Sep 22 at 13:37
















    • In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
      – DobromirM
      Sep 22 at 1:16











    • @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
      – Quintec
      Sep 22 at 1:34










    • In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
      – Spitemaster
      Sep 22 at 13:35










    • @Spitemaster thanks :) my brain is malfunctioning
      – Quintec
      Sep 22 at 13:37















    In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
    – DobromirM
    Sep 22 at 1:16





    In asshole_PlayCards() line 4 you should change if times < 3 and not self.obj.flag: to if self.obj.times < 3 and not self.obj.flag:
    – DobromirM
    Sep 22 at 1:16













    @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
    – Quintec
    Sep 22 at 1:34




    @DobromirM good catch, thanks. i need to rework a bit of the endgame logic of this bot after this anyway :)
    – Quintec
    Sep 22 at 1:34












    In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
    – Spitemaster
    Sep 22 at 13:35




    In your StartRound function, you probably don't want to return i - I'm guessing you would rather return card. ;)
    – Spitemaster
    Sep 22 at 13:35












    @Spitemaster thanks :) my brain is malfunctioning
    – Quintec
    Sep 22 at 13:37




    @Spitemaster thanks :) my brain is malfunctioning
    – Quintec
    Sep 22 at 13:37










    up vote
    3
    down vote













    Moniathan



    def moniathan_CallBS(self, pos, player, handSize, currCard, numCards, numPile):
    if numCards > self.numBots * 0.5:
    return True
    if self.hand.count(currCard) == self.numBots:
    return True
    if self.hand.count(currCard) + numCards > self.numBots * 0.5:
    return True
    if numPile > self.numBots * 2:
    return True
    return False


    def moniathan_PlayCards(self, currCard, numPile, stillPlaying):
    cards = [c.val for c in self.hand]

    if cards.count(currCard) > 1:
    return cards.count(currCard) * [card(currCard)]

    if cards.count(currCard) == 1:
    if len(self.hand) > 1:
    add_more = self.getRandom() > 0.75
    if add_more:
    return [card(currCard), [c for c in self.hand if c.val != currCard][0]]
    else:
    return [card(currCard)]
    else:
    return [card(currCard)]
    else:
    if self.getRandom() > 0.5:
    if self.getRandom() > 0.5 and len(self.hand) > 1:
    return [self.hand[0], self.hand[1]]
    else:
    return [self.hand[0]]
    else:
    return


    def moniathan_StartRound(self):
    return max(self.hand, key=lambda x: self.hand.count(x.val)).val


    It mostly tries to play safe but sometimes it will take small risks to get ahead.






    share|improve this answer






















    • if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
      – Spitemaster
      Sep 22 at 12:59











    • Yes it should be ==. Thank you!
      – DobromirM
      Sep 22 at 14:36














    up vote
    3
    down vote













    Moniathan



    def moniathan_CallBS(self, pos, player, handSize, currCard, numCards, numPile):
    if numCards > self.numBots * 0.5:
    return True
    if self.hand.count(currCard) == self.numBots:
    return True
    if self.hand.count(currCard) + numCards > self.numBots * 0.5:
    return True
    if numPile > self.numBots * 2:
    return True
    return False


    def moniathan_PlayCards(self, currCard, numPile, stillPlaying):
    cards = [c.val for c in self.hand]

    if cards.count(currCard) > 1:
    return cards.count(currCard) * [card(currCard)]

    if cards.count(currCard) == 1:
    if len(self.hand) > 1:
    add_more = self.getRandom() > 0.75
    if add_more:
    return [card(currCard), [c for c in self.hand if c.val != currCard][0]]
    else:
    return [card(currCard)]
    else:
    return [card(currCard)]
    else:
    if self.getRandom() > 0.5:
    if self.getRandom() > 0.5 and len(self.hand) > 1:
    return [self.hand[0], self.hand[1]]
    else:
    return [self.hand[0]]
    else:
    return


    def moniathan_StartRound(self):
    return max(self.hand, key=lambda x: self.hand.count(x.val)).val


    It mostly tries to play safe but sometimes it will take small risks to get ahead.






    share|improve this answer






















    • if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
      – Spitemaster
      Sep 22 at 12:59











    • Yes it should be ==. Thank you!
      – DobromirM
      Sep 22 at 14:36












    up vote
    3
    down vote










    up vote
    3
    down vote









    Moniathan



    def moniathan_CallBS(self, pos, player, handSize, currCard, numCards, numPile):
    if numCards > self.numBots * 0.5:
    return True
    if self.hand.count(currCard) == self.numBots:
    return True
    if self.hand.count(currCard) + numCards > self.numBots * 0.5:
    return True
    if numPile > self.numBots * 2:
    return True
    return False


    def moniathan_PlayCards(self, currCard, numPile, stillPlaying):
    cards = [c.val for c in self.hand]

    if cards.count(currCard) > 1:
    return cards.count(currCard) * [card(currCard)]

    if cards.count(currCard) == 1:
    if len(self.hand) > 1:
    add_more = self.getRandom() > 0.75
    if add_more:
    return [card(currCard), [c for c in self.hand if c.val != currCard][0]]
    else:
    return [card(currCard)]
    else:
    return [card(currCard)]
    else:
    if self.getRandom() > 0.5:
    if self.getRandom() > 0.5 and len(self.hand) > 1:
    return [self.hand[0], self.hand[1]]
    else:
    return [self.hand[0]]
    else:
    return


    def moniathan_StartRound(self):
    return max(self.hand, key=lambda x: self.hand.count(x.val)).val


    It mostly tries to play safe but sometimes it will take small risks to get ahead.






    share|improve this answer














    Moniathan



    def moniathan_CallBS(self, pos, player, handSize, currCard, numCards, numPile):
    if numCards > self.numBots * 0.5:
    return True
    if self.hand.count(currCard) == self.numBots:
    return True
    if self.hand.count(currCard) + numCards > self.numBots * 0.5:
    return True
    if numPile > self.numBots * 2:
    return True
    return False


    def moniathan_PlayCards(self, currCard, numPile, stillPlaying):
    cards = [c.val for c in self.hand]

    if cards.count(currCard) > 1:
    return cards.count(currCard) * [card(currCard)]

    if cards.count(currCard) == 1:
    if len(self.hand) > 1:
    add_more = self.getRandom() > 0.75
    if add_more:
    return [card(currCard), [c for c in self.hand if c.val != currCard][0]]
    else:
    return [card(currCard)]
    else:
    return [card(currCard)]
    else:
    if self.getRandom() > 0.5:
    if self.getRandom() > 0.5 and len(self.hand) > 1:
    return [self.hand[0], self.hand[1]]
    else:
    return [self.hand[0]]
    else:
    return


    def moniathan_StartRound(self):
    return max(self.hand, key=lambda x: self.hand.count(x.val)).val


    It mostly tries to play safe but sometimes it will take small risks to get ahead.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 22 at 14:35

























    answered Sep 22 at 1:11









    DobromirM

    2638




    2638











    • if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
      – Spitemaster
      Sep 22 at 12:59











    • Yes it should be ==. Thank you!
      – DobromirM
      Sep 22 at 14:36
















    • if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
      – Spitemaster
      Sep 22 at 12:59











    • Yes it should be ==. Thank you!
      – DobromirM
      Sep 22 at 14:36















    if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
    – Spitemaster
    Sep 22 at 12:59





    if self.hand.count(currCard) > self.numBots: This will never trigger, as you can't have more cards of that type than there are in the game. :)
    – Spitemaster
    Sep 22 at 12:59













    Yes it should be ==. Thank you!
    – DobromirM
    Sep 22 at 14:36




    Yes it should be ==. Thank you!
    – DobromirM
    Sep 22 at 14:36










    up vote
    2
    down vote













    Halfwit



    def halfwit_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
    # Call if I know he's lying
    if numCards + self.hand.count(currCard) > self.numBots:
    return True
    # Call if he'd win otherwise
    if handSize == 0:
    return True
    # Call if that would be more than half of the remaining cards, more than 3, and he's got lots of cards
    if handSize > 14 and numCards > 3 and numCards + self.hand.count(currCard) > (self.numBots - numPile) / 2:
    return True
    return False
    def halfwit_PlayCards(self,currCard,numPile,stillPlaying):
    # If I have this card, play all that I've got.
    if self.hand.count(currCard) > 0:
    return [card(currCard)] * self.hand.count(currCard)
    # If more than half of the cards of this value are allegedly already out, play nothing
    if numPile * 2 >= self.numBots:
    return
    # Play the smallest stack I've got.
    counts = [self.hand.count(i) for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")]
    choice = "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")[counts.index(min([x if x != 0 else 100 for x in counts]))]
    return [card(choice)] * min([x for x in counts if x != 0])
    def halfwit_StartRound(self):
    # Play the card I have the most of
    return max(self.hand, key=lambda x: self.hand.count(x.val)).val


    Halfwit always plays something - and he cheats if he doesn't have any of the right cards to play. Right now there's a few issues with the controller and with the bot and I'm not sure which is which, so I'll have to come back and fix some bugs later.






    share|improve this answer
























      up vote
      2
      down vote













      Halfwit



      def halfwit_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
      # Call if I know he's lying
      if numCards + self.hand.count(currCard) > self.numBots:
      return True
      # Call if he'd win otherwise
      if handSize == 0:
      return True
      # Call if that would be more than half of the remaining cards, more than 3, and he's got lots of cards
      if handSize > 14 and numCards > 3 and numCards + self.hand.count(currCard) > (self.numBots - numPile) / 2:
      return True
      return False
      def halfwit_PlayCards(self,currCard,numPile,stillPlaying):
      # If I have this card, play all that I've got.
      if self.hand.count(currCard) > 0:
      return [card(currCard)] * self.hand.count(currCard)
      # If more than half of the cards of this value are allegedly already out, play nothing
      if numPile * 2 >= self.numBots:
      return
      # Play the smallest stack I've got.
      counts = [self.hand.count(i) for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")]
      choice = "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")[counts.index(min([x if x != 0 else 100 for x in counts]))]
      return [card(choice)] * min([x for x in counts if x != 0])
      def halfwit_StartRound(self):
      # Play the card I have the most of
      return max(self.hand, key=lambda x: self.hand.count(x.val)).val


      Halfwit always plays something - and he cheats if he doesn't have any of the right cards to play. Right now there's a few issues with the controller and with the bot and I'm not sure which is which, so I'll have to come back and fix some bugs later.






      share|improve this answer






















        up vote
        2
        down vote










        up vote
        2
        down vote









        Halfwit



        def halfwit_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
        # Call if I know he's lying
        if numCards + self.hand.count(currCard) > self.numBots:
        return True
        # Call if he'd win otherwise
        if handSize == 0:
        return True
        # Call if that would be more than half of the remaining cards, more than 3, and he's got lots of cards
        if handSize > 14 and numCards > 3 and numCards + self.hand.count(currCard) > (self.numBots - numPile) / 2:
        return True
        return False
        def halfwit_PlayCards(self,currCard,numPile,stillPlaying):
        # If I have this card, play all that I've got.
        if self.hand.count(currCard) > 0:
        return [card(currCard)] * self.hand.count(currCard)
        # If more than half of the cards of this value are allegedly already out, play nothing
        if numPile * 2 >= self.numBots:
        return
        # Play the smallest stack I've got.
        counts = [self.hand.count(i) for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")]
        choice = "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")[counts.index(min([x if x != 0 else 100 for x in counts]))]
        return [card(choice)] * min([x for x in counts if x != 0])
        def halfwit_StartRound(self):
        # Play the card I have the most of
        return max(self.hand, key=lambda x: self.hand.count(x.val)).val


        Halfwit always plays something - and he cheats if he doesn't have any of the right cards to play. Right now there's a few issues with the controller and with the bot and I'm not sure which is which, so I'll have to come back and fix some bugs later.






        share|improve this answer












        Halfwit



        def halfwit_CallBS(self,pos,player,handSize,currCard,numCards,numPile):
        # Call if I know he's lying
        if numCards + self.hand.count(currCard) > self.numBots:
        return True
        # Call if he'd win otherwise
        if handSize == 0:
        return True
        # Call if that would be more than half of the remaining cards, more than 3, and he's got lots of cards
        if handSize > 14 and numCards > 3 and numCards + self.hand.count(currCard) > (self.numBots - numPile) / 2:
        return True
        return False
        def halfwit_PlayCards(self,currCard,numPile,stillPlaying):
        # If I have this card, play all that I've got.
        if self.hand.count(currCard) > 0:
        return [card(currCard)] * self.hand.count(currCard)
        # If more than half of the cards of this value are allegedly already out, play nothing
        if numPile * 2 >= self.numBots:
        return
        # Play the smallest stack I've got.
        counts = [self.hand.count(i) for i in "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")]
        choice = "A,2,3,4,5,6,7,8,9,10,J,Q,K,j".split(",")[counts.index(min([x if x != 0 else 100 for x in counts]))]
        return [card(choice)] * min([x for x in counts if x != 0])
        def halfwit_StartRound(self):
        # Play the card I have the most of
        return max(self.hand, key=lambda x: self.hand.count(x.val)).val


        Halfwit always plays something - and he cheats if he doesn't have any of the right cards to play. Right now there's a few issues with the controller and with the bot and I'm not sure which is which, so I'll have to come back and fix some bugs later.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 22 at 13:54









        Spitemaster

        1613




        1613



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f172628%2frussian-bs-submissions-accepted-until-october-13th%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)