Tree not functioning as exspected - python

I am trying to have my program load a tree of every possible tic-tac-toe board and then when given a random board input it can print out all the possible next moves based on the tree. However, when I try to do this all of my nodes seem to return None, except the root node.
My code right now:
import random
def main():
root = createNode(board, None, "X")
setBoard = (" ", " ", " ",
" ", "X", "X",
" ", " ", "O")
nextMoves = find(root, setBoard)
print(nextMoves)
for child in nextMoves.children:
printBoard(child.boardState)
boardCases = set()
board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
def printBoard(board):
for i in range(3):
print(board[i*3], end="")
print("|", end="")
print(board[i*3+1], end="")
print("|", end="")
print(board[i*3+2], end="")
print("")
if i < 2:
print("-+-+-")
print("~~~~~~~~~~~~")
def checkForWin(board, c):
# all column cases
for i in range(3):
if board[i] == c and board[i+3] == c and board[i+6] == c:
#print(c + " wins!")
return True
#all row cases
for i in range(3):
if board[i*3] == c and board[i*3+1] == c and board[i*3+2] == c:
#print(c + " wins!")
return True
#all across cases
if board[0] == c and board[4] == c and board[8] == c:
#print(c + " wins!")
return True
if board[2] == c and board[4] == c and board[6] == c:
#print(c + " wins!")
return True
#no wins game tie
counter = 0
for i in range(9):
if board[i] == " ":
# no tie found ---> game countinues
return False
else:
counter += 1
if counter == 9:
#print("Tie Game!")
return True
class boardNode:
def __init__(self):
self.boardState = ()
self.children = []
self.winner = ""
def numChildren(self):
return len(self.availableMoves())
def availableMoves(self):
moves = set()
for i in range(9):
if self.boardState[i] == " ":
moves.add(i)
return moves
counter = 0
def createNode(currentBoard, posToFill, c):
global counter
newNode = boardNode()
board = list(currentBoard)
counter +=1
if posToFill != None:
board[int(str(posToFill))] = c
newNode.boardState = tuple(board)
if checkForWin(tuple(board), c) == False:
newNode.winner = None
if c == "X":
for pos in newNode.availableMoves():
newNode.children.append(createNode(newNode.boardState, pos, "O"))
else:
for pos in newNode.availableMoves():
newNode.children.append(createNode(newNode.boardState, pos, "X"))
else:
newNode.winner = c
if newNode.boardState not in boardCases:
boardCases.add(newNode.boardState)
return newNode
def find(node, boardToSearch):
if list(node.boardState) == list(boardToSearch):
return node
else:
for child in node.children:
return find(child, boardToSearch)
if __name__ == "__main__":
main()
Here is my output for my current case:
$ python ticTacToe.py
None
Traceback (most recent call last):
File "test.py", line 115, in <module>
main()
File "test.py", line 11, in main
for child in nextMoves.children:
AttributeError: 'NoneType' object has no attribute 'children'

Related

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.

TicTacToe and Minimax

