Help with simplifying the tie function - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Homework (https://python-forum.io/forum-9.html) +--- Thread: Help with simplifying the tie function (/thread-28004.html) |
Help with simplifying the tie function - blacklight - Jun-30-2020 Hi so for my AI class intro we had to programme a game. I made tic tac toe in python. If you look at the check_for_tie function, it looks a little bit too long and janky. Is there a way to simplify it? #creating tic tac toe # 1 create a board # 2 print the board # 3 create a function that asks the users for input. # 4 create a function that checks for a win. # global variable game = True #create a board board = [ "-", "-", "-", "-", "-", "-", "-", "-", "-", ] player_won = "none" # create a function that prints the board def print_board(): print("|" + board[0] + "|" + board[1] + "|" + board[2] + "|") print("|" + board[3] + "|" + board[4] + "|" + board[5] + "|") print("|" + board[6] + "|" + board[7] + "|" + board[8] + "|") # create the functions that ask the two users for input. You wil have an x and an o # we want it to ask for the position def player_x(): position = input("Choose your position from 1-9: ") position = int(position) - 1 board[position] = "x" # the function for player o def player_o(): position = input("Choose your position from 1-9: ") position = int(position) - 1 board[position] = "o" tie = False # check for rows def check_rows(): global game row1 = board[0] == board[1] == board[2] != "-" row2 = board[3] == board[4] == board[5] != "-" row3 = board[6] == board[7] == board[8] != "-" if row1 or row2 or row3: game = False if row1: print("You have won, player: " + board[0]) elif row2: print("You have won, player: " + board[3]) elif row3: print("You have won, player: " + board[6]) # check for diagonals def check_diagonals(): global game diag1 = board[2] == board[4] == board[6] != "-" diag2 = board[0] == board[4] == board[8] != "-" if diag1 or diag2: game = False if diag1: return print("You have won, player: " + board[2]) elif diag2: return print("You have won, player: " + board[0]) # check for columns def check_columns(): global game c1 = board[0] == board[3] == board[6] != "-" c2 = board[1] == board[4] == board[7] != "-" c3 = board[2] == board[5] == board[8] != "-" if c1 or c2 or c3: game = False if c1: return print("You have won, player: " + board[0]) if c2: return print("You have won, player: " + board[1]) if c3: return print("You have won, player: " + board[2]) # create a function where all the positions are filled in with x's or o's. So basically where everything doesn't equal "-". def check_for_tie(): global game b1 = board[0] and board[1] and board[2] and board[3] and board[4] and board[5] and board[6] and board[7] and board[8] != "-" if b1: game = False print("You have tied!") # creating the check function def check_for_winner(): check_rows() check_diagonals() check_columns() # creating the game loop # this is the game loop that makes the code run while game: print_board() player_x() check_for_winner() print_board() player_o() check_for_winner() check_for_tie() RE: Help with simplifying the tie function - mlieqo - Jul-01-2020 First off, this condition, is not doing what you think it is doing: board[0] and board[1] and board[2] and board[3] and board[4] and board[5] and board[6] and board[7] and board[8] != "-"for board[0]-> board[7] you are only checking if they are truthy values and only board[8] is checked if it's not equal "-" value, you would have to write it like this: board[0] != "-" and board[1] != "-" and board[2] != "-" and board[3] != "-" and board[4] != "-" and board[5] != "-" and board[6] != "-" and board[7] != "-" and board[8] != "-"or shorter version: if all(x != '-' for x in board): game = False print("You have tied!") RE: Help with simplifying the tie function - deanhystad - Jul-01-2020 Why are you testing for a tie? The three outcomes after an entry are: Player Wins, Continue Play, Tie. If the last entry did not win the game the state of the board is Tie or Continue Play. How can we differentiate between the two? One way is to verify that each position on the board is filled, but a simpler solution is to count the number of entries made since the start of the game. If entries < 9, the game is not over. If entries = 9 and nobody won, the game ended in a tie. I would write this game starting with : for i in range(9): else: print('You have tied!')Next I would have to decide who makes the next choice, X or O. Player X plays on even turns and Y plays on odd turns. Then I would notice that the player_x() and player_o() functions are identical except they use a different letter. I hate code, so I combine the two. Why are there so many functions for finding a win? Do I care how the player won? Is a diagonal win better than a row or column? If there is no difference between the wins, why is there more than one win function? Do you think it makes the code easier to read? You have some nice tests to check for a win, why not combine them into one function? def player_wins(mark): """Return True of player "mark" won""" # Check the rows if mark == board[0] == board[1] == board[2] or \ mark == board[3] == board[4] == board[5] or \ mark == board[6] == board[7] == board[8]: return True # Check the columns if mark == board[0] == board[3] == board[6] or \ mark == board[1] == board[4] == board[7] or \ mark == board[2] == board[5] == board[8]: return True # Check the columns if mark == board[0] == board[4] == board[8] or \ mark == board[2] == board[4] == board[6]: return True return FalseThe test for a win is complicated by empty spots using the same marker ("-"). Are you required to use this marker, or could you use something different like this: Now each spot is different, simplifying the test for a win. Plus the numbers on the board help the player make a selection.Tic-tac-toe is a simple game and it should be a simple program. Starting with your code I chopped it down to 30 lines, including a few comments. As with most programs, code reduction/optimization resulted mostly from removing what wasn't needed (do not need a test for a tie), replacing specific code with generic code (replace player_x() and player_o() with one function that does either) and doing things in the simplest way (test for win is the most complicated part of the program. Make as simple as possible. My win test got so short it no longer deserves its' own function). |