2

I have made a tic/tac/toe game but I want to create a computer player that controls "O" while the user controls "X".

For the clicked function in my code, I am trying to return a boolean but I am not sure if I am doing it right. The function returns True if the user's click operations were successful. If the user clicks on a position that is already outside of the board area, the move is invalid and the function should then return False. My code:

import turtle
import time
import random 

pieces = ["_", "_", "_", "_", "_", "_", "_", "_", "_"]
turn = "X"
def drawgame(brd):
    # draw board
    turtle.setup(600, 600)
    turtle.bgcolor("silver")
    turtle.color("white")
    turtle.hideturtle()
    turtle.speed('fastest')
    turtle.width(10)
    turtle.up()

    # Horizontal bars
    turtle.goto(-300, 100)
    turtle.down()
    turtle.forward(600)
    turtle.up()
    turtle.goto(-300, -100)
    turtle.down()
    turtle.forward(600)
    turtle.up()

    # Vertical bars
    turtle.goto(-100, 300)
    turtle.setheading(-90)
    turtle.down()
    turtle.forward(600)
    turtle.up()
    turtle.goto(100, 300)
    turtle.down()
    turtle.forward(600)
    turtle.up()
    turtle.color("blue")
    x, y = -300, 300
    for pos in pieces:
        if pos == "X":
            # Draw X
            turtle.up()
            turtle.goto(x + 20, y - 20)
            turtle.setheading(-45)
            turtle.down()
            turtle.forward(226)
            turtle.up()
            turtle.goto(x + 180, y - 20)
            turtle.setheading(-135)
            turtle.down()
            turtle.forward(226)
            turtle.up()

        elif pos == "O":
            #Draw O
            turtle.up()
            turtle.goto(x + 100, y - 180)
            turtle.setheading(0)
            turtle.down()
            turtle.circle(80)
            turtle.up()
        x += 200
        if x > 100:
            x = -300
            y -= 200


def clicked(board, x, y):
    #sig: list(str), int, int -> NoneType
    global turn, pieces
    turtle.onscreenclick(None)  # disabling handler when inside handler
    column = (x + 300) // 200
    row = (y - 300) // -200
    square = int(row * 3 + column)
    print("User clicked ", x, ",", y, " at square ", square)

    if pieces[square] == "_":
        pieces[square] = turn
        if turn == "X":
            turn = "O"
        else:
            turn = "X"
        drawgame(pieces)
    else:
        print("That square is already taken")
    turtle.onscreenclick(clicked)

def computer_AI(board):
    #sig: list(str) -> NoneType

def gameover(board):
    #sig: list(str) -> bool
    #checks gameover on board if there is a three in a row pattern or not

def handler(x, y):
    #sig: int, int -> NoneType
    if clicked(the_board, x, y):
        drawgame(the_board)
        if not gameover(pieces):
            computer_AI(pieces)
            drawgame(pieces)
            gameover(pieces)


def main():
    #Runs the game 
    turtle.tracer(0,0)
    turtle.hideturtle()
    turtle.onscreenclick(handler)
    drawgame(pieces)
    turtle.mainloop()

main()


I am trying to achieve this output: enter image description here

Any help is appreciated.

cdlane
  • 40,441
  • 5
  • 32
  • 81
Angel Baby
  • 137
  • 1
  • 9

1 Answers1

2

For my clicked function in my code, I am trying to return a bool but I am not sure if I am doing it right.

The clicked() function is an event hander, it doesn't return anything to anyone. We have to design based on that. I've reworked your code below, combining the hander() and clicked() functions, such that it now "plays". That is, the user goes first, and is "X", and then the computer responds as player "O":

import turtle
import random

board = ["_", "_", "_", "_", "_", "_", "_", "_", "_"]

def drawgame(board):
    # draw board
    turtle.setup(600, 600)
    turtle.bgcolor("silver")
    turtle.color("white")
    turtle.hideturtle()
    turtle.speed('fastest')
    turtle.width(10)
    turtle.up()

    # Horizontal bars
    turtle.goto(-300, 100)
    turtle.down()
    turtle.forward(600)
    turtle.up()
    turtle.goto(-300, -100)
    turtle.down()
    turtle.forward(600)
    turtle.up()

    # Vertical bars
    turtle.setheading(-90)
    turtle.goto(-100, 300)
    turtle.down()
    turtle.forward(600)
    turtle.up()
    turtle.goto(100, 300)
    turtle.down()
    turtle.forward(600)
    turtle.up()

    turtle.color("blue")
    x, y = -300, 300

    for pos in board:
        if pos == "X":
            # Draw X
            turtle.up()
            turtle.goto(x + 20, y - 20)
            turtle.setheading(-45)
            turtle.down()
            turtle.forward(226)
            turtle.up()
            turtle.goto(x + 180, y - 20)
            turtle.setheading(-135)
            turtle.down()
            turtle.forward(226)
            turtle.up()
        elif pos == "O":
            # Draw O
            turtle.up()
            turtle.goto(x + 100, y - 180)
            turtle.setheading(0)
            turtle.down()
            turtle.circle(80)
            turtle.up()

        x += 200
        if x > 100:
            x = -300
            y -= 200

def handler(x, y):
    # sig: list(str), int, int -> NoneType

    turtle.onscreenclick(None)  # disabling handler when inside handler

    column = (x + 300) // 200
    row = (y - 300) // -200
    square = int(row * 3 + column)

    if board[square] == "_":
        board[square] = "X"
        drawgame(board)
        if not gameover(board):
            computer_AI(board)
            drawgame(board)

            if not gameover(board):
                turtle.onscreenclick(handler)  # allow player to take a turn
    else:
        print("That square is already taken!")
        turtle.onscreenclick(handler)  # allow player to retake turn

def computer_AI(board): # sig: list(str) -> NoneType

    """ stupid robot player, just picks randomly from what's available """

    available = [index for index, character in enumerate(board) if character == "_"]

    if available:
        index = random.choice(available)
        board[index] = "O"

def gameover(board):
    # sig: list(str) -> bool
    # checks game over on board if there is a three in a row pattern or not

    pass  # to be implemented!

    return False

def main():
    # Runs the game
    turtle.hideturtle()
    turtle.onscreenclick(handler)
    drawgame(board)
    turtle.mainloop()

main()

To do: the logic to determine if the game is over, and who won, still doesn't exist, so you need to write that. Currently it just returns False to indicate the game isn't over. The computer_AI() code has no smarts at all, it simply notes all the open squares and picks one at random. You need to improve on this.

cdlane
  • 40,441
  • 5
  • 32
  • 81