Tkinter Canvas портит сетку - PullRequest
1 голос
/ 27 мая 2020

Я пытаюсь создать шахматную игру, и я делаю графику с помощью библиотеки tkinter в Python. Я создал подкласс Canvas под названием chessPiece. Используя следующий код, я распространил его на сетку tkinter:

        for i in range(8):
            for j in range(8):
                if (i%2==0 and j%2==0) or (i%2==1 and j%2==1):
                    color='blanched almond'
                else:
                    color='olive drab'
                self.cells.append(chessPiece(self,color,(i,j)))
                self.cells[i*8+j].grid(row=i,column=j)

, и он отлично работает. Настоящая проблема возникает позже, когда я пытаюсь добавить 5 кнопок, 4 в новую 8-ю строку и 1 в новую 9-ю строку, используя следующий код:

        self.master.qButton = Button(text='Queen',command=self.createQueen)
        self.master.rButton = Button(text='Rook',command=self.createRook)
        self.master.bButton = Button(text='Bishop',command=self.createBishop)
        self.master.kButton = Button(text='Knight',command=self.createKnight)
        self.master.conButton = Button(text='CONFIRM PIECE',command=self.conPiece)
        self.master.qButton.grid(row=8,column=0,columnspan=2)
        self.master.rButton.grid(row=8,column=2,columnspan=2)
        self.master.bButton.grid(row=8,column=4,columnspan=2)
        self.master.kButton.grid(row=8,column=6,columnspan=2)
        self.master.conButton.grid(row=9,column=2,columnspan=4)

Вместо того, чтобы красиво умещаться под доской , первая кнопка находится по центру под доской и занимает все пространство, а остальные четыре кнопки находятся сбоку от доски, образуя какой-то 9-й столбец, в то время как я только пытаюсь создать второй столбец!

Я публикую здесь весь код. Обратите внимание, что я ввел только частичное логи c для пешек, и что я сделал так, чтобы все черные пешки были белыми. Код, с которым у меня возникают проблемы, - это функция promote(self) в классе chessPiece, когда пешка продвигается, поэтому просто возьмите фигуру с белой пешкой, чтобы быстро продвинуть ее и увидеть результат моего кода.

Полный код:

from tkinter import *
from PIL import ImageTk, Image

def cL(coord):
    return coord[0]*8+coord[1]

class chessPiece(Canvas):
    pics = {\
            'bpawn':'bPawn.png',\
            'bbish':'bBishop.png',\
            'bking':'bKing.png',\
            'brook':'bRook.png',\
            'bknit':'bKnight.png',\
            'bquen':'bQueen.png',\
            'wpawn':'wPawn.png',\
            'wbish':'wBishop.png',\
            'wking':'wKing.png',\
            'wrook':'wRook.png',\
            'wknit':'wKnight.png',\
            'wquen':'wQueen.png',\
            }
    def __init__(self,master,BG,coord):
        self.bgColor = BG
        self.coord=coord
        self.cLoc=coord[0]*8+coord[1]
        self.width=50
        self.height=50
        Canvas.__init__(self,master,width=self.width,height=self.height,bg=BG,\
                        highlightthickness=0,relief=RAISED)
        self.piece = 'none'
        self.bind("<Button-1>",self.move)

    def createPiece(self,pieceName, size=(50,50)):
        self.createImage(pieceName,size)
        self.piece = pieceName

    def createImage(self,pieceName,size):
        filename = self.pics[pieceName]
        self.im = Image.open(filename)
        self.resizePic(size)
        self.img=ImageTk.PhotoImage(self.im)
        self.pic = self.create_image(self.width/2,self.height/2,anchor=CENTER,\
                                     image=self.img)

    def resizePic(self,size):
        self.im = self.im.resize(size,Image.ANTIALIAS)

    def removePiece(self):
        self.piece = 'none'
        self.delete(self.pic)

    def move(self, misc = ''):
        if self['bg']=='lightgreen':
            self.unhighlight()
            self.master.lastCell=-1
            return 0
        if not self.master.hasHighlighted:
            self.master.cells[self.master.lastCell].unhighlight()
            self.highlight()
            self.master.lastCell=self.cLoc
        else:
            if self.master.lastCell==-1:
                return 0
            if self.master.validMove(self.master.cells[self.master.lastCell], self):
                self.master.cells[self.master.lastCell].unhighlight()
                self.highlight()
                self.createPiece(self.master.cells[self.master.lastCell].piece)
                self.master.cells[self.master.lastCell].removePiece()
                if (self.piece=='bpawn' and self.coord[0]==7) or (self.piece=='wpawn' and self.coord[0]==0):
                    self.promote()
                self.master.lastCell=self.cLoc
                self.master.toggleTurn()
            

    def highlight(self):
        self['bg']='lightgreen'
        self.master.hasHighlighted = True

    def unhighlight(self):
        self['bg']=self.bgColor
        self.master.hasHighlighted = False

    def promote(self):
        self.master.qButton = Button(text='Queen',command=self.createQueen)
        self.master.rButton = Button(text='Rook',command=self.createRook)
        self.master.bButton = Button(text='Bishop',command=self.createBishop)
        self.master.kButton = Button(text='Knight',command=self.createKnight)
        self.master.conButton = Button(text='CONFIRM PIECE',command=self.conPiece)
        self.master.qButton.grid(row=8,column=0,columnspan=2)
        self.master.rButton.grid(row=8,column=2,columnspan=2)
        self.master.bButton.grid(row=8,column=4,columnspan=2)
        self.master.kButton.grid(row=8,column=6,columnspan=2)
        self.master.conButton.grid(row=9,column=2,columnspan=4)

    def createQueen(self):
        if self.piece[0]=='w':
            self.createPiece('wquen')
        else:
            self.createPiece('bquen')

    def createRook(self):
        if self.piece[0]=='w':
            self.createPiece('wrook')
        else:
            self.createPiece('brook')

    def createBishop(self):
        if self.piece[0]=='w':
            self.createPiece('wbish')
        else:
            self.createPiece('bbish')

    def createKnight(self):
        if self.piece[0]=='w':
            self.createPiece('wknit')
        else:
            self.createPiece('bknit')

    def conPiece(self):
        if self.piece == 'bpawn' or self.piece=='wpawn':
            return 0
        self.master.qButton.grid_remove()
        self.master.rButton.grid_remove()
        self.master.bButton.grid_remove()
        self.master.kButton.grid_remove()
        self.master.conButton.grid_remove()

