Python Forum
Automate the boring stuff : the tic tac toe game - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Automate the boring stuff : the tic tac toe game (/thread-17706.html)



Automate the boring stuff : the tic tac toe game - DJ_Qu - Apr-21-2019

Hello,
I have a question about "a tic-tac-toe game" using dictionary in automate the boring stuff.
https://automatetheboringstuff.com/chapter5/

Instead of checking if the game has a winner by looking specifically at all rows, all columns and all diagonals, I wish to do it by iterating over keys to detect if three values were equal to each other.

for k in range (0, len(board.keys()), 3):
   #check if keys are equal here
But dictionary do not have order, is that right?
How can I rewrite method testForAWin to minimize code duplication -while still using a dictionary?


turn = 'X'



theBoard = {'top-L': ' ', 'top-M': ' ', 'top-R': ' ',
        'mid-L': ' ', 'mid-M': ' ', 'mid-R': ' ',
        'low-L': ' ', 'low-M': ' ', 'low-R': ' '}

def printBoard(board):
    print(board['top-L'] + '|' + board['top-M'] + '|' + board['top-R'])
    print('-+-+-')
    print(board['mid-L'] + '|' + board['mid-M'] + '|' + board['mid-R'])
    print('-+-+-')
    print(board['low-L'] + '|' + board['low-M'] + '|' + board['low-R'])

def testForAWin(board):
    won = False


    if((board['top-L'] == board['top-M'] == board['top-R']) and board['top-L'] != ' '):
        won = True
    elif(board['mid-L'] == board['mid-M'] == board['mid-R'] and board['mid-L'] != ' '):
        won = True
    #to be done for diagonals and columns as well, and lowest row
    return won


for i in range(9):
    printBoard(theBoard)
    print('Turn for :' + turn + ' Choose a space : ')
    move = input()

    while not theBoard[move]== ' ':
        print('Do not try to steal a place! ')
        move = input()

    theBoard[move] = turn
    won = testForAWin(theBoard)
    if won:
        print(turn + ' wins the game!')
        break
    elif turn == 'X':
        turn = '0'
    else:
        turn = 'X'
printBoard(theBoard)



RE: Automate the boring stuff : the tic tac toe game - ichabod801 - Apr-21-2019

The way I have done this in the past is to have a list or tuple of the sets of winning keys, and iterate over that:

WINS = (('top-L', 'top-M', 'top-R'), ('mid-L', 'mid-M', 'mid-R'), ...)
The you iterate over that list, either getting the tuples of keys (for win in WINS:) or getting the individual keys (for first, second, third in WINS:).


RE: Automate the boring stuff : the tic tac toe game - DJ_Qu - Apr-22-2019

(Apr-21-2019, 12:20 PM)ichabod801 Wrote: The way I have done this in the past is to have a list or tuple of the sets of winning keys, and iterate over that:

WINS = (('top-L', 'top-M', 'top-R'), ('mid-L', 'mid-M', 'mid-R'), ...)
The you iterate over that list, either getting the tuples of keys (for win in WINS:) or getting the individual keys (for first, second, third in WINS:).

Thank you so much!
But how do you iterate over tuples?


RE: Automate the boring stuff : the tic tac toe game - Yoriz - Apr-22-2019

tuples are iterated the same way lists are
WINS = (('top-L', 'top-M', 'top-R'), ('mid-L', 'mid-M', 'mid-R'))

for win in WINS:
    print(win)
Output:
('top-L', 'top-M', 'top-R') ('mid-L', 'mid-M', 'mid-R')



RE: Automate the boring stuff : the tic tac toe game - DJ_Qu - Apr-22-2019

Ok, I asked the wrong question here. How would I know I have a win based on my tuples?


RE: Automate the boring stuff : the tic tac toe game - ichabod801 - Apr-22-2019

Well, say you use for first, second, third in WINS:. The first time through the loop, first is 'top-L', second is 'top-M', and third is 'top-R'. You know how to test for a win with those three strings, right? So use that method to test first, second, and third for a win.

Before the loop over WINS, you set win_exists to False. During the loop, if at any point first, second, and third represent a win, set win_exists to True, and use a break statement to get out of the loop. That way, at the end of the loop, win_exists tells you if the current player won.


RE: Automate the boring stuff : the tic tac toe game - DJ_Qu - Apr-24-2019

Hello,
So I should iterate over the tuple and check if all strings are equal. I can do that :)
Is there any way to minimize code duplication any further?
There is 8 cases for win?
Maybe if I put the positions in a double array I could be able to check every row, every column and make some custom code for diagonal?


RE: Automate the boring stuff : the tic tac toe game - ichabod801 - Apr-24-2019

For tic-tac-toe, it is simplest just to hard code the possible wins like I showed. When I coded Connect Four, I wrote code to generate all of the possible wins for me. But I just ran that code once before the game, and saved it to keep checking each turn.