Python Forum
Automate the boring stuff : the tic tac toe game
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Automate the boring stuff : the tic tac toe game
#1
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)
Reply
#2
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:).
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
(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?
Reply
#4
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')
Reply
#5
Ok, I asked the wrong question here. How would I know I have a win based on my tuples?
Reply
#6
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.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
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?
Reply
#8
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.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Run the code for some stuff it does not return me why Anldra12 3 2,844 Apr-19-2021, 02:01 PM
Last Post: Anldra12
  "Automate the Boring Stuff with Python" creating a path works but only for CMD promt Milos 2 2,864 Nov-28-2020, 01:08 PM
Last Post: Larz60+
  Unable to print stuff from while loop Nick1507 4 2,325 Sep-17-2020, 02:26 PM
Last Post: Nick1507
  How Do I Install Stuff for Python? CopBlaster 6 3,179 May-08-2020, 12:27 PM
Last Post: hussainmujtaba
  Learning to have Class and doing stuff with it... bako 2 1,988 Apr-29-2020, 05:07 PM
Last Post: bako
  Getting Cells from the Sheets "automate the boring stuff" Shafla 8 3,986 Sep-24-2019, 04:53 AM
Last Post: snippsat
  [split] Automate the boring stuff, inserting commas in list srikanth 1 2,106 Jul-02-2019, 02:29 PM
Last Post: metulburr
  Regex Issue from Automate the Boring Stuff book robgraves 2 2,814 Jun-16-2019, 12:41 AM
Last Post: robgraves
  Automate the boring stuff: regex not matching DJ_Qu 7 3,773 Apr-27-2019, 07:03 AM
Last Post: micseydel
  Automate the boring stuff, inserting commas in list DJ_Qu 3 4,687 Apr-21-2019, 03:52 PM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020