I am a young programmer that is learning python and struggling to implement an AI (using minimax) to play TicTacToe. I started watching a tutorial online, but the tutorial was on JavaScript and thus couldn't solve my problem. I also had a look at this question ( Python minimax for tictactoe ), but it did not have any answers and the implementation was considerably different from mine.
EDIT: the code you will find below is an edit suggested by one of the answers (#water_ghosts).
EDIT #2: I deleted possiblePositions, as the AI should choose a free field and not a place from the possiblePositions (that wouldn't make it that smart while implementing minimax :) )
Now the code doesn't give out any errors at all and functions properly, but one small thing: the AI always chooses the next available field. For example in situations where i am i move away from winning, instead of blocking my win option, it chooses the next free spot.
If you're wondering what that elements dict is doing there: i just wanted to make sure the programm chose the best index...
Here is my code:
class TicTacToe:
def __init__(self):
self.board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
self.playerSymbol = ""
self.playerPosition = []
self.aiSymbol = ""
self.aiPosition = []
self.score = 0
self.winner = None
self.scoreBoard = {
self.playerSymbol: -1,
self.aiSymbol: 1,
"tie": 0
}
self.turn = 0
self.optimalMove = int()
def drawBoard(self):
print(self.board[0] + " | " + self.board[1] + " | " + self.board[2])
print("___" + "___" + "___")
print(self.board[3] + " | " + self.board[4] + " | " + self.board[5])
print("___" + "___" + "___")
print(self.board[6] + " | " + self.board[7] + " | " + self.board[8])
def choice(self):
answer = input("What do you want to play as? (type x or o) ")
if answer.upper() == "X":
self.playerSymbol = "X"
self.aiSymbol = "O"
else:
self.playerSymbol = "O"
self.aiSymbol = "X"
def won(self):
winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}]
for position in winningPositions:
if position.issubset(self.playerPosition):
self.winner = self.playerSymbol
print("Player Wins :)")
return True
elif position.issubset(self.aiPosition):
self.winner = self.aiSymbol
print("AI wins :(")
return True
if self.board.count(" ") == 0:
self.winner = "tie"
print("Guess it's a draw")
return True
return False
def findOptimalPosition(self):
bestScore = float("-Infinity")
elements = {} # desperate times call for desperate measures
for i in range(9):
if self.board[i] == " ":
self.board[i] = self.aiSymbol # AI quasi made the move here
if self.minimax(True) > bestScore:
bestScore = self.score
elements[i] = bestScore
self.board[i] = " "
return max(elements, key=lambda k: elements[k])
def minimax(self, isMaximizing):
if self.winner is not None:
return self.scoreBoard[self.winner]
if isMaximizing:
bestScore = float("-Infinity")
for i in range(9):
if self.board[i] == " ":
self.board[i] = self.aiSymbol
bestScore = max(self.minimax(False), bestScore)
self.board[i] = " "
return bestScore
else:
bestScore = float("Infinity")
for i in range(9):
if self.board[i] == " ":
self.board[i] = self.playerSymbol
bestScore = min(self.minimax(True), bestScore)
self.board[i] = " "
return bestScore
def play(self):
self.choice()
while not self.won():
if self.turn % 2 == 0:
pos = int(input("Where would you like to play? (0-8) "))
self.playerPosition.append(pos)
self.board[pos] = self.playerSymbol
self.turn += 1
self.drawBoard()
else:
aiTurn = self.findOptimalPosition()
self.aiPosition.append(aiTurn)
self.board[aiTurn] = self.aiSymbol
self.turn += 1
print("\n")
print("\n")
self.drawBoard()
else:
print("Thanks for playing :)")
tictactoe = TicTacToe()
tictactoe.play()
I come from a java background and am not used to this :(
Any help would be highly appreciated
I am open to suggestions and ways to improve my code and fix this problem.
Thanks in advance and stay healthy,
Kristi
Change this part, your implementation will return optimalMove even if it doesn't go inside the if statement, and optimalMove will not be assigned at that point, so put the return inside.
if score > sampleScore:
sampleScore = score
optimalMove = i
return optimalMove
optimalMove = 0 in play() and optimalMove = i in findOptimalField() are declaring two distinct variables, each of which is local to the function declaring it.
If you want multiple functions to have access to the same variable, you can use the global keyword, but that's generally considered a bad practice. It can make it hard to reason about the code (e.g. is var = x creating a new local variable or overwriting the value of a global?) and it doesn't stop you from accidentally using a variable before it's declared.
Since you're coming from a Java background, you can turn this into a class to get behavior more like what you expect, eliminating the need for globals:
class TicTacToe:
def __init__(self):
self.board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
self.playerSymbol = ""
self.playerPosition = []
self.aiSymbol = ""
self.aiPosition = []
self.score = 0
self.playerSymbol = None
self.aiSymbol = None
...
def drawBoard(self):
print(self.board[0] + " | " + self.board[1] + " | " + self.board[2])
...
def choice(self):
answer = input("What do you want to play as? (type x or o) ")
if answer.upper() == "X":
self.playerSymbol = "X"
self.aiSymbol = "O"
...
Each method now takes an explicit self argument that refers to the current instance, and you can use this to access any variables that belong to the class instance instead of a particular method. If you don't include self. before a variable, that variable will still be local to the method that declares it. In this case, the drawBoard() method won't be able to access the answer variable defined in choice().
You can create new self. variables in any of the class's methods, but the best practice is to initialize all of them in the __init__ constructor method, using None as a placeholder for variables that don't have a value yet.
I am posting this as an answer, just in case somebody in the future stumbles upon the same problem :)
the main issue i encountered (besides my bad programming style) is that i forgot to update the contents the lists playerPosition and aiPosition.
You can review the rest of the changes in the working code:
class TicTacToe:
def __init__(self):
self.board = [" ", " ", " ", " ", " ", " ", " ", " ", " "]
self.playerSymbol = ""
self.playerPosition = []
self.aiSymbol = ""
self.aiPosition = []
self.winner = None
self.scoreBoard = None
self.turn = 0
self.optimalMove = int()
def drawBoard(self):
print(self.board[0] + " | " + self.board[1] + " | " + self.board[2])
print("___" + "___" + "___")
print(self.board[3] + " | " + self.board[4] + " | " + self.board[5])
print("___" + "___" + "___")
print(self.board[6] + " | " + self.board[7] + " | " + self.board[8])
def choice(self):
answer = input("What do you want to play as? (type x or o) ")
if answer.upper() == "X":
self.playerSymbol = "X"
self.aiSymbol = "O"
else:
self.playerSymbol = "O"
self.aiSymbol = "X"
self.scoreBoard = {
self.playerSymbol: -1,
self.aiSymbol: 1,
"tie": 0
}
def availableMoves(self):
moves = []
for i in range(0, len(self.board)):
if self.board[i] == " ":
moves.append(i)
return moves
def won_print(self):
self.won()
if self.winner == self.aiSymbol:
print("AI wins :(")
exit(0)
elif self.winner == self.playerSymbol:
print("Player Wins :)")
exit(0)
elif self.winner == "tie":
print("Guess it's a draw")
exit(0)
def won(self):
winningPositions = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
{0, 4, 8}, {2, 4, 6}, {0, 3, 6},
{1, 4, 7}, {2, 5, 8}]
for position in winningPositions:
if position.issubset(self.playerPosition):
self.winner = self.playerSymbol
return True
elif position.issubset(self.aiPosition):
self.winner = self.aiSymbol
return True
if self.board.count(" ") == 0:
self.winner = "tie"
return True
self.winner = None
return False
def set_i_ai(self, i):
self.aiPosition.append(i)
self.board[i] = self.aiSymbol
def set_clear_for_ai(self, i):
self.aiPosition.remove(i)
self.board[i] = " "
def set_i_player(self, i):
self.playerPosition.append(i)
self.board[i] = self.playerSymbol
def set_clear_for_player(self, i):
self.playerPosition.remove(i)
self.board[i] = " "
def findOptimalPosition(self):
bestScore = float("-Infinity")
elements = {} # desperate times call for desperate measures
for i in self.availableMoves():
self.set_i_ai(i)
score = self.minimax(False)
if score > bestScore:
bestScore = score
elements[i] = bestScore
self.set_clear_for_ai(i)
if bestScore == 1:
print("you messed up larry")
elif bestScore == 0:
print("hm")
else:
print("whoops i made a prog. error")
return max(elements, key=lambda k: elements[k])
def minimax(self, isMaximizing):
if self.won():
return self.scoreBoard[self.winner]
if isMaximizing:
bestScore = float("-Infinity")
for i in self.availableMoves():
self.set_i_ai(i)
bestScore = max(self.minimax(False), bestScore)
self.set_clear_for_ai(i)
return bestScore
else:
bestScore = float("Infinity")
for i in self.availableMoves():
self.set_i_player(i)
bestScore = min(self.minimax(True), bestScore)
self.set_clear_for_player(i)
return bestScore
def play(self):
self.choice()
while not self.won_print():
if self.turn % 2 == 0:
pos = int(input("Where would you like to play? (0-8) "))
self.playerPosition.append(pos)
self.board[pos] = self.playerSymbol
self.turn += 1
self.drawBoard()
else:
aiTurn = self.findOptimalPosition()
self.aiPosition.append(aiTurn)
self.board[aiTurn] = self.aiSymbol
self.turn += 1
print("\n")
print("\n")
self.drawBoard()
else:
print("Thanks for playing :)")
if __name__ == '__main__':
tictactoe = TicTacToe()
tictactoe.play()
But as mentioned, the code may work, but there are MANY problems regarding the logic and structure, so do not straight-forward copy-paste it :))