class chessBoard(Frame):
    def __init__(self,master):
        Frame.__init__(self,master)
        self.grid()
        self.cells=[]
        for i in range(8):
            for j in range(8):
                if (i%2==0 and j%2==0) or (i%2==1 and j%2==1):
                    color='blanched almond'
                else:
                    color='olive drab'
                self.cells.append(chessPiece(self,color,(i,j)))
                self.cells[i*8+j].grid(row=i,column=j)
        self.rowconfigure(8,minsize=8)
        self.cells[0].createPiece('brook')
        self.cells[1].createPiece('bknit')
        self.cells[2].createPiece('bbish')
        self.cells[3].createPiece('bquen')
        self.cells[4].createPiece('bking')
        self.cells[5].createPiece('bbish')
        self.cells[6].createPiece('bknit')
        self.cells[7].createPiece('brook')
        for i in range(8):
            self.cells[cL((1,i))].createPiece('wpawn')
            self.cells[cL((6,i))].createPiece('wpawn')
        self.cells[cL((7,0))].createPiece('wrook')
        self.cells[cL((7,1))].createPiece('wknit')
        self.cells[cL((7,2))].createPiece('wbish')
        self.cells[cL((7,3))].createPiece('wquen')
        self.cells[cL((7,4))].createPiece('wking')
        self.cells[cL((7,5))].createPiece('wbish')
        self.cells[cL((7,6))].createPiece('wknit')
        self.cells[cL((7,7))].createPiece('wrook')
        self.lastCell = -1
        self.turn = 0
        self.hasHighlighted = False
        

    def toggleTurn(self):
        self.turn = (self.turn+1)%2

    def validMove(self, oCell, nCell):
        if oCell.piece=='wpawn':
            return self.validMoveWP(oCell, nCell)
        elif oCell.piece=='bpawn':
            return self.validMoveBP(oCell, nCell)
        else:
            return False

    def validMoveWP(self, oCell, nCell):
        if self.turn != 0:
            return False
        if oCell.coord[1]==nCell.coord[1]:
            if oCell.coord[0]==6:
                if self.cells[cL((5,oCell.coord[1]))].piece != 'none':
                    return False
                if (nCell.coord[0]==5 or nCell.coord[0]==4):
                    return True
            elif (nCell.coord[1]==oCell.coord[1]):
                    return True
        elif abs(oCell.coord[1]-nCell.coord[1])==1 and \
             oCell.coord[0]-nCell.coord[0]==1 and \
             nCell.piece != 'none':
            return True
        return False

    def validMoveBP(self, oCell, nCell):
        if self.turn != 1:
            return False
        if oCell.coord[1]==nCell.coord[1]:
            if oCell.coord[0]==1:
                if self.cells[cL((2,oCell.coord[1]))].piece != 'none':
                    return False
                if (nCell.coord[0]==2 or nCell.coord[0]==3):
                    return True
            elif (nCell.coord[1]==oCell.coord[1]):
                    return True
        elif abs(oCell.coord[1]-nCell.coord[1])==1 and \
             oCell.coord[0]-nCell.coord[0]==-1 and \
             nCell.piece != 'none':
            return True
        return False
        
        
def play_chess():
    root = Tk()
    root.title('Chess')
    game = chessBoard(root)
    root.mainloop()
play_chess()

bBishop

bKnight

bPawn

bQueen

bRook

Вам нужно будет сохранить изображения, названные как описания изображений, которые я дал им. Например, вам нужно будет сохранить изображение черной пешки как bPawn.png.

Заранее спасибо!

...