@WyzZeR

Как написать красивый и понятный код?

Мне нужен совет, как сделать код более понятным и "Красивым". Как это сделать? Пример кода внизу.

P. S. Я знаю, что код - жесть(уже писали).

import tkinter as tk
import tkinter.messagebox as tkm


def winner():
    if area[0][0]["text"] == "X" and area[0][1]["text"] == "X" and area[0][2]["text"] == "X":
        return "X"
    if area[1][0]["text"] == "X" and area[1][1]["text"] == "X" and area[1][2]["text"] == "X":
        return "X"
    if area[2][0]["text"] == "X" and area[2][1]["text"] == "X" and area[2][2]["text"] == "X":
        return "X"
    if area[0][0]["text"] == "X" and area[1][0]["text"] == "X" and area[2][0]["text"] == "X":
        return "X"
    if area[0][1]["text"] == "X" and area[1][1]["text"] == "X" and area[2][1]["text"] == "X":
        return "X"
    if area[0][2]["text"] == "X" and area[1][2]["text"] == "X" and area[2][2]["text"] == "X":
        return "X"
    if area[0][0]["text"] == "X" and area[1][1]["text"] == "X" and area[2][2]["text"] == "X":
        return "X"
    if area[0][2]["text"] == "X" and area[1][1]["text"] == "X" and area[2][0]["text"] == "X":
        return "X"
    if area[0][0]["text"] == "0" and area[0][1]["text"] == "0" and area[0][2]["text"] == "0":
        return "0"
    if area[1][0]["text"] == "0" and area[1][1]["text"] == "0" and area[1][2]["text"] == "0":
        return "0"
    if area[2][0]["text"] == "0" and area[2][1]["text"] == "0" and area[2][2]["text"] == "0":
        return "0"
    if area[0][0]["text"] == "0" and area[1][0]["text"] == "0" and area[2][0]["text"] == "0":
        return "0"
    if area[0][1]["text"] == "0" and area[1][1]["text"] == "0" and area[2][1]["text"] == "0":
        return "0"
    if area[0][2]["text"] == "0" and area[1][2]["text"] == "0" and area[2][2]["text"] == "0":
        return "0"
    if area[0][0]["text"] == "0" and area[1][1]["text"] == "0" and area[2][2]["text"] == "0":
        return "0"
    if area[0][2]["text"] == "0" and area[1][1]["text"] == "0" and area[2][0]["text"] == "0":
        return "0"
    return ""


def new_game():
    global area, turn
    turn = 1
    for x in range(3):
        for y in range(3):
            area[x][y]["text"] = ""


def push(button):
    global turn
    print(turn)
    if turn %2 == 0:
        turn_char = "0"
        tkm.showinfo(f"{turn} ход", f"Сейчас походили 0 , сейчас ходят X")
    else:
        turn_char = "X"
        tkm.showinfo(f"{turn} ход", f"Сейчас походили X , сейчас ходят 0")
    if button["text"] == "":
        button["text"] = turn_char
        turn += 1
    if winner() == "X":
        tkm.showinfo("Победа", "Победили крестики")
        new_game()
    if winner() == "0":
        tkm.showinfo("Победа", "Победили нолики")
        new_game()
    if winner() == "" and turn == 10:
        tkm.showinfo("Ничья", "Никто не победил")
        new_game()

#

window = tk.Tk()
window.title("Крестики нолики")
window.geometry("300x300")
window.resizable(False, False)

area = []
turn = 1
for x in range(3):
    area.append([])
    for y in range(3):
        button = tk.Button(window, text="", width=13, height=6)
        area[x].append(button)
        area[x][y].place(x=x * 100, y =y * 100)
        area[x][y]["command"] = lambda selected_button = button: push(selected_button)

window.mainloop()
  • Вопрос задан
  • 117 просмотров
Пригласить эксперта
Ответы на вопрос 2
snaiper04ek
@snaiper04ek
Не стреляйте в эникея, он админит как умеет
Красивый и понятный код = читаемый код.
Нагугли что такое самодокументирующийся код.

Я сам начинающий, но с чего бы я начал это распутывать:
area[0][0]["text"] - тут у тебя куча раз написано примерно одно и то же, меняется только 2 числа.
Легчайшим образом переносится в функцию:
def x_here(x,y):
    if area[x][y][text] == X:
        return True
    else:
        return False


тогда одна строка в winner() уже будет вот так выглядеть:

if x_here(0,0) and x_here(0,1) and x_here(0,2):
    return "X"


тут у тебя снова есть повторяющиеся элементы
во-первых, координаты для победы заранее известны
win_condition_topleft_to_botright = ((0,0),(0,1),(0,2))

у нас есть кортеж с кортежами. Если в этих координатах везде окажутся иксы - нужно вернуть X (победа). У этого кортежа понятное название (слева вверху к низу справа)

далее нам нужна функция которая примет это условие победы и проверит его:
def check_win_condition(first, second, third):  
    """на вход три кортежа, являющиеся координатами игрового поля"""

    if x_here(*first) and x_here(*second) and x_here(*third):
        return "X"

def winner():
    check_win_condition(*win_condition_topleft_to_botright)
    check_win_condition(*win_condition_2)
    check_win_condition(*win_condition_3)
    check_win_condition(*win_condition_4)


И... видишь повторяющиеся элементы? 4 одинаковые строки, в которых меняется только один параметр?
Ah shit, here we go again

Ты знаешь что делать. Действуй.
Ответ написан
Vindicar
@Vindicar
RTFM!
Разбей программу на две части.
1. Класс "игровое поле". Хранит и сообщает (но не показывает на экране!) текущее состояние поля игры, позволяет делать ходы, отслеживает их очерёдность и корректность, определяет завершение игры и победителя (если есть). Словом, содержит в себе собственно логику игры.
2. Класс "окно игры". Держит у себя ссылку на экземпляр класса "игровое поле", показывает его состояние, т.ч. состояние игры в целом, вызывает метод хода согласно действиям пользователя.
2,5. Основная программа. Создаёт поле, создаёт окно игры, показывает его на экране, уходит в рабочий цикл (mainloop).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы