so my code looks like this:
def parse(info):
"""
'info' is a list made out of data received (info = list(data)). Examples are as follows:
['NEWGAME', '1', 'testbot', 'testbot', '100', '200', '2', '1', '10000.00000']
['NEWHAND', '1', '0', '4c', '5d', '0', '0', '0', '10000.00000']
['GETACTION', '3', '0', '2', 'POST:testbot:1,POST:testbot:2', '3', 'FOLD,CALL,RAISE:4', '10000.0']
['HANDOVER', '0', '0', '0', '3', 'FOLD:bot3001,FOLD:testbot,WIN:testbot:3', '9999.9506']
"""
phase = info[0] # setting board cards to 0
boardCard1 = 0 # 0 means no card
boardCard2 = 0
boardCard3 = 0
boardCard4 = 0
boardCard5 = 0
if phase == "NEWGAME":
gameID = int(info[1]) # Game ID
leftOpp = info[2] # Left Opponent
rightOpp = info[3] # Right Opponent
maxHands = int(info[4]) #Initializing number of hands that will be played
maxStackSize = int(info[5]) # Stack size, also the maximum bet size
bigBlind = int(info[6])
smBlind = int(info[7])
maxTime = float(info[8]) # Initiallizing milliseconds of time allocated for the game
return (phase, gameID, leftOpp, rightOpp, maxHands, maxStackSize, bigBlind, smBlind, maxTime)
if phase == "NEWHAND":
handID = int(info[1]) # The hand number which we're currently at
position = int(info[2]) # Possition, either 0, 1, or 2. 0 = dealer, 1 = smalll blind, 2 = big blind
card1 = info[3] # Card 1
card1Rank = (list(info[3]))[0] # Rank of Card 1
card1Suit = (list(info[3]))[1] # Suit of Card 1
card2 = info[4] # Card 2
card2Rank = (list(info[4]))[0] # Rank of Card 2
card2Suit = (list(info[4]))[1] # Suit of Card 2
hand = [card1, card2] # A list containing the 2 cards in your hand
bankRoll = int(info[5]) # Your bank roll, total amount made (can be negative)
leftOppBank = info[6] # Left Opponent's bankroll
rightOppBank = info[7] # Right Opponent's bankroll
timeLeft = float(info[8]) # Milliseconds of time allocated for the game
boardPhase = "PREFLOP" # Initializing boardPhase
return(boardPhase, phase, handID, position, card1, card1Rank, card1Suit, card2, card2Rank, card2Suit, hand, bankRoll, leftOppBank, rightOppBank, timeLeft)
elif phase == "GETACTION":
potSize = int(info[1])
numBoardCards = int(info[2]) # can be 0,3,4 or 5
boardCardsPacket = 0 # 0 for none, 1 for present
boardCards =[]
if numBoardCards != 0:
boardCardsPacket = 1
boardCards = (info[4]).split(",") # info[4] looks like 'Th,Ad,Js,5h' and split(",") turns it into [Th, Ad, Js, 5h]
boardCard1 = boardCards[0]
boardCard2 = boardCards[1]
boardCard3 = boardCards[2]
try:
boardCard4 = boardCards[3]
try:
boardCard5 = boardCards[4]
except:
pass
except:
pass
numLastActions = int(info[3+boardCardsPacket])
lastActions = []
if numLastActions != 0:
actionsString = info[4+boardCardsPacket] # a string of actions ex: POST:testbot:1,POST:testbot:2
lastActions = actionsString.split(",") # A list of the actions ex: ['POST:testbot:1','FOLD:testbot','WIN:testbot:3']
for i, item in enumerate(actions):
if "DEAL" in item.split(":"):
boardPhase = item.split(":")[1]
numLegalActions = int(info[5+boardCardsPacket])
legalActions = (info[6+boardCardsPacket]).split(",") # List of Legal Actions, ex: ['FOLD', 'CALL', 'RAISE:4']
minBet = "NULL" # it will be NULL if BET is not a legal action.
for i, item in enumerate(legalActions):
if "BET" in item.split(":"):
minBet = item.split(":")[1]
minRaise = "NULL"
for i, item in enumerate(legalActions):
if "RAISE" in item.split(":"):
minRaise = item.split(":")[1]
realLegalActions = []
for item1 in legalActions:
for item2 in item1.split(":"): # this creates realLegalActions which will not include numbers, will look like ['FOLD','CALL', 'RAISE'], makes it easier to check if an action is in legalActions
try:
int(item2)
except:
realLegalActions.append(item2)
timeLeft = float(info[7+boardCardsPacket])
try: # If the boardPhase is still PREFLOP then there is no variable boardPhase to return, so we have an exception for that.
return (realLegalActions, minBet, timeLeft, boardPhase, legalActions, numLegalActions, lastActions, numLastActions, boardCardsPacket,
boardCards, boardCard1, boardCard2, boardCard3, boardCard4, boardCard5, potSize, numBoardCards, minRaise)
except:
return (realLegalActions, minBet, timeLeft, legalActions, numLegalActions, lastActions, numLastActions, boardCardsPacket,
boardCards, boardCard1, boardCard2, boardCard3, boardCard4, boardCard5, potSize, numBoardCards, minRaise)
elif info[0] == "HANDOVER":
bankRoll = int(info[1])
leftOppBank = int(info[2])
rightOppBank = int(info[3])
numLastAction = int(info[4])
LastActions =[]
if numLastAction!=0:
LastActions = (info[5]).split(",")
timeLeft = float(info[6])
return(numLastAction, timeLeft, bankRoll, leftOppBank, rightOppBank, LastActions)
How can I use all the variables that I am returning? What would be the easiest way? Should I have created a class (I’m not too good at using classes but I will revisit my code if it’s possible with classes)?
edit—-
I just want to parse the strings and then return all the variables so I can use them in other classes and functions. This is the main function that is importing it:
import socket
import sys
import pokerParser
from time import time
import betMaster
import historian
if __name__ == "__main__":
port = int(sys.argv[1])
s = socket.create_connection(('127.0.0.1', int(sys.argv[1])))
f_in = s.makefile()
while 1:
start = time() # converting from seconds to miliseconds
data = f_in.readline()
if not data:
print "Gameover, engine disconnected"
break
info = data.split()
pokerParser.parse(info)
if phase == "HANDOVER":
historian.lastActionInitiator(lastActions)
if phase == "GETACTION":
if (timeLeft/handsRemaining) < (maxTime*.90)/maxHands:
output = "NULL" #Null is not a legalAction so it will be changed to CHECK or FOLD later.
while (maxTime-(time()-startTimeelapsedTime)*1000)*.90/(handsRemaining-1): #This will set the cutoff time for a response at a time that will set the bot back on track time-wise.
#output = jonsModule.attribute()
else:
while (time()-startTime)*1000 < (maxTime*.90)/maxHands:
#output = jonsModule.attribute()
#if output.split(":")[0] not in realLegalActions and "CHECK" in realLegalActions:
#output = "CHECK"
#if output.split(":")[0] == "BET":
#if output.split(":")[1] < minBet:
#output = "CHECK"
#if output.split(":")[0] == "RAISE":
#if output.split(":")[1] < minRaise:
#output = "CHECK"
#elif output not in legalActions and "CHECK" not in legalActions:
#output = "FOLD"
#s.send(output)
s.close()
# commented = dummy code for now
Short Answer
You may return variables from Python methods in any manner that makes sense to you, or your intended purpose. This may be a singular value, a tuple, a dictionary, a new class, or nothing at all – depending, of course, on your intention.
Long Answer (which may be a CodeReview issue)
In a context such as this, you will run into an issue in which there are too many variables defined keeping track of different things. It may be an old habit to use local-scope variables to keep track of stuff, but in Python, since you have the list (and you document what each position in the list represents somewhere), you could just use that explicitly instead.
Example:
It’s a matter of what the full intention and scope of your code is. I would strongly encourage that you sit down and refactor your code, so it is both clear in intent (not just to us, but to yourself), and each function is specific and well-defined in purpose.