Tic-Tac-Toe Game - python

I've wrote a code for the Tic-Tac-Toe game.
Here's what the code does:
Gets the name of Player 1.
Gets the name of Player 2.
Asks if the Player 1 wants X or O.
If he chooses X then Player 2 gets O and vice versa.
Prints the empty board.
Asks both players to enter the row and column one by one and prints the updated board.
If a player doesn't repeat previous player's spot, everything works fine until the end without any problem.
If a player repeats previous player's spot, a message is displayed saying that the previous player has already taken this spot and makes him guess again.
Now, after this point, if I guess any index other than the one that the previous player has already taken, it overwrites the previous players spot.
Screenshot of the terminal when this occurs:
I'm certain that the problem is in the function enterguess(turncount), but haven't been able to spot it yet. Any idea where the problem is?
<----------------------------------------------[ Demo Without the colors ]-------------------------------------------->
Code:
import termcolor
board = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
vb = termcolor.colored("|", "yellow", None, ['bold'])
s = termcolor.colored("\t+---+---+---+", "yellow", None, ['bold'])
players = {
'player1' : '',
'player2' : ''
}
sym = {
'player1': '',
'player2': ''
}
def rules ():
print("\nWelcome to Tic Tac Toe...")
def printboard():
#boardlist = [[" "," "," "],[" "," "," "],[" "," "," "]]
for row in board:
print s
print "\t" + vb + " " + row[0] + " " + vb + " " + row[1] + " " + vb + " " + row[2] + " " + vb
print s
def playerNames():
p1 = termcolor.colored(raw_input("\nEnter name of Player 1: ").title(), 'red', None, ['underline'])
p2 = termcolor.colored(raw_input("Enter name of Player 2: ").title(), 'blue', None, ['underline'])
sym['player1'] = termcolor.colored(raw_input("\n" + p1 + ', you want X or O? - ').capitalize(), 'red', None, ['bold'])
if sym['player1'] == 'X':
sym['player2'] = termcolor.colored('O', 'blue', None, ['bold'])
else:
sym['player2'] = termcolor.colored('X', 'red', None, ['bold'])
players['player1'] = p1
players['player2'] = p2
return {p1:termcolor.colored('X', 'red', None, ['bold']), p2: termcolor.colored('O', 'blue', None, ['bold'])}
def enterguess(turncount):
def guess(name):
return (int(input("\n" + players[name] + ", Enter row number: ")),
int(input(players[name] + ", Enter column number: ")))
if turncount % 2 == 0:
(row, col) = guess('player1')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player2'] + " already took that spot! Please guess again."
enterguess(turncount)
except:
print "\nPlease enter the indexes between 1 and 3."
enterguess(turncount)
else:
(row, col) = guess('player2')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player1'] + " already took that spot! Please guess again."
enterguess(turncount)
except IndexError:
print "\nPlease enter a number between 1 and 3."
enterguess(turncount)
return (row - 1, col - 1)
def changeboard(row, col, xo, c):
if c % 2 == 0:
board[row][col] = xo[players['player1']]
else:
board[row][col] = xo[players['player2']]
def checkWinner():
for x in range(3):
if board[x][0] == board[x][1] == board[x][2] and board[x][0] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[x][0]][0]
for y in range(3):
if board[0][y] == board[1][y] == board[2][y] and board[0][y] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[0][y]][0]
xx = 0
yy = 2
while True:
if board[xx][xx] == board[1][1] == board[2][yy] and board[xx][xx] != " ":
return [players[n] for n, s in sym.iteritems() if s == board[xx][xx]][0]
xx += 2
yy -= 2
if xx == 2:
break
def main():
rules()
xo = playerNames()
printboard()
turncount = 0
for turn in range(9):
(r, c) = enterguess(turncount)
print (r, c)
changeboard(r, c, xo, turncount)
turncount += 1
winner = checkWinner()
printboard()
if winner:
print("\nCongratulations " + winner + "! You are the winner.\n")
break
if turn == 8:
print ("\n Well! Its a tie.\n")
main()

