How to know who is winner in Tic Tac Toe in python using guizero How to know who is winner in Tic Tac Toe in python using guizero tkinter tkinter

How to know who is winner in Tic Tac Toe in python using guizero


Nice game. To work with the game board, I would suggest to create an internal data representation rather than working with the gui elements all the time according to common practice.

The reason is, that if you work with the gui elements everywhere, it might be slower, as it is not the ideal data representation. You could not save the data with pickle etc and you also add a strong dependency to the gui framework you use.E.g. if you later plan to convert it to a web application etc. you will have a very hard time.

So I just created a simple data representation in which I store the field in a two dimensional array.

# check_win checks if there are three markings# in one row/column or diagonallydef check_win():    # the checks array is just a trick to    # reduce the amount of code,    # you could avoid it by just adding    # one nested loop where the outer iterates     # over y and the inner over x    # one with the outer on x and the inner on y    # and then two others with just one loop    # for the diagonals    # the body of the inner loops would    # esentially look the same as for the while    # loop below    checks= [(0, 0, 1, 1), (0, 2, 1, -1)]    for i in range(3):        checks.append((i, 0, 0, 1))        checks.append((0, i, 1, 0))    won= None    for y, x, incr_y, incr_x in checks:        player= field[y][x]        found= player is not None        while found and x < 3 and y < 3:            found= (player == field[y][x])            y+= incr_y            x+= incr_x        if found:            won= player            break    return won# I also changed your clicked method a bit, so# it calles the check_win method# and also changed the signature, so# it gets the y and x coordinate of the# button which makes maintaining the# field array inside the clicked method# a bit simpler and also seems more natural# to medef clicked(y, x):    button = buttonlist[y][x] # Finds out which button was pressed    global empty, player    if button.text != empty:        pass # If button already pushed do nothing    else:        # Marks button with user's go        button.text = player        field[y][x] = player        # Switches players        if player == "X":            player = "O"        else:            player = "X"    won= check_win()    if won is not None:        print(f'Player {won} has won the game')    return# now I initialize the field array# it will contain None for an untouched# cell and X/O if taken by the corresponding# userfield= [[None] * 3 for i in range(3)]buttonlist= list()# to get the buttons to call the # clicked function with the new# signature and also maintain the# buttons in a two dimensional array# I changed the order of your loops# and the args argumentfor y in range(0, 3):    rowlist= list()    buttonlist.append(rowlist)    for x in range(3):        rowlist.append(PushButton(app, text=empty, args=(y, x), grid=[x, y+2], command=clicked))        z+=1app.display()# a plain vanilla version of check_win would look something like:def check_win():    for start in range(3):        x= start        mark= field[0][x]        for y in range(1, 3):            if field[y][x] != mark:                # the sequence is not complete                mark= None        if mark is not None:            # player who set the mark won            return mark        y= start        mark= field[y][0]        for x in range(1, 3):            if field[y][x] != mark:                # the sequence is not complete                mark= None        if mark is not None:            # player who set the mark won            return mark    mark= field[0][0]    for x in range(1, 3):        if field[y][x] != mark:            # the sequence is not complete            mark= None    if mark is not None:        # player who set the mark won        return mark    mark= field[0][3]    for x in range(1, 3):        if field[y][2-x] != mark:            # the sequence is not complete            mark= None    if mark is not None:        # player who set the mark won        return mark    return None