В настоящее время я работаю над проектом (для развлечения), который состоит из создания полностью играбельной шахматной игры! Я попытался сделать «структуру» в своем проекте и разделил все свои классы по разным файлам ... У меня также есть файл luncher.py
, который вам нужно запустить, чтобы запустить игру. Но при его выполнении появляется ошибка:
Traceback (most recent call last):
File "d:/Paul/Document/Python/Projet Echecs/luncher.py", line 12, in <module>
from classes.ChessBoard import *
File "d:\Paul\Document\Python\Projet Echecs\classes\ChessBoard.py", line 4, in <module>
from classes.Pieces import *
File "d:\Paul\Document\Python\Projet Echecs\classes\Pieces.py", line 15, in <module>
class Pieces(ChessBoard):
NameError: name 'ChessBoard' is not defined
Вот структура проекта:
- Папка проекта:
- Классы папок:
- ChessBoard.py
- Pieces.py
- Rook.py
- Папка img: со всеми изображениями
- luncher.py (корневой файл)
- Классы папок:
Вот код каждого файла:
luncher.py
:
'''Ce fichier est le fichier root du projet!
C'est lui qu'i faut executer pour le lancer!
'''
#On importe les modules necessaires
from tkinter import *
from classes.ChessBoard import *
#On creer un fenetre, puis l'échiquier (On appelle la classe ChessBoard)
fenetre = Tk()
fenetre.title("Echecs")
test = ChessBoard(fenetre, 650, 650)
fenetre.mainloop()
ChessBoard.py
:
# On importe tous les modules necessaire au bon fonctionnement de la classe
from tkinter import *
from classes.Pieces import *
import os
# Creation de la classe
class ChessBoard:
# On initialise l'objet
def __init__(self, window, height=650, width=650, color="#546760", wdCase=76):
'''
Parametre obligatoire: - une fenetre TKinter
Parametres facultatifs: -hauteur de la fenetre
- largeur de la fenetre
- couleur des cases
- largeur des cases
'''
self.height = height
self.width = width
self.backgroundColor = color
self.wdCase = wdCase
self.window = window
self.game = self.getGame()
self.rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
self.columns = ["A","B","C","D","E","F","G","H"]
# On creer le plateau
self.board = Canvas(self.window, height=self.height, width=self.width)
self.board.pack()
self.case = [[self.board.create_rectangle(i * self.wdCase, j * self.wdCase, (i+1) * self.wdCase, (j+1) * self.wdCase,fill = "#F3F3F3")for i in range(8)] for j in range(8)]
self.board.create_line(2, 2, 2, self.wdCase * 8)
self.board.create_line(2, 2, self.wdCase * 8, 2)
# On implemente les couleurs des cases qui peuvent etre modifiées en passant color=.... en parametre
for i in range(0,8,2):
for j in range(1,9,2):
self.board.itemconfigure(self.case[i][j],fill=self.backgroundColor)
self.board.itemconfigure(self.case[j][i],fill=self.backgroundColor)
# On implemente les labels de lignes et de colonnes : A-F et de 1-8
# On créer une variable locale pour les coordonnées des lettres et des chiffres a place dans le Canvas
textPositionX = self.wdCase / 2
textPositionY = self.wdCase / 2
a = (self.wdCase) * 8 + (self.wdCase / 4)
for i in range(8):
self.board.create_text(textPositionX, a, text=self.columns[i])
self.board.create_text(a, textPositionY, text=self.rows[-i - 1])
textPositionX += self.wdCase
textPositionY += self.wdCase
# On peut maintenant générer les pieces
test = Rook(303, 532, "Noir")
def getGame(self):
"""
Cette méthode de la classe ChessBoard permet de récuperer une partie en cours si il en existe
une et dans le cas contraire créer une nouvelle partie.
Dans tous les cas, la methode renvoie un tableau décrivant la disposition des pieces sur le plateau.
"""
# On verifie si le fichier saves.txt existe
if os.path.exists("saves.txt"):
# Si il existe, on l'ouvre et on recupere les donnees
with open("save.txt") as save:
#A FINIR
pass
else:
#Sinon on creer une nouvelle partie
piece = [["."]*8]*8
piece[0] = ["TN", "CN", "FN", "DN", "RN", "FN", "CN", "TN"]
piece[1] = ["PN"]*8
piece[7] = ["TB", "CB", "FB", "DB", "RB", "FB", "CB", "TB"]
piece[6] = ["PB"]*8
return piece
Pieces.py
'''Ce module contient la classe Piece'''
# On importe les modules necessaires
from tkinter import *
from classes.ChessBoard import *
# On peu modifier la variable path pour charger les images
path = "D:\Paul\Document\Python\Projet Echecs\img\Pieces\\"
class Pieces(ChessBoard):
def __init__(self, X, Y, color):
self.color = color
self.coordinateX = X
self.coordinatY = Y
И наконец Rook.py
:
from tkinter import *
from classes.ChessBoard import *
from classes.Pieces import *
class Rook(Pieces):
def __init__(self, X, Y, color):
Pieces.__init__(self, X, Y, color)
self.img = PhotoImage(file=path + "T{}.gif".format(self.color[0].upper()))
self.board.create_image(self.coordinatX, self.coordinatY, anchor=NW, image=self.img)
1 ответ
У вас есть круговой импорт.
В ChessBoard
вы импортируете Pieces
:
from classes.Pieces import *
На этом этапе ChessBoard
в основном пусто , потому что единственная завершившаяся строка - это from tkinter import *
.
И во время импорта Pieces
вы затем импортируете этот пустой модуль ChessBoard
:
from classes.ChessBoard import *
На данный момент нет класса ChessBoard
; все, что вы импортировали, - это имена tkinter
.
Вы можете увидеть это в трассировке:
File "d:/Paul/Document/Python/Projet Echecs/luncher.py", line 12, in <module>
from classes.ChessBoard import *
ChessBoard
импортируется luncher.py
File "d:\Paul\Document\Python\Projet Echecs\classes\ChessBoard.py", line 4, in <module>
from classes.Pieces import *
Который в строке 4 импортирует Pieces
, и
File "d:\Paul\Document\Python\Projet Echecs\classes\Pieces.py", line 15, in <module>
class Pieces(ChessBoard):
Пытается использовать ChessBoard
, но этот класс определен только через несколько строк после строки 4.
Если у вас должен быть доступ к классу Pieces
в ChessBoard
, вам нужно будет переместить строку импорта ниже определения class ChessBoard
.
Однако я думаю, что ваша основная ошибка здесь состоит в том, что класс Pieces
унаследован от ChessBoard
вообще . Шахматные фигуры - это не шахматная доска! Если вам необходимо совместно использовать некоторые функции между классом ChessBoard
и классом Pieces
, выделите это в отдельный модуль, который затем будут использовать оба.
Наследование классов - это способ совместного использования функциональных возможностей там, где это имеет смысл , а также для категоризации ваших классов. Шахматная доска и фигуры на доске обычно не имеют общих функций; доска не делает ходов или, например, принадлежит тому или иному игроку.
Отсутствие наследования от класса ChessBoard
упростило бы ваши два других модуля:
'''Ce module contient la classe Piece'''
# On peu modifier la variable path pour charger les images
path = "D:\\Paul\\Document\\Python\\Projet Echecs\\img\\Pieces\\"
class Pieces:
def __init__(self, board, X, Y, color):
self.board
self.color = color
self.coordinateX = X
self.coordinatY = Y
А также
from tkinter import *
from classes.Pieces import path, Pieces
class Rook(Pieces):
def __init__(self, board, X, Y, color):
Pieces.__init__(self, board, X, Y, color)
self.img = PhotoImage(file=path + "T{}.gif".format(self.color[0].upper()))
self.board.create_image(self.coordinatX, self.coordinatY, anchor=NW, image=self.img)
Обратите внимание, что я также дал классу Pieces
аргумент board
, как вы используете его в Rook.__init__()
. Поэтому, когда вы создаете экземпляр Rook
, передайте доску с помощью:
test = Rook(self, 303, 532, "Noir")
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.