Forum Archive

Tic Tac Toe - Ui help

XenithRai

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')

mikael

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()
XenithRai

I ended up figuring out all the functions and the game is fully functional now, but I’m left with 2 questions :

  1. Is there a more efficient way to grab all UI elements instead of calling them individually?

  2. 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

ccc

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!!

ccc

https://github.com/Pythonista-Tools has a Pythonista Tic-Tac-Toe UI in the Games directory.