2
\$\begingroup\$

With the following code I implemented the mini-game "Tic-Tac-Toe" in Python. However, I am still a beginner in programming and I wanted to ask if someone could give me some tips on how to make the code more elegant and better. But please don't be too strict, because as already mentioned I am a beginner. So the code works but is not so nice/clean.

I would be very happy about answers.

from random import shuffle, seed
seed()

# Winning options are defined

WINNING_OPTIONS = [[0, 1, 2],[3, 4, 5],[6, 7, 8],[0, 3, 6],[1, 4, 7],[2, 5, 8],[0, 4, 8],[2, 4, 6]]

# Game board is created
board_fields = [box for box in range(1,10)]
def game_board():
    for line in 0,3,6:
        print(f"|{board_fields[line]}|{board_fields[line+1]}|{board_fields[line+2]}|")

# Start player is selected
def player_order():
    liste = ["x","o"]
    shuffle(liste)
    return liste

# Input is checked for correctness
def input_verification():
    while (user_input := "placeholder")not in board_fields:
        try:
            user_input = int(input(f"{xo} is now on the turn: "))
            if user_input not in board_fields:
                print("The input was invalid. Please try again.")
                continue
            board_fields[user_input-1] = xo
            break
        except:
            print("The input was invalid. Please try again.")
            continue

# Game process

game_end = False
occupied_boxes = 0
suggested_solution = []
sequence_player = player_order()

while not game_end:
    for xo in sequence_player:
        game_board()
        
        input_verification()
        occupied_boxes = occupied_boxes + 1

        startpos = 0
        while xo in board_fields[startpos:]:
            pos = board_fields.index(xo, startpos)
            if xo == "x":
                suggested_solution.append(pos)
            startpos = pos + 1
    
        # The winner and the loser are recognized
        
        for solution in WINNING_OPTIONS:
            if set(solution) <= set(suggested_solution):
                print(f"Great! You win, player {xo}")
                game_end = True
        if occupied_boxes == 9:
            game_board()
            print("Draw.")
            game_end = True
            break
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Hi and welcome to the forum! I have a longer post about what I often see when someone asks for improvement, you can check it out here.

What I want to focus on though, is naming, specifically methods. Methods do stuff, so their names should be action like, e.g. print_something, check_if_player_won and so on.

Specifically, let's look at two of your methods:

  • game_board prints out the board. So let's name it like that: print_game_board, or print_board if it's clear from context that the game board is meant. Props to you btw, otherwise the method is fine. Most importantly, it is short, easy to understand and only does one thing. This is very important to making code easy to comprehend, other than naming.
  • input_verification This name is a lie. The name suggests (ignoring the naming convention) that this method takes some input and verifies it in some way, and giving back whether the input is valid or not. What it should be is something akin to get_guaranteed_input or read_valid_player_input. Note here, that the name suggests nothing about how the method works, just its intent. And the intent is to get an input that is valid and guaranteed to be so.

Conclusion

Naming is important. Be precise, and name methods after their intent. This enables readers to understand what a method does without having to know how it accomplishes that.

Naming precisely is important, because if something is named one way but does something else, there suddenly is a lot of confusion as to what it actually does and what it should.

All that said though, getting the hang of properly naming things is hard, especially as a beginner. I also regularly rename my methods because I can think of a better name. Just keep trying and if you can't think of a better name, move on. Good thing: Most modern IDEs have a built in refactor to rename methods (and other stuff), which makes it really easy.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.