The issue you have is that although you recall enterguess, you don't return it. So it simply keeps recalling enterguess until a valid input is given, then it just ignores all this and goes to the final return statement which still has the malformed guess.
Add return statements:
def enterguess(turncount):
def guess(name):
return (int(input("\n" + players[name] + ", Enter row number: ")),
int(input(players[name] + ", Enter column number: ")))
if turncount % 2 == 0:
(row, col) = guess('player1')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player2'] + " already took that spot! Please guess again."
return enterguess(turncount)
except:
print "\nPlease enter the indexes between 1 and 3."
return enterguess(turncount)
else:
(row, col) = guess('player2')
try:
if board[row - 1][col - 1] in [sym['player1'], sym['player2']]:
print "\n" + players['player1'] + " already took that spot! Please guess again."
return enterguess(turncount)
except IndexError:
print "\nPlease enter a number between 1 and 3."
return nterguess(turncount)
return (row - 1, col - 1)

Related

Why does my tic tac toe minimax algorithm not work?

Sorry to dump my code like this, but I've been pulling my hair out the last hours trying to figure out where my minimax algorithm in python is going wrong. Any help is greatly appreciated!
inf = 1000
bo = [["x", "o", "o"],
[" ", "o", " "],
[" ", "x", "x"]]
def bestMove(board):
bestScore = -inf
bestMove = None
for i in range(3):
for j in range(3):
if(board[i][j]==" "):
board[i][j]=getTurn(board)
score = minimax(board, searchdepth, True)
board[i][j]=" "
if score > bestScore:
bestScore = score
bestMove = [i, j]
print("\n\n\n")
return bestMove
searchdepth = 10
def minimax(node, depth, maxP):
resultat = win(node)
if resultat=="x": return 1
if resultat=="o": return -1
if resultat=="tie": return 0
if depth == 0: return 0
if maxP==True:
value = -inf
for i in range(3):
for j in range(3):
if node[i][j] == " ":
node[i][j] = getTurn(node)
newval = minimax(node, depth - 1, False)
node[i][j] = " "
value = max(newval, value)
return value
if maxP==False:
value = inf
for i in range(3):
for j in range(3):
if node[i][j] == " ":
node[i][j] = getTurn(node)
newval = minimax(node, depth - 1, True)
node[i][j] = " "
value = min(newval, value)
return value
print(bestMove(bo))
Output: [1, 0]
Expected output: [2, 0]
You are always sending a 1 in case 'X' wins, this is not correct. This means that if it is O:s turn it will think it is good if X wins. The easiest way would be to give a different value depending on who's turn it is, that is give a score of 1 if YOURSELF win, -1 if OPPONENT wins and 0 if draw.
I supplied versions of getTurn and win, since you didn't supply them, and I fixed the indentation problems below, and this prints out [2,0].
inf = 1000
bo = [[" ", " ", " "],
[" ", " ", " "],
[" ", " ", " "]]
def getTurn(board):
x = sum(n == 'x' for row in bo for n in row)
o = sum(n == 'o' for row in bo for n in row)
return 'x' if x == o else 'o'
def win(board):
for i in range(3):
if board[i][0]==board[i][1]==board[i][2] and board[i][0] != ' ':
return board[i][0]
if board[0][i]==board[1][i]==board[2][i] and board[0][i] != ' ':
return board[0][i]
if board[0][0]==board[1][1]==board[2][2] and board[0][0] != ' ':
return board[0][0]
if board[0][2]==board[1][1]==board[2][0] and board[0][2] != ' ':
return board[0][2]
if not any( n == ' ' for row in board for n in row ):
return 'tie'
return None
def bestMove(board):
bestScore = -inf
bestMove = None
for i in range(3):
for j in range(3):
if(board[i][j]==" "):
board[i][j]=getTurn(board)
score = minimax(board, searchdepth, True)
board[i][j]=" "
if score > bestScore:
bestScore = score
bestMove = [i, j]
return bestMove
searchdepth = 10
def minimax(node, depth, maxP):
resultat = win(node)
if resultat=="x": return 1
if resultat=="o": return -1
if resultat=="tie": return 0
if depth == 0: return 0
if maxP:
value = -inf
for i in range(3):
for j in range(3):
if node[i][j] == " ":
node[i][j] = getTurn(node)
newval = minimax(node, depth - 1, False)
node[i][j] = " "
value = max(newval, value)
else:
value = inf
for i in range(3):
for j in range(3):
if node[i][j] == " ":
node[i][j] = getTurn(node)
newval = minimax(node, depth - 1, True)
node[i][j] = " "
value = min(newval, value)
return value
while not win(bo):
t = getTurn(bo)
m = bestMove(bo)
bo[m[0]][m[1]] = t
print(bo)
print("Result:",win(bo))

