Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Tic Tac Toe - Ui help
-
I’m currently working on a tic tac toe game and have a lot of the game fleshed out, but two things that have me stumped are the following:
-When the game is over, I want a pop up to ask if the user would like to play again
-Efficiently access ui elements (see restart function)In my ui file, I’ve got 9 buttons in a 3x3 named 1-9. When the user clicks one, it titles that button as “X” or “O” depending on whose turn it is. The game is able to determine the winner in all scenarios correctly, and displays whose turn it is and the winner in a label below.
Currently, I have a Restart button, but I’d like it to be a pop up after the game is over and am not sure how that works. The whole views part is throwing me off. I’ve read through the glossary in the app, but I’m still not able to make much sense of it.
Any help is appreciated! TIYA
turnCount = True #True for X, False for O #Create board array, allows us to check positions throughout the game board = [ ["-", "-", "-"], ["-", "-", "-"], ["-", "-", "-"] ] #gets row of input def row(sender): t = sender #user inputs 1. 1-1 = 0 / 3 = row 0 | inputs 8. 8 - 1 = 7 / 3 = row 2 row = (int(t) - 1) / 3 return int(row) def col(sender): t = sender #user inputs 2. 2 - 1 = 1 % 3 = row 2 | user inputs 9. 9 - 1 = 8 % 3 = row 2 col = (int(t) - 1) % 3 return int(col) def rowWin(sender, board): t = sender #gets first part of board array for row in board: rWin = True #check each space in each row for space in row: if space != t: rWin = False break if rWin: return True return False def colWin(sender, board): t = sender #Checks each column - first row for col in range(3): cWin = True #index all rows for row in range(3): if board[row][col] != t: cWin = False break if cWin: return True return False def diagWin(sender, board): t = sender if board[0][0] == t and board[1][1] == t and board[2][2] == t: return True elif board[2][0] == t and board[1][1] == t and board[0][2] == t: return True else: return False def isWin(sender, board): t = sender #Check each condition for a win after each turn if rowWin(t, board): return True if colWin(t, board): return True if diagWin(t, board): return True return False def turn(sender, label, board): #Buttons display - X or O t = sender.title #Buttons number n = sender.name #Set variable to determine whose turn it is global turnCount turn = turnChange() #assign X or O to selected button board[row(n)][col(n)] = turn #Change buttons and label dispaly, changes whose turn it is if turnCount: sender.title = turn label.text = "It's O's turn" turnCount = False else: sender.title = turn label.text = "It's X's turn" turnCount = True def turnChange(): global turnCount #Determines X or O output if turnCount: turn = "X" else: turn = "O" return turn def moveCheck(sender, board): #Check if button's display is empty or not' if sender.title is "": return True else: return False def restart(sender): global board #Define variable for all button elements b1 = sender.superview["1"] b2 = sender.superview["2"] b3 = sender.superview["3"] b4 = sender.superview["4"] b5 = sender.superview["5"] b6 = sender.superview["6"] b7 = sender.superview["7"] b8 = sender.superview["8"] b9 = sender.superview["9"] #Creates list for all buttons spaceList = [b1,b2,b3,b4,b5,b6,b7,b8,b9] #Reset the display of all buttons for space in spaceList: space.title = "" for row in board: for space in row: #Reset each space in programs board space = "-" def buttonPress(sender): #Gets button from UI t = sender user = turnChange() global board #Declare label from UI label = sender.superview["label1"] #Check if valid move if moveCheck(t, board): #If it's valid, place users input turn(t, label, board) #If not a valid move, display an error else:label.text = "This spot is taken" #After the move, check for a win if isWin(user, board): label.text = "{} Wins!".format(user) v = ui.load_view() v.present('sheet')
-
Does this help?
import console def restart(): print("Restarting") console.alert("Game Over", "Do you want to start a new game?", "OK") # Cancel throws an interrupt so no need # to check the result restart()
-
I ended up figuring out all the functions and the game is fully functional now, but I’m left with 2 questions :
-
Is there a more efficient way to grab all UI elements instead of calling them individually?
-
What’s the best way to export to windows to try and work on projects from my computer? When I tried running the program in VS, it kept giving me an error with import ui and wasn’t able to link up the .py and .pyui files
-
-
Is there a more efficient way to grab all UI elements instead of calling them individually?
Loop thru all ui.Buttons changing their tint_color and title while ignoring all ui.Labels...
from itertools import cycle from time import sleep import ui color_cycle = cycle(("red", "green", "blue", "black")) view = ui.View() view.add_subview( ui.Label( frame=(60, 5, 500, 20), text="This is a label, not a button so it will not change.", ) ) for i in range(9): view.add_subview(ui.Button(x=i * 20, y=i * 20, title=str(i))) view.present() while True: for subview in view.subviews: if isinstance(subview, ui.Button): subview.tint_color = next(color_cycle) subview.title = str(int(subview.title) + 1) sleep(2)
If you want to do this from a button action, you might need a construct like
sender.superview.superview.subviews
!! -
https://github.com/Pythonista-Tools has a Pythonista Tic-Tac-Toe UI in the Games directory.