3
\$\begingroup\$

I am a beginner programmer who coded a simple Tic-tac-toe in Python for practice. Any feedback, especially regarding best practices and tidying up the code, is appreciated.

import random board = {"a1": ".", "b1": ".", "c1": ".", "a2": ".", "b2": ".", "c2": ".", "a3": ".", "b3": ".", "c3": "."} #randomly assigns user to either x or o userIcon = random.choice(["x", "o"]) if userIcon == "x": computerIcon = "o" else: computerIcon = "x" def main(): print("\n\nWelcome to Tic-tac-toe!\n") print("The columns and rows are labelled with letters and numbers respectively") print("Choose your desired spot by typing in the letter followed by the number and pressing Enter") print("For example: b2[Enter]\n") print(f"You {userIcon} will be playing against the computer ({computerIcon})") #the turn variable keeps track of whose turn it is (even number is user's turn, odd number is computer's turn) if userIcon == "x": print("Your turn is first") turn = 0 else: print("Your turn is second") turn = 1 input("\nPress Enter to start!\n") printBoard() #moves are made until the game is finished while True: if turn % 2 == 0: try: user() turn += 1 printBoard() result = arbiter() if result != 0: break except: print("Invalid") continue else: computer() turn += 1 printBoard() result = arbiter() if result != 0: break if result == 1: print("User wins") elif result == 2: print("Computer wins") else: print("Draw") def printBoard(): print("\n a b c") for i in [1, 2, 3]: print(i, board[f"a{i}"], board[f"b{i}"], board[f"c{i}"], sep=" ") print("____________________________________") #lets user make their move def user(): while True: selection = input("\nChoose your spot: ") if board[selection] != ".": print("Spot taken") continue else: board[selection] = userIcon break #picks random available spot for computer def computer(): while True: row = random.choice(["1", "2", "3"]) column = random.choice(["a", "b", "c"]) if board[column + row] == ".": board[column + row] = computerIcon break #returns 1 if user wins, 2 if computer wins, 3 if draw def arbiter(): if winner(userIcon) == True: return 1 if winner(computerIcon) == True: return 2 #checks for draw for i in board: if board[i] == ".": return 0 return 3 #returns True if specified player has won, False if they have not won def winner(icon): #check rows for i in [1, 2, 3]: line = 0 for j in ["a", "b", "c"]: if board[f"{j}{i}"] == icon: line += 1 if line == 3: return True #check columns for i in ["a", "b", "c"]: line = 0 for j in [1, 2, 3]: if board[f"{i}{j}"] == icon: line += 1 if line == 3: return True #check major diagonal line = 0 for i in ["a1", "b2", "c3"]: if board[f"{i}"] == icon: line += 1 if line == 3: return True #check minor diagonal line = 0 for i in ["c1", "b2", "a3"]: if board[f"{i}"] == icon: line += 1 if line == 3: return True return False main() 
\$\endgroup\$

    1 Answer 1

    2
    \$\begingroup\$

    You could represent the board as list of nine items, initialized as

    board = ["."] * 9 

    Where, if row and col are zero-based coordinates, the respective index into board can be calculated as row * 3 + col. The indices of the board items are then placed like

    0 1 2 3 4 5 6 7 8 

    This may need some rewrite but allows to define a function

    def check_winner_seq(icon, start, step): for i in range(start, start + step * 3, step): if board[i] != icon: return False return True 

    To check a whole row, column or diagonal at once.

    Then you can rewrite winner like

    def winner(icon): # Check rows for i in range(0, 9, 3): if check_winner_seq(icon, i, 1): return True # Check cols for i in range(0, 3, 1): if check_winner_seq(icon, i, 3): return True # Check major diagonal if check_winner_seq(icon, 0, 4): return True # Check minor diagonal if check_winner_seq(icon, 2, 2): return True return False 

    With some advanced features like list comprehensions and the all and any functions, this can be written even more concise.

    \$\endgroup\$

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.