Loop over a list from the middle outwards

I am making a connect four AI and would like the AI to loop through the available moves from the middle and outwards because in connect four the middle moves are usually better and then the probability of alpha beta pruning happening is much higher.
For example if I gave it a array like this: [1,2,3,4,5]
It should loop though them like this 3,4,2,5,1
Or with a array like this [1,2,3,4,5,6]
It should loop though them like this 4,3,5,2,6,1
Thanks in advance
This is my code for connect four:
import os # os.system('cls') to clear screen
import random
import time
import sys
class ConnectFour:
def __init__(self):
self.board = [[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "]]
self.numberLine = [1,2,3,4,5,6,7]
self.rowCount = 6
self.columnCount = 7
def printBoard(self, column=None, row=None):
os.system('cls') # clears the screen
terminalWidth = os.get_terminal_size().columns
terminalHeight = os.get_terminal_size().lines
playerToHighlighted = {
'R': '\033[91;44mR\033[0m',
'Y': '\033[93;44mY\033[0m' }
print("\n"*round(terminalHeight/2 - (1 + self.columnCount))) #
highlightedPlayer = ''
try:
playerHold = self.board[row][column]
self.board[row][column] = 'H'
highlightedPlayer = playerToHighlighted[playerHold]
except:
pass
print(
((((
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[5])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[4])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[3])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[2])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[1])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
((" {} | {} | {} | {} | {} | {} | {} ".format(*self.board[0])).center(terminalWidth)) + '\n' +
'\033[94m' + ("---------------------------------------").center(terminalWidth) + '\033[0m' + '\n' +
(((" {} | {} | {} | {} | {} | {} | {} ").format(*self.numberLine)).center(terminalWidth))).replace('Y', '\033[93mY\033[0m')).replace('R', "\033[91mR\033[0m")).replace('|', '\033[94m|\033[0m')).replace('H', highlightedPlayer) )
try:
self.board[row][column] = playerHold
except:
pass
def clearBoard(self):
self.board = [[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "],
[" ", " ", " ", " ", " ", " "," "]]
def makeMove(self, position, player):
for row in range(self.rowCount):
if self.board[row][position] == " ":
self.board[row][position] = player
return row
def availableMoves(self): # this might be broken
moves = []
for column in range(self.columnCount):
if self.board[self.rowCount - 1][column] == ' ':
moves.append(column)
return moves
def removeMove(self, row, column):
self.board[row][column] = " "
def checkWin(self):
for player in ('R', 'Y'):
for column in range(self.columnCount - 3): # Check vertical locations for win
for row in range(self.rowCount):
if self.board[row][column] == player and self.board[row][column+1] == player and self.board[row][column+2] == player and self.board[row][column+3] == player:
return player
for column in range(self.columnCount): # Check vertical locations for win
for row in range(self.rowCount - 3):
if self.board[row][column] == player and self.board[row+1][column] == player and self.board[row+2][column] == player and self.board[row+3][column] == player:
return player
for column in range(self.columnCount- 3): # Check positively sloped diaganols
for row in range(self.rowCount - 3):
if self.board[row][column] == player and self.board[row+1][column+1] == player and self.board[row+2][column+2] == player and self.board[row+3][column+3] == player:
return player
for column in range(self.columnCount-3): # Check negatively sloped diaganols
for row in range(3, self.rowCount):
if self.board[row][column] == player and self.board[row-1][column+1] == player and self.board[row-2][column+2] == player and self.board[row-3][column+3] == player:
return player
def whoWon(self):
if self.checkWin() == 'R':
return "Red"
elif self.checkWin() == 'Y':
return "Yellow"
elif self.checkGameOver() == True:
return "Nobody"
def checkGameOver(self):
if self.checkWin() != None:
return True
for column in range(self.columnCount):
if self.board[self.rowCount - 1][column] == " ":
return False
return True
def getMoveCount(self, player): # getStoneCount this can be better
moveCount = 0
for column in range(self.columnCount):
for row in range(self.rowCount):
if self.board[row][column] == player:
moveCount += 1
return moveCount
def minimax(self, node, depth, alpha, beta, player):
if depth == 0 or node.checkGameOver():
if node.checkWin() == 'R':
return -(22 - self.getMoveCount('R'))
elif node.checkWin() == 'Y':
return 22 - self.getMoveCount('Y')
else:
return 0
if player == 'Y':
maxValue = -(sys.maxsize)
for move in node.availableMoves():
moveRow = node.makeMove(move, player)
moveValue = self.minimax(node, depth-1, alpha, beta, changePlayer(player))
node.removeMove(moveRow, move)
maxValue = max(maxValue, moveValue)
alpha = max(alpha, moveValue)
if beta <= alpha:
break
return maxValue
if player == 'R':
minValue = sys.maxsize
for move in node.availableMoves():
moveRow = node.makeMove(move, player)
moveValue = self.minimax(node, depth-1, alpha, beta, changePlayer(player))
node.removeMove(moveRow, move)
minValue = min(minValue, moveValue)
beta = min(beta, moveValue)
if beta <= alpha:
break
return minValue
def changePlayer(player):
if player == 'R':
return 'Y'
else:
return 'R'
def makeBestMove(board, depth, player):
neutralValue = 0
choices = []
bestLossingMoveValue = -(sys.maxsize)
for move in board.availableMoves():
moveRow = board.makeMove(move, player)
moveValue = board.minimax(board, depth-1, -(sys.maxsize), sys.maxsize, changePlayer(player))
board.removeMove(moveRow, move)
print(moveValue)
if moveValue > neutralValue:
choices = [move]
#instaWin = True
break
elif moveValue == neutralValue:
choices.append(move)
elif moveValue > bestLossingMoveValue:
bestLossingMove = move
if len(choices) > 0:
return random.choice(choices), choices
elif bestLossingMove != None:
return bestLossingMove, [False]
else:
return random.choice(board.availableMoves()), [] # idk if i need this
def askPlayAgain():
terminalWidth = os.get_terminal_size().columns
print("Would you like to play again?".center(terminalWidth))
playAgain = input(' ' * round(terminalWidth/2 - 8) + "Enter y/n here: ")
if playAgain == 'y':
game.clearBoard()
game.printBoard()
setupGame()
elif playAgain == 'n':
exit()
else:
game.printBoard()
print("Error: Please try again!".center(terminalWidth))
askPlayAgain()
playerToColor = {
'R': '\033[91mRed\033[0m',
'Y': '\033[93mYellow\033[0m' }
def askPlayerMove(player):
terminalWidth = os.get_terminal_size().columns
print(("You are " + playerToColor[player] + ": Choose number from 1-7").center(terminalWidth + 8))
move = input(" " * round(terminalWidth/2 - 9) + "Enter Move Here: ")
try:
move = int(move) - 1
except:
game.printBoard()
print("Error: Please try again!".center(terminalWidth))
return askPlayerMove(player)
if move >= 0 and move <= game.columnCount - 1:
row = game.makeMove(move, player)
return [move, row]
else:
game.printBoard()
print("Error: Please try again!".center(terminalWidth))
return askPlayerMove(player)
def askDepth():
terminalWidth = os.get_terminal_size().columns
print(("What depth do you want the engine to use?").center(terminalWidth))
depth = input(" " * round(terminalWidth/2 - 17) + "Enter depth here: (Recommended: 9) ")
try:
depth = int(depth)
return depth
except:
game.printBoard()
print("Error: Please try again!".center(terminalWidth))
return askDepth()
def setupGame():
terminalWidth = os.get_terminal_size().columns
print("Would you like to play computer or player".center(terminalWidth))
gameMode = input(" " * round(terminalWidth/2 - 8) + "Enter c/p Here: ")
if gameMode == 'p':
startGame(gameMode)
elif gameMode == 'c':
game.printBoard()
depth = askDepth()
startGame(gameMode, depth)
else:
game.printBoard()
print("Error: Please try again!".center(terminalWidth))
setupGame()
def startGame(gameMode, depth=None):
game.printBoard()
while game.checkGameOver() == False:
movePosition = askPlayerMove('R')
game.printBoard(movePosition[0], movePosition[1])
if game.checkGameOver() == True:
break
if gameMode == 'c':
terminalWidth = os.get_terminal_size().columns
print("Computer choosing move...".center(terminalWidth))
computerMove = makeBestMove(game, depth, 'Y')
movePosition[1] = game.makeMove(computerMove[0], 'Y')
movePosition[0] = computerMove[0]
computerChoices = computerMove[1]
elif gameMode == 'p':
movePosition = askPlayerMove('Y')
game.printBoard(movePosition[0], movePosition[1])
if gameMode == 'c':
print(("Computer choices are " + str(computerChoices)).center(terminalWidth))
terminalWidth = os.get_terminal_size().columns
game.printBoard()
print(("Game Over. " + game.whoWon() + " Wins").center(terminalWidth))
askPlayAgain()
if __name__ == '__main__':
game = ConnectFour()
game.printBoard()
setupGame() #start game
Always taking the middle out:
def middle_out(a):
while a:
yield a.pop(len(a) // 2)
Demo:
>>> print(*middle_out([1,2,3,4,5]))
3 4 2 5 1
>>> print(*middle_out([1,2,3,4,5,6]))
4 3 5 2 6 1
If you want to sort by distance to middle, you can use a lambda expression.
a = [1, 2, 3, 4, 5]
sortedByMiddle = sorted(a, key = lambda x: abs(x-a[len(a)//2]))
This will loop through the array and sort by the absolute value of the difference between the element and middle value of the array.

Python skipping elif statement

I'm trying to write a program that prints the values and keys in a dictionary depending of the input the user types. The problem appears when the elif statement on line 11 gets skipped. It doesn't matter if the if statement is false, the elif statement gets skipped. I'm learning so I don't really know where my error is. Thanks for the help!
areaM = {str(1) + " acre" : str(160) + " sq rods"}
linearM = {str(1) + " ft" : str(12) + " in", str(1) + " yd": str(3) + " ft"}
def displayConversion(conv):
for k, v in conv.items():
print(str(v) + " = " + str(k))
while True:
print("Enter a conversion")
if input() == "Area Meassure":
displayConversion(areaM)
elif input() == "Linear Meassure":
displayConversion(linearM)
else:
print("Conversion not available")
Maybe this as the full code (too much inputss):
areaM = {str(1) + " acre" : str(160) + " sq rods"}
linearM = {str(1) + " ft" : str(12) + " in", str(1) + " yd": str(3) + " ft"}
def displayConversion(conv):
for k, v in conv.items():
print(str(v) + " = " + str(k))
while True:
a=input("Enter a conversion\n")
if a == "Area Meassure":
displayConversion(areaM)
break
elif a == "Linear Meassure":
displayConversion(linearM)
break
else:
print("Conversion not available")

TIC TAC TOE GAME - python

i wrote a "tic tac toe" game in python(pycharm). At the end of the game i asked the user if he wants to play again: if he pressed 'y' the game began again, and if he pressed 'n' the game/code stopped. do you know how can i show him an error massege like: "you entered a wrong answer! please try again:" when he doesn't press any of this letters but somthing else? for example:
"Would you like to play again? "fnj"(his answer). And show this massage until he enter a correct answer?
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def playTicTacToe():
rows,cols = 3,3
winLength = 3
board = makeNewBoard(rows, cols)
moves = 0
player = 1
while moves < rows*cols:
row,col = getMove(board, player)
board = setPiece(board, row, col, player)
if (didWin(board, player, winLength)):
printBoard(board)
print ""
#print '%s The Player %s color.GREEN + color.Bold + "-->" + color.END, """ IS THE WINNER OF THE GAME!!!""" + color.END % (color.GREEN,getPieceLabel(player),
print color.RED + color.BOLD + "The Player" + color.END, getPieceLabel(player), color.RED + color.BOLD + "IS THE WINNER OF THE GAME!!! " + color.END
return
player = otherPlayer(player)
moves += 1
print color.RED + color.BOLD + "TIE GAME!" + color.END
def makeNewBoard(rows, cols):
return [([0]*cols) for row in xrange(rows)]
def getRows(board):
return len(board)
def getCols(board):
return len(board[0])
def getPiece(board, row, col):
return board[row][col]
def setPiece(board, row, col, value):
board[row][col] = value
return board
def isEmpty(board, row, col):
return (getPiece(board, row, col) == 0)
def isOnBoard(board, row, col):
rows = getRows(board)
cols = getCols(board)
return ((row >= 0) and (row < rows) and
(col >= 0) and (col < cols))
def getPieceLabel(piece):
if (piece == 1):
return "|" + color.PURPLE + color.BOLD + "X" + color.END + "|"
elif (piece == 2):
return "|" + color.BLUE + color.BOLD + "O" + color.END + "|"
else:
return color.BOLD + "|_|" + color.END
def printBoard(board):
print "\n-----------------------------------------------------------------------------------------------------------"
rows = getRows(board)
cols = getCols(board)
for row in xrange(rows):
for col in xrange(cols):
piece = getPiece(board, row, col)
label = getPieceLabel(piece)
print label,
print
def didWin(board, player, winLength):
rows = getRows(board)
cols = getCols(board)
for startRow in xrange(rows):
for startCol in xrange(cols):
if (didWin1(board, player, winLength, startRow, startCol)):
return True
return False
def didWin1(board, player, winLength, startRow, startCol):
for drow in xrange(-1,+2):
for dcol in xrange(-1,+2):
if ((drow != 0) or (dcol != 0)):
if (didWin2(board, player, winLength,
startRow, startCol, drow, dcol)):
return True
return False
def didWin2(board, player, winLength,
startRow, startCol, drow, dcol):
rows = getRows(board)
cols = getCols(board)
for step in xrange(winLength):
row = startRow + step*drow
col = startCol + step*dcol
if (not isOnBoard(board, row, col)):
return False
elif (getPiece(board, row, col) != player):
return False
return True
def otherPlayer(player):
return 1 if (player == 2) else 2
def oops(msg):
print " ", msg, color.RED + color.BOLD + "Try again." + color.END
def readInt(prompt):
while True:
try:
return int(raw_input(prompt))
except:
oops(color.RED + color.BOLD + "Input must be an integer." + color.END)
def getMove(board, player):
while True:
printBoard(board)
print "Enter move for player:" + getPieceLabel(player)
row = readInt(" Row --> ") - 1
col = readInt(" Col --> ") - 1
if (not isOnBoard(board, row, col)):
oops(color.RED + color.BOLD + """\n \n Out of range (not on the board)!""" + color.END)
elif (not isEmpty(board, row, col)):
oops(color.RED + color.BOLD +"""\n Already occupied!""" + color.END)
else:
return (row, col)
def finish():
answer = raw_input(color.PURPLE + color.BOLD + """Would you like to play again?! (press \'y\' for yes and \'n\' for no):""" + color.END)
if answer.lower() == "n":
print ""
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
if answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
def main():
while True:
playTicTacToe()
if finish():
break
if __name__ == '__main__':
main()
You can modify the finish function as follows:
def finish():
while True:
answer = raw_input(color.PURPLE + color.BOLD + """Would you like to play again?! (press \'y\' for yes and \'n\' for no):""" + color.END)
if answer.lower() == "n":
print ""
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
elif answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
else:
print 'Not valid input...'
By this way the program ignores invalid inputs and asks the user again.
PS. I would suggest to insert a mechanism for exiting before the completion of the game in the case the user wants to terminate the game.
if answer.lower() == "n":
print color.BLUE + color.BOLD + "Bye Bye! See you next time! :)" + color.END
return True
elif answer.lower() == "y":
print (color.BLUE + color.BOLD + """\nGreat choice! The game will start again""" + color.END)
return False
else:
print (color.BLUE + color.BOLD + """\nyou entered a wrong answer! please try again:""" + color.END)
return False

trouble with classes in python

I am getting an error that reads this and no matter what I do I am unable to get rid of this code.
Traceback (most recent call last):
File "C:\Users\Ian\Desktop\BlackJack.py", line 226, in <module>
main()
File "C:\Users\Ian\Desktop\BlackJack.py", line 225, in main
blackjack.playgame()
File "C:\Users\Ian\Desktop\BlackJack.py", line 145, in playgame
self.firstround()
File "C:\Users\Ian\Desktop\BlackJack.py", line 83, in firstround
a=self.dealer.hand.append(DeckofCards.deal(DeckofCards.shuffledeck))
AttributeError: type object 'DeckofCards' has no attribute 'shuffledeck'
The following is the actual code that I have written ( I have changed a great deal in order to move the error along but can no longer figure out what is going on) I am really just want someone to skim over this and tell me about the obvious mistakes, I am sure there are many, and I apologize but our professor doesn't teach use how to do things and then just expects us to know how.
from random import*
class Card(object):
def __init__(self,suit,number):
self.suit=suit
self.number=number
class DeckofCards(object):
def __init__(self,deck):
self.deck=deck
self.shuffledeck=self.shuffle()
#print(self.shuffledeck)
def shuffle(self):
#print('This is shuffle function')
b=[]
count=0
while count<len(self.deck):
a=randrange(0,len(self.deck))
if a not in b:
b.append(self.deck[a])
count+=1
return(b)
def deal(self):
if len(self.shuffledeck)>0:
return(self.shuffledeck.pop(0))
else:
shuffle(self)
return(self.shuffledeck.pop(0))
class Player(object):
def __init__(self,name,hand,inout,money,score,bid):
self.name=name
self.hand=hand
self.inout=inout
self.money=money
self.score=score
self.bid=bid
def __str__(self):
x = self.name + ":\t"
x += "Card(s):"
for y in range(len(self.hand)):
x +=self.hand[y].face + self.hand[y].suit + " "
if (self.name != "dealer"):
x += "\t Money: $" + str(self.money)
return(x)
class Game(object):
def __init__(self,deck, player):
self.player=Player(player,[],True,100,0,0)
self.dealer=Player("Dealer",[],True,100,0,0)
self.deck=DeckofCards(deck)
self.blackjack= False #self.blackjacksearch()
def blackjacksearch(self):#this is where it says there is an error we moved this because she said it needed to be in this class to get the Getot function
if self.player.hand.gettot()==21:
return True
else:
return False
def firstround(self):
self.player.inout=True
self.player.hand=[]
self.dealer.hand=[]
a=self.dealer.hand.append(DeckofCards.deal(DeckofCards.shuffledeck))
print(a)
playerbid=int(input('How much would you like to bet?'))
self.player.bid=playerbid
def playturn(self):
while self.player.blackjack!=True or hit=='yes':
print(self.player.hand)
a=self.player.hand.append(deal())
print('The card that you just drew is ' + str(a))
print(gettot())
hit=input('Would you like to hit? ')
if hit=='yes':
return(self.player.hand.append(deal()))
else:
return() #might need to change this
if self.player.blackjack==True:
print(self.player.name + " has blackjack ")
if hit=='no':
print (self.player.hand.gettot())
def playdealer(self):
while self.dealer.hand<17:
self.dealer.hand.append(deal())
dealerhand=self.dealer.hand.gettot() #confused
print(dealerhand)
if self.dealer.hand==21:
self.dealer.blackhjack=True
dealerhand1=self.dealer.hand.gettot()
print(dealerhand1)
def gettot(self,hand):
total=0
for x in self.hand:
if x==Card('H','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('D','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('S','A'):
b=total+x
if b>21:
total+=1
else:
total+=11
if x==Card('C','A'):
if b>21:
total+=1
else:
total+=11
else:
total+=x
return(total)
def playgame(self):
play = "yes"
while (play.lower() == "yes"):
self.firstround()
self.playturn()
if self.player.blackjack == True:
print(self.player.name + " got BLACKJACK! ")
self.player.money += self.player.bid * 1.5
print (self.player.name + " now has " + str(self.player.money))
print("\n")
self.player.inout = False
if self.player.score > 21:
print(self.player.name + " lost with a tot of " + str(self.player.score))
self.player.money -= self.player.bid
print (self.player.name + " now has " + str(self.player.money))
print ("\n\n")
self.player.inout = False
self.playdealer()
if self.dealer.blackjack == True:
print("Dealer got blackjack, dealer wins\n")
self.player.money -= self.player.bid
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
elif self.player.inout == True:
print("Round\n")
print("\t",self.dealer)
print("\t",self.player)
print("\n\t Dealer has " + str(self.dealer.score) + ", " + self.player.name + " has " + str(self.player.score))
if self.dealer.score > 21:
print("\t Dealer lost with a total of " + str(self.dealer.score))
self.player.money += self.player.bid
print(self.player.name + " now has " + str(self.player.money))
elif self.player.score > self.dealer.score:
print("\t" +self.player.name + " won with a total of " + str(self.player.score))
self.player.money += self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("\t Dealer won with a total of " + str(self.dealer.score))
self.player.money -= self.player.bid
print("\t"+self.player.name + " now has " + str(self.player.money))
else:
print("Round")
print("\t",self.dealer)
print("\t",self.player)
if self.player.blackjack == False:
print("\t "+ self.player.name + " lost" )
else:
print("\t "+self.player.name + " Won!")
if self.player.money <= 0:
print(self.player.name + " out of money - out of game ")
play = "no"
else:
play = input("\nAnother round? ")
print("\n\n")
print("\nGame over. ")
print(self.player.name + " ended with " + str(self.player.money) + " dollars.\n")
print("Thanks for playing. Come back soon!")
ls= [Card('H','A'),Card('H','2'),Card('H','3'),Card('H','4'),Card('H','5'),Card('H','6'),Card('H','7'),Card('H','8'),Card('H','9'),Card('H','10'),
Card('H','J'),Card('H','Q'),Card('H','K'),
Card('S','A'),Card('S','2'),Card('S','3'),Card('S','4'),Card('S','5'),
Card('S','6'),Card('S','7'),Card('S','8'),Card('S','9'),Card('S','10'),
Card('S','J'),Card('S','Q'),Card('S','K'),
Card('C','A'),Card('C','2'),Card('C','3'),Card('C','4'),Card('C','5'),
Card('C','6'),Card('C','7'),Card('C','8'),Card('C','9'),Card('C','10'),
Card('C','J'),Card('C','Q'),Card('C','K'),
Card('D','A'),Card('D','2'),Card('D','3'),Card('D','4'),Card('D','5'),
Card('D','6'),Card('D','7'),Card('D','8'),Card('D','9'),Card('D','10'),
Card('D','J'),Card('D','Q'),Card('D','K')]
'''tom=Card('Heart','Queen')
print(tom.suit)
print(DeckofCards(ls))
print(ls.suit)'''
def main():
x = input("Player's name? ")
blackjack = Game(ls,x)
blackjack.playgame()
main()
This line right is one problem:
a=self.dealer.hand.append(DeckofCards.deal(DeckofCards.shuffledeck))
append returns None (regardless of what you append), so a will be None
DeckofCards refers to the class object, not an instance of the class. You probably want to use self.deck instead of DeckofCards.
x==Card('S','A'): isn't going to work either. You haven't defined __eq__ for the Card object, so comparisons don't work (you'll always get False).
The shuffledeck attribute only exists for instances of DeckOfCards, change DeckOfCards.shuffledeck to DeckOfCards().shuffledeck.
class Game(object):
def __init__(self,deck, player):
self.player=Player(player,[],True,100,0,0)
self.dealer=Player("Dealer",[],True,100,0,0)
self.deck=DeckofCards(deck)
self.blackjack= False #self.blackjacksearch()
def blackjacksearch(self):#this is where it says there is an error we moved this because she said it needed to be in this class to get the Getot function
if self.player.hand.gettot()==21:
return True
else:
return False
def firstround(self):
self.player.inout=True
self.player.hand=[]
self.dealer.hand=[]
a=self.dealer.hand.append(DeckofCards.deal(DeckofCards.shuffledeck))
You are using the class incorrectly. The DeckofCards was never created.
a=self.dealer.hand.append(self.deck.deal(self.deck.shuffledeck))

Categories