Python: Create Dict in function a and call it in function b

i have a problem with creating a dict in python.
In my mainloop i call function 1 which should creat an empty dict.
function 1 calls function 2.
function 2 calls itself (loop through a game tree)
but i can not use the dict i created in f1.
and it is not possible to pass it as agrument.
i would like to have the dict globaly accessible
def f1(): # function 1
#test_dict = {} # this needs to be global scope
#test_dict["key"] = "value"
test_dict["key2"] = "value2"
print (test_dict)
f2()
def f2(): # function 2
# here starts a loop that calls f2 again and again -> global dict is needed
# dict needs to be created
print (test_dict)
test_dict = {} # only works without errors when i create it before calling f1
test_dict["key"] = "value"
f1()
Here is my "real" Code :)
The >>MinMaxComputerMove<< need to edit the dict.
but at the end of a nood i cant pass it because the for loop just goes on.
# [] [] []
# [] [] []
# [] [] []
#Input Layer:
#9 Punkte mit -1 (geg.) 0 (leer) 1 (eig.)
from time import sleep
from random import randint
from random import choice
from IPython.display import clear_output
def clearBoard():
board = [0] * 10
return (board)
def drawBoard(board, PlayerSymbol, ComputerSymbol, turn):
turn += 1
#clear_output()
Symbolboard = []
for index, value in enumerate(board):
if value == 1:
Symbolboard.append(PlayerSymbol)
elif value == -1:
Symbolboard.append(ComputerSymbol)
else:
Symbolboard.append(" ")
print ("Turn: " + str(turn))
print ("")
print (str(Symbolboard[7]) + " - " + str(Symbolboard[8]) + " - " + str(Symbolboard[9]))
print ("| \ | / |")
print (str(Symbolboard[4]) + " - " + str(Symbolboard[5]) + " - " + str(Symbolboard[6]))
print ("| / | \ |")
print (str(Symbolboard[1]) + " - " + str(Symbolboard[2]) + " - " + str(Symbolboard[3]))
return (validMoves(board), turn)
def validMoves(board):
#return list with valid indices
validMoveList = []
for index, value in enumerate(board):
if index > 0 and value == 0:
validMoveList.append(index)
return (validMoveList)
def Symbol():
#X always goes first
if randint(0, 1) == 0:
print ("X: YOU")
print ("O: COMPUTER")
return ("X"), ("O")
else:
print ("X: COMPUTER")
print ("O: YOU")
return ("O"), ("X")
def PlayerMove(validMoveList, PlayerSymbol):
PlayerInput = input("Welches Feld? (1-9):")
if int(PlayerInput) in validMoveList:
return (PlayerInput, PlayerSymbol)
else:
print("Falsche Eingabe." + PlayerInput + " kein möglicher Zug")
def ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI):
print("ComputerMove")
if AI == 1:
return RandomComputerMove(validMoveList, ComputerSymbol)
elif AI == 2:
path_dict = {}
return MinMaxComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, depth = 1, firstrun = 1)
# more AIs
# ...
def ComputerThinking():
print("Computer is thinking", end = "")
sleep(0.5)
print(".", end = "")
sleep(0.5)
print(".", end = "")
sleep(0.5)
print(".")
sleep(1)
return
def RandomComputerMove(validMoveList, ComputerSymbol):
ComputerChoice = choice(validMoveList)
ComputerThinking()
print("ComputerChoice: " + str(ComputerChoice))
sleep(1.5)
print("RandomComputerMove Output: " + str((ComputerChoice, ComputerSymbol)))
return (ComputerChoice, ComputerSymbol)
def MinMaxComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, depth, firstrun = 0, start_path = -1):
initial_validMoveList = validMoveList.copy()
initial_board = board.copy()
turns_left = len(initial_validMoveList)
#debug
print("firstrun: " + str(firstrun))
print("depth: " + str(depth))
if firstrun == 1: #first run of function
path_dict = {}
for path, field in enumerate(initial_validMoveList):
path_dict[path] = {}
for extent in range(3):
path_dict[path][extent+1] = 5
#debug
print("---MinMaxComputerMove---")
print("Start MinMaxComputerMove with depth: " + str(depth))
print("validMoveList: " + str(validMoveList) + str(id(validMoveList)))
print("board: " + str(board) + str(id(board)))
print("ComputerSymbol: " + str(ComputerSymbol))
print("start_path: " + str(start_path))
for path, field in enumerate(initial_validMoveList): #(2, 6, 8):
if firstrun == 1:
start_path = path
print("start_path: " + str(start_path))
# for every path in tree diagram create a key in dict with empty list
# goal: dict("path": [field, depth_1_(max)value, depth_2_(min)value, depth_3_(max)value])
#debug
print("depth: " + str(depth))
if depth % 2 == 1: # Computer:
ChoosenIndex = (str(field), ComputerSymbol)
else: # Player
ChoosenIndex = (str(field), PlayerSymbol)
new_board = updateBoard(initial_board.copy(), ChoosenIndex, PlayerSymbol) # copy() or initial_board would change
new_validMoveList = validMoves(new_board)
#debug
print("---For Loop---")
print("ChoosenIndex: " + str(ChoosenIndex) + str(id(ChoosenIndex)))
print("new_validMoveList: " + str(new_validMoveList) + str(id(new_validMoveList)))
print("new_board: " + str(new_board) + str(id(new_board)))
print("path_dict: " + str(path_dict))
print("depth: " + str(depth))
if checkWinner(new_board) == 0 and depth != 3 and turns_left >= 1: # no winner yet and game not over
print ("no winner yet and game not over")
# go deeper
path_dict[start_path][depth] = 0
MinMaxComputerMove(new_validMoveList, new_board, PlayerSymbol, ComputerSymbol, depth + 1, 0, start_path)
elif checkWinner(new_board) == 0 and depth == 3 and turns_left >= 1: # no winner yet and game not over and minmax ends (depth = 3)
print ("checkWinner(new_board) == 0 and depth == 3 and turns_left >= 1")
path_dict[start_path][depth] = 0
elif checkWinner(new_board) == -1: # computer wins
print ("elif checkWinner(new_board) == -1")
if depth % 2 == 1: # Computer -> MIN:
path_dict[start_path][depth] <= -1
else: # Player -> MAX
if path_dict[start_path][depth] > -1:
path_dict[start_path][depth] = -1
elif checkWinner(new_board) == 1: # player wins
print ("elif checkWinner(new_board) == 1")
path_dict[start_path][depth] = 1
elif depth >= 3 or turns_left < 1: # reached depth 3 or no more turns
print ("elif depth >= 3 or turns_left < 1:")
else:
print ("else")
print("--- END FOR PATH ---")
print("--- END FOR LOOP ---")
print(path_dict)
# return choise
return (2, ComputerSymbol)
def updateBoard(board, ChoosenIndex, PlayerSymbol): #[0, 1, -1, 0, ...],[5, "X"], "X"
if PlayerSymbol == ChoosenIndex[1]:
board[int(ChoosenIndex[0])] = 1
return (board)
else:
board[int(ChoosenIndex[0])] = -1
return (board)
def checkWinner(board):
if (board[7] == board[8] == board[9]) and 0 != board[7]: # top row
return board[7]
elif (board[4] == board[5] == board[6]) and 0 != board[4]: # mid row
return board[4]
elif (board[1] == board[2] == board[3]) and 0 != board[1]: # bot row
return board[1]
elif (board[7] == board[4] == board[1]) and 0 != board[7]: # left column
return board[7]
elif (board[8] == board[5] == board[2]) and 0 != board[8]: # mid row
return board[8]
elif (board[9] == board[6] == board[3]) and 0 != board[9]: # right row
return board[9]
elif (board[7] == board[5] == board[3]) and 0 != board[7]: # diagonal \
return board[7]
elif(board[1] == board[5] == board[9]) and 0 != board[1]: # diagonal /
return board[1]
else:
return 0
def GameLoop(AI, turn = 0, winner = 0):
#choose AI difficulty
#...
#...
#set first player (X)
PlayerSymbol, ComputerSymbol = Symbol()
sleep(3)
#init board with list 10 * 0
board = clearBoard()
#debug
board = [0, 1, 0, 1, -1, -1, 0, 1, 0, -1]
PlayerSymbol, ComputerSymbol = ("O", "X") # computer first
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
while winner == 0 and turn <=9:
sleep(1.5)
if turn % 2 == 1: # "X" player move
if PlayerSymbol == "X":
#player move
ChoosenIndex = PlayerMove(validMoveList, PlayerSymbol)
#update current board
board = updateBoard(board, ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
#computer move
ChoosenIndex = ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else: # "O" player move
if PlayerSymbol == "O":
#player move
ChoosenIndex = PlayerMove(validMoveList, PlayerSymbol)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
#computer move
ChoosenIndex = ComputerMove(validMoveList, board, PlayerSymbol, ComputerSymbol, AI)
#update current board
board = updateBoard(board,ChoosenIndex, PlayerSymbol)
#draw current board
validMoveList, turn = drawBoard(board, PlayerSymbol, ComputerSymbol, turn)
#check for winner
winner = checkWinner(board)
else:
if winner == 1:
print ("YOU WON!")
elif winner == -1:
print ("COMPUTER WON!")
else:
print ("DRAW!")
GameLoop(AI = 2)
The "return value" answer is:
def f1(test_dict): # function 1
#test_dict = {} # this needs to be global scope
#test_dict["key"] = "value"
test_dict["key2"] = "value2"
print ('In f1 {}'.format(test_dict))
f2(test_dict)
return test_dict
def f2(test_dict): # function 2
# here starts a loop that calls f2 again and again -> global dict is needed
# dict needs to be created
print ('In f2 {}'.format(test_dict))
return test_dict
test_dict = {} # only works without errors when i create it before calling f1
test_dict["key"] = "value"
test_dict = f1(test_dict)
which gives output of:
In f1 {'key2': 'value2', 'key': 'value'}
In f2 {'key2': 'value2', 'key': 'value'}
But at some level, you probably want to put some of this into a class and then have test_dict as a variable within the class. That allows f1 and f2 (assuming they are class methods) to access the class variable without passing it as a parameter to the two methods.
class Example:
def __init__(self):
self._test_dict = {}
self._test_dict["key"] = "value"
def f1(self): # function 1
self._test_dict["key2"] = "value2"
print ('In f1 {}'.format(self._test_dict))
self.f2()
def f2(self): # function 2
print ('In f2 {}'.format(self._test_dict))
example = Example()
example.f1()
Below is a very simply version of what your script is attempting. You need to consider what your function parameters should be (what is passed to the function), as well as what your function should be providing at the end of its execution (given to you with the return statement). This way you can manipulate objects without having to keep everything in global scope, and you can avoid having to initialize every conceivable variable at the start of the routine.
Python Functions
Return Statement
def f1():
f1_dict = {}
f1_dict = f2(f1_dict)
return f1_dict
def f2(dict_arg):
f2_dict = {}
for i in range(0,5):
f2_dict[str(i)] = i**i
return f2_dict
dictionary = f1()
print(dictionary)

MVC infrastructure

import random
class Spinner(object):
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def getPosition(self):
return self.position
def getName(self):
return self.name
def spin(self):
newSpin = Spinner.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
class Display():
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(2)]
ladders[0][0] = 2
ladders[0][1] = 7
ladders[1][0] = 4
ladders[1][1] = 5
return ladders
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(2)]
chutes[0][0] = 9
chutes[0][1] = 2
chutes[1][0] = 6
chutes[1][1] = 3
return chutes
class Check(Player):
def checkLadders(self):
ladders = Display.buildLadders()
for i in range(0,len(ladders),1):
if self.getPosition() == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def checkChutes(self):
chutes = Display.buildChutes()
for i in range(0,len(chutes),1):
if self.getPosition() == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes! from " + \
str(chutes[i][0]) + " to " + str(chutes[i][1]))
def checkQuestions(num):
one = random.randint(num,num*10)
two = random.randint(num,num*10)
listqq = [one,two]
return listqq
class Controller(object):
def __init__(self,names):
self.winner = ''
self.players = []
for n in names:
p = Player(n)
self.players.append(p)
def move(self):
players = self.players
winner = self.winner
click = ''
count = 1
while True:
for i in range(0,len(players)):
if winner == '' and click != 'e':
print("----" + str(players[i].getName()) + "'s TURN----")
click = input("Press r to roll or e to exit: ")
while click != 'r' and click != 'e':
click = input("Press r to roll or e to exit: ")
if click == 'r' and click != 'e':
count = count + 1
listqq = Check.checkQuestions(count)
answer = input(str(listqq[0]) + ' + ' + str(listqq[1]) +' is:')
if answer == str(listqq[0]+listqq[1]):
print(str(players[i].getName()) + "'s initial position is " \
+ str(players[i].getPosition()))
View(players).display()
players[i].spin()
Check.checkLadders(players[i])
Check.checkChutes(players[i])
else:
pass
if players[i].getPosition() >= 12:
players[i].position = players[i].setPosition(12 - (players[i].getPosition() - 12))
print(str(players[i].getName()) + "'s new position is " \
+ str(players[i].getPosition()))
View(players).display()
if players[i].getPosition() == 12:
winner = players[i].getName()
if click == 'e' and click != 'r':
print('Bye')
break
if winner != '':
print(str(winner) + " is the winner!!!")
break
class View(Player):
def __init__(self,player):
self.players = player
def display(self):
players = self.players
listof = [9,10,11,12,8,7,6,5,1,2,3,4]
ladders = Display.buildLadders()
chutes = Display.buildChutes()
board = [[]] * 3
for i in range(len(players)):
for j in range(len(listof)):
if self.players[i].position == listof[j]:
listof[j] = 'X'
for j in range(len(listof)):
for i in range(len(ladders)):
if ladders[i][0] == listof[j]:
listof[j] = 'L'
for j in range(len(listof)):
for i in range(len(chutes)):
if chutes[i][0] == listof[j]:
listof[j] = 'C'
for i in range(0,4):
board[0] = board[0] + [listof[i]]
for i in range(4,8):
board[1] = board[1] + [listof[i]]
for i in range(8,12):
board[2] = board[2] + [listof[i]]
for row in board:
for num in row:
if num == 'X':
print(" X", end=" ")
if num == 'L':
print(" L", end= " ")
if num == 'C':
print(" C", end= " ")
if num != 'X' and num != 'L' and num != 'C':
if 10 <= num <= 20:
print(num,end=" ")
if num != 'X' and num != 'L' and num!= 'C':
if 1 <= num <= 9:
print(str(num).rjust(2), end= " ")
print()
def main():
n = input("Please enter number of players: ")
names = []
for i in range (0,int(n)):
name = input("Please input your name: ")
names.append(name)
game = Controller(names)
game.move()
while True:
ask = input("Do you want to play again? (y/n)")
if ask == 'y':
game = Controller(names)
game.move()
if ask == 'n':
print("Bye, see you again!")
break
main()
fixed version:
import random
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def spin(self):
newSpin = self.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
def checkLadders(self):
ladders = self.buildLadders()
for i in range(0,len(ladders),1):
if self.position == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def checkChutes(self):
chutes = self.buildChutes()
for i in range(0,len(chutes),1):
if self.position == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes! from " + \
str(chutes[i][0]) + " to " + str(chutes[i][1]))
#staticmethod
def checkQuestions(num):
one = random.randint(num,num*10)
two = random.randint(num,num*10)
listqq = [one,two]
return listqq
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
#staticmethod
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(2)]
ladders[0][0] = 2
ladders[0][1] = 7
ladders[1][0] = 4
ladders[1][1] = 5
return ladders
#staticmethod
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(2)]
chutes[0][0] = 9
chutes[0][1] = 2
chutes[1][0] = 6
chutes[1][1] = 3
return chutes
class Controller(object):
def __init__(self,names):
self.winner = ''
self.players = []
for n in names:
p = Player(n)
self.players.append(p)
def move(self):
players = self.players
winner = self.winner
click = ''
count = 1
while True:
for i in range(0,len(players)):
if winner == '' and click != 'e':
print("----" + str(players[i].name) + "'s TURN----")
click = input("Press r to roll or e to exit: ")
while click != 'r' and click != 'e':
click = input("Press r to roll or e to exit: ")
if click == 'r' and click != 'e':
count = count + 1
listqq = Player.checkQuestions(count)
answer = input(str(listqq[0]) + ' + ' + str(listqq[1]) +' is:')
if answer == str(listqq[0]+listqq[1]):
print(str(players[i].name) + "'s initial position is " \
+ str(players[i].position))
View(players).display()
players[i].spin()
Player.checkLadders(players[i])
Player.checkChutes(players[i])
else:
pass
if players[i].position >= 12:
players[i].position = players[i].setPosition(12 - (players[i].getPosition() - 12))
print(str(players[i].name) + "'s new position is " \
+ str(players[i].position))
View(players).display()
if players[i].position == 12:
winner = players[i].name
if click == 'e' and click != 'r':
print('Bye')
break
if winner != '':
print(str(winner) + " is the winner!!!")
break
class View():
def __init__(self,player):
self.players = player
def display(self):
players = self.players
listof = [9,10,11,12,8,7,6,5,1,2,3,4]
ladders = Player.buildLadders()
chutes = Player.buildChutes()
board = [[]] * 3
for i in range(len(players)):
for j in range(len(listof)):
if self.players[i].position == listof[j]:
listof[j] = 'X'
for j in range(len(listof)):
for i in range(len(ladders)):
if ladders[i][0] == listof[j]:
listof[j] = 'L'
for j in range(len(listof)):
for i in range(len(chutes)):
if chutes[i][0] == listof[j]:
listof[j] = 'C'
for i in range(0,4):
board[0] = board[0] + [listof[i]]
for i in range(4,8):
board[1] = board[1] + [listof[i]]
for i in range(8,12):
board[2] = board[2] + [listof[i]]
for row in board:
for num in row:
if num == 'X':
print(" X", end=" ")
if num == 'L':
print(" L", end= " ")
if num == 'C':
print(" C", end= " ")
if num != 'X' and num != 'L' and num != 'C':
if 10 <= num <= 20:
print(num,end=" ")
if num != 'X' and num != 'L' and num!= 'C':
if 1 <= num <= 9:
print(str(num).rjust(2), end= " ")
print()
def main():
n = input("Please enter number of players: ")
names = []
for i in range (0,int(n)):
name = input("Please input your name: ")
names.append(name)
game = Controller(names)
game.move()
while True:
ask = input("Do you want to play again? (y/n)")
if ask == 'y':
game = Controller(names)
game.move()
if ask == 'n':
print("Bye, see you again!")
break
main()
Is this following the MVC infrastructure? How to know if it fits the MVC structure or not? Thanks. Does we have to put each model,view,and controller in different module for it to be described as following the MVC structure?
First off the program is not really object oriented. View is instanciated every time when the game state has to be displayed just to call the one and only method. Classes with just the __init__() and one other method are a code smell because, like in this case, it's just a function crammed into a class for no good reason. The same can be said about Control — also just the __init__() and one additional method that get's called exactly once right after instanciating the object and directly after the call the object isn't used anymore.
Taking those ”fake” classes and considering the amount of static methods it seems you are under the impression classes automatically lead to object oriented programs — they don't. And there is nothing wrong with using functions instead of artificially introducing unnecessary complexity with classes that are just syntactically classes. Functions are objects too in Python, so when you have a display function it's okay to pass that around as „view” part of an MVC pattern. It's a callable object.
Which brings us to the MVC question: Supposing Player is the model then it should not interact with the user by printing stuff. Display and input is for the view to handle. So Control isn't a controller because the function in disguise also heavily interacts with the user via print() and input().

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