コード例 #1
0
    def ResizeCanvas(self, canvasSize):
        # Save position of current pieces
        currentPositions = dict()
        for coordinate, piece in State().GetChessPiecePositions().items():
            currentPositions[coordinate] = piece

        # Recalculate parameters
        Parameters().CalculateDimensionParam(canvasSize)
        self.canvas.config(width=canvasSize, height=canvasSize)
        for ChessType in Parameters().GetTypesOfChess():
            ImgProcessor().ResizeChessPieceImages(ChessType)

        # Clear all objects
        self.ClearPiecesFromBoard()
        for object in self.chessboardObjects:
            self.canvas.delete(object)

        # Call functions to draw the chess board
        if State().GetChessType() == 'Chess':
            self.DrawChessBoard()
        elif State().GetChessType() == 'XiangQi':
            self.DrawXiangQiBoard()
        else:
            logging.error('Wrong "ChessType" when calling ResizeCanvas!')
            exit(1)

        # Add pieces to board
        for coordinate, chessPiece in currentPositions.items():
            self.AddPieceToBoard(chessPiece['PlayerColor'],
                                 chessPiece['PieceType'], coordinate)
コード例 #2
0
    def BingMove(self, coordinate):
        ChessType = 'XiangQi'
        CurrentMove = self.GetCurrentMove()
        PlayerColor = CurrentMove.GetPlayerColor()
        isValidMove = False

        yCoordinateLim = (5, 9)
        direction = 1
        if PlayerColor == Parameters().GetPlayerColors(ChessType)[0]:
            yCoordinateLim = (Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[1],
                              Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[0])
            direction = -1

        if coordinate[0] == CurrentMove.GetStartPos(
        )[0] and coordinate[1] == CurrentMove.GetStartPos()[1] + direction:
            isValidMove = True
        elif coordinate[1] == CurrentMove.GetStartPos()[1] and abs(
                coordinate[0] - CurrentMove.GetStartPos()[0]
        ) == 1 and yCoordinateLim[0] <= coordinate[1] <= yCoordinateLim[1]:
            isValidMove = True

        if isValidMove:
            self.GetCurrentMove().SetEndPos(coordinate)
            return True
        return False
コード例 #3
0
    def __InitCanvasParameters(self):
        Parameters().CalculateDimensionParam()
        self.canvas.config(width=Parameters().GetCanvasSize(),
                           height=Parameters().GetCanvasSize())

        self.chessboardObjects = list()
        self.chesspiecesObjects = dict()
        self.active_square_objects = list()

        self.canvas.bind('<Button-1>', self.lmb_callback)
コード例 #4
0
        def LoadFromFile():
            filename = filedialog.askopenfilename(
                initialdir='.',
                filetypes=(('Comma Separated Values', '*.csv*'), ('all files',
                                                                  '*.*')))

            if filename != '':
                data = dict()
                file = open(filename, 'r')

                lines = file.read().split('\n')
                self.CaptionPanel.delete(0, tkinter.END)
                self.CaptionPanel.insert(0, lines[0])

                for line in lines[1:]:
                    if line:
                        x, y, piece = line.split(',')
                        data[(int(x), int(y))] = piece
                file.close()

                # Get types of chess pieces
                chess_piece_types = set()
                for chess_piece in data.values():
                    chess_piece_types.add(chess_piece.split('_')[1])

                # Find out what type of chess it is
                ChessType = 'Chess'
                for piece in chess_piece_types:
                    if ChessType == 'Chess' and piece not in Parameters(
                    ).GetTypesOfChessPieces('Chess'):
                        ChessType = 'XiangQi'

                # Change chess type if neccessary
                if ChessType != State().GetChessType():
                    self.chess_type_var.set(ChessType)
                    self.ChangeChessType(ChessType)

                # Update chess pieces
                self.ChessBoard.ClearPiecesFromBoard()
                for coordinate, piece in data.items():
                    if 0 <= coordinate[0] < Parameters().GetChessBoardXArray(
                            ChessType) and 0 <= coordinate[1] < Parameters(
                            ).GetChessBoardYArray(ChessType):
                        self.ChessBoard.AddPieceToBoard(
                            piece['PlayerColor'], piece['PieceType'],
                            coordinate)
                    else:
                        msg = 'Coordinate ' + str(
                            coordinate
                        ) + ' is out of range!\nThe piece will be ignored.'
                        messagebox.showerror('Warning', msg)
                State().ClearMoveList()
                self.ChessBoard.RemoveHighlights()
コード例 #5
0
    def AddMenu(self):
        ChessType = State().GetChessType()
        PlayerColors = Parameters().GetPlayerColors(ChessType)
        TypesOfChessPieces = Parameters().GetTypesOfChessPieces(ChessType)

        State().SetGameIsOngoing(True)
        var = tkinter.StringVar(value='deselect')

        def callback():
            if State().GetSelectedPieceToAddToBoard() != var.get():
                if var.get() != 'deselect':
                    State().ClearMoveList()
                    self.ChessBoard.RemoveHighlights()

                State().SetSelectedPieceToAddToBoard(var.get())
                if var.get() == 'deselect':
                    State().SetGameIsOngoing(True)
                else:
                    State().SetGameIsOngoing(False)

        for piece in TypesOfChessPieces:
            RadiobtnFrame = tkinter.Frame(self.frame)
            RadiobtnFrame.pack(anchor='w')
            for PlayerColor in PlayerColors:
                ChessPieceString = PlayerColor + '_' + piece
                img = ImgProcessor().GetImage(ChessType, ChessPieceString)
                LongerSide = img.size[
                    0] if img.size[0] > img.size[1] else img.size[1]
                ScalingFactor = self.__RadiobtnSize / LongerSide
                ScaledSize = (int(ScalingFactor * img.size[0]),
                              int(ScalingFactor * img.size[1]))
                img = ImageTk.PhotoImage(img.resize(ScaledSize))

                Radiobtn = tkinter.Radiobutton(RadiobtnFrame,
                                               command=callback,
                                               variable=var,
                                               value=ChessPieceString,
                                               image=img,
                                               indicatoron=0,
                                               width=self.__RadiobtnSize,
                                               height=self.__RadiobtnSize)
                Radiobtn.image = img
                Radiobtn.pack(side=tkinter.LEFT)
        tkinter.Radiobutton(self.frame,
                            command=callback,
                            variable=var,
                            value='remove',
                            text='Remove').pack(anchor='w')
        tkinter.Radiobutton(self.frame,
                            command=callback,
                            variable=var,
                            value='deselect',
                            text='Deselect').pack(anchor='w')
コード例 #6
0
    def lmb_callback(self, event):
        ChessType = State().GetChessType()
        CellSize = Parameters().GetCellSize(ChessType)
        BoardXStart, BoardXEnd = Parameters().GetBoardXLimits(ChessType)
        BoardYStart, BoardYEnd = Parameters().GetBoardYLimits(ChessType)

        # Handle events within the chessboard
        if BoardXStart < event.x < BoardXEnd and BoardYStart < event.y < BoardYEnd:
            x = int((event.x - BoardXStart) / CellSize)
            y = int((event.y - BoardYStart) / CellSize)

            # Check if x,y are allowed values
            if x < 0: x = 0
            if x >= Parameters().GetChessBoardXArray(ChessType):
                x = Parameters().GetChessBoardXArray(ChessType) - 1

            if y < 0: y = 0
            if y >= Parameters().GetChessBoardYArray(ChessType):
                y = Parameters().GetChessBoardYArray(ChessType) - 1

            coordinate = (x, y)
            if State().IsGameOngoing():
                MoveHandler().Process(coordinate)
            else:
                self.ChangePieceOnBoard(coordinate)
コード例 #7
0
 def AddPieceToBoard(self, PlayerColor, PieceType, coordinate):
     State().AddChessPieceToPosition(PlayerColor, PieceType, coordinate)
     ChessType = State().GetChessType()
     img = ImgProcessor().GetPhotoImage(ChessType,
                                        PlayerColor + '_' + PieceType)
     self.chesspiecesObjects[coordinate] = [
         self.canvas.create_image(Parameters().GetCellCenter(
             ChessType, coordinate),
                                  image=img), img
     ]
コード例 #8
0
    def DrawChessBoard(self):
        ChessType = 'Chess'
        BoardMargin = Parameters().GetBoardMargin()
        BoardSize = Parameters().GetBoardSize()
        CellSize = Parameters().GetCellSize(ChessType)
        TextMargin = Parameters().GetTextMargin(ChessType)

        # Draw black and white squares
        self.chessboardObjects.append(
            self.canvas.create_rectangle(BoardMargin,
                                         BoardMargin,
                                         BoardMargin + BoardSize,
                                         BoardMargin + BoardSize,
                                         fill='white',
                                         width=4))
        for i in range(Parameters().GetChessBoardXArray(ChessType)):
            for j in range(Parameters().GetChessBoardYArray(ChessType)):
                cell_color = 'white' if (i + j) % 2 == 0 else 'black'
                x = BoardMargin + i * CellSize
                y = BoardMargin + j * CellSize
                self.chessboardObjects.append(
                    self.canvas.create_rectangle(x,
                                                 y,
                                                 x + CellSize,
                                                 y + CellSize,
                                                 fill=cell_color,
                                                 width=0))

        # Insert alphabets and numbers for notation
        alphabets = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h')
        for i in range(Parameters().GetChessBoardXArray(ChessType)):
            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin + (i + 0.5) * CellSize,
                                        BoardMargin + BoardSize + TextMargin,
                                        text=alphabets[i],
                                        font=12))
            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin - TextMargin,
                                        BoardMargin + BoardSize -
                                        (i + 0.5) * CellSize,
                                        text=i + 1,
                                        font=12))

            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin + (i + 0.5) * CellSize,
                                        BoardMargin - TextMargin,
                                        text=alphabets[i],
                                        font=12,
                                        angle=180))
            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin + BoardSize + TextMargin,
                                        BoardMargin + BoardSize -
                                        (i + 0.5) * CellSize,
                                        text=i + 1,
                                        font=12,
                                        angle=180))
コード例 #9
0
    def ShuaiMove(self, coordinate):
        ChessType = 'XiangQi'
        CurrentMove = self.GetCurrentMove()
        PlayerColor = CurrentMove.GetPlayerColor()
        isValidMove = False

        xCoordinateLim = (3, 5)
        yCoordinateLim = (0, 2)
        if PlayerColor == Parameters().GetPlayerColors(ChessType)[0]:
            yCoordinateLim = (Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[1],
                              Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[0])
        if abs(coordinate[0] - CurrentMove.GetStartPos(
        )[0]) == 1 and coordinate[1] == CurrentMove.GetStartPos(
        )[1] and xCoordinateLim[0] <= coordinate[0] <= xCoordinateLim[1]:
            isValidMove = True
        elif abs(coordinate[1] - CurrentMove.GetStartPos(
        )[1]) == 1 and coordinate[0] == CurrentMove.GetStartPos(
        )[0] and yCoordinateLim[0] <= coordinate[1] <= yCoordinateLim[1]:
            isValidMove = True
        else:
            EnemyKing = State().GetChessPieceAtPosition(coordinate)
            if EnemyKing != None and EnemyKing[
                    'PlayerColor'] != CurrentMove.GetPlayerColor(
                    ) and EnemyKing['PieceType'] == 'shuai':
                isBlocked = False
                CheckRange = (coordinate[1], CurrentMove.GetStartPos()[1])
                CheckRange = (min(CheckRange), max(CheckRange))
                for i in range(CheckRange[0] + 1, CheckRange[1]):
                    if State().PieceExistsAtPosition((coordinate[0], i)):
                        isBlocked = True
                        break
                if not isBlocked:
                    isValidMove = True

        if isValidMove:
            self.GetCurrentMove().SetEndPos(coordinate)
            return True
        return False
コード例 #10
0
                def __init__(self):
                    root = Parameters().GetRoot()
                    self.PieceToPromoteTo = None

                    self.PromotionWindow = tkinter.Toplevel(root)
                    self.PromotionWindow.title('Promotion')

                    def callback(ChosenPiece):
                        self.PieceToPromoteTo = ChosenPiece
                        self.PromotionWindow.destroy()

                    for PieceType in Parameters().GetTypesOfChessPieces(
                            'Chess'):
                        if PieceType != 'king' and PieceType != 'pawn':
                            ImgName = color + '_' + PieceType
                            ButtonSize = Parameters().GetCellSize('Chess')
                            img = ImgProcessor().GetPhotoImage(
                                'Chess', ImgName)
                            bt = tkinter.Button(
                                self.PromotionWindow,
                                image=img,
                                command=lambda s=PieceType: callback(s),
                                width=ButtonSize,
                                height=ButtonSize)
                            bt.image = img
                            bt.pack(side=tkinter.LEFT)

                    root.wait_window(self.PromotionWindow)
コード例 #11
0
    def ShiMove(self, coordinate):
        ChessType = 'XiangQi'
        CurrentMove = self.GetCurrentMove()
        PlayerColor = CurrentMove.GetPlayerColor()
        isValidMove = False

        xCoordinateLim = (3, 5)
        yCoordinateLim = (0, 2)
        if PlayerColor == Parameters().GetPlayerColors(ChessType)[0]:
            yCoordinateLim = (Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[1],
                              Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[0])
        if (abs(coordinate[0] - CurrentMove.GetStartPos()[0]) == 1
                and abs(coordinate[1] - CurrentMove.GetStartPos()[1]) == 1
                and xCoordinateLim[0] <= coordinate[0] <= xCoordinateLim[1]
                and yCoordinateLim[0] <= coordinate[1] <= yCoordinateLim[1]):
            isValidMove = True

        if isValidMove:
            self.GetCurrentMove().SetEndPos(coordinate)
            return True
        return False
コード例 #12
0
    def XiangMove(self, coordinate):
        ChessType = 'XiangQi'
        CurrentMove = self.GetCurrentMove()
        PlayerColor = CurrentMove.GetPlayerColor()
        isValidMove = False

        yCoordinateLim = (0, 4)
        if PlayerColor == Parameters().GetPlayerColors(ChessType)[0]:
            yCoordinateLim = (Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[1],
                              Parameters().GetChessBoardYArray(ChessType) - 1 -
                              yCoordinateLim[0])
        if (abs(coordinate[0] - CurrentMove.GetStartPos()[0]) == 2
                and abs(coordinate[1] - CurrentMove.GetStartPos()[1]) == 2
                and yCoordinateLim[0] <= coordinate[1] <= yCoordinateLim[1]):
            midpoint = ((coordinate[0] + CurrentMove.GetStartPos()[0]) // 2,
                        (coordinate[1] + CurrentMove.GetStartPos()[1]) // 2)
            if State().GetChessPieceAtPosition(midpoint) == None:
                isValidMove = True

        if isValidMove:
            self.GetCurrentMove().SetEndPos(coordinate)
            return True
        return False
コード例 #13
0
 def GetPlayerColorFromYCoordinate(self, yCoordinate):
     if yCoordinate == 7:
         return Parameters().GetPlayerColors()[0]
     if yCoordinate == 0:
         return Parameters().GetPlayerColors()[1]
     return None
コード例 #14
0

def SetupLogging():
    logDirName = 'log'
    if not os.path.exists(logDirName):
        os.makedirs(logDirName)
    logging.basicConfig(
        filename=logDirName + os.path.sep + date.today().strftime('%Y%m%d') +
        '.log',
        encoding='utf-8',
        format='%(asctime)s %(levelname)-8s %(module)-30s: %(message)s',
        level=logging.INFO,
        datefmt='%Y-%m-%d %H:%M:%S',
    )


if __name__ == '__main__':
    SetupLogging()
    logging.info('Program has started')

    Parameters()
    State()
    ImgProcessor()

    root = tkinter.Tk()
    root.state('zoomed')
    Parameters().SetRoot(root)

    MainWindow = MainWindow(root)
    root.mainloop()
コード例 #15
0
    def AddHighlight(self, square):
        if square != 0:
            ChessType = State().GetChessType()
            linewidth = Parameters().GetHighlightLinewidth()
            color = Parameters().GetHighlightColor(ChessType)
            x, y = Parameters().GetCellCenter(ChessType, square)
            size = 0.5 * Parameters().GetCellSize(ChessType)
            length = 0.6 * size
            offset = 0.1 * linewidth

            # Top left corner
            self.active_square_objects.append(
                self.canvas.create_rectangle(x - size + offset,
                                             y - size + offset,
                                             x - size + length,
                                             y - size + linewidth,
                                             width=0,
                                             fill=color))
            self.active_square_objects.append(
                self.canvas.create_rectangle(x - size + offset,
                                             y - size + offset,
                                             x - size + linewidth,
                                             y - size + length,
                                             width=0,
                                             fill=color))

            # Top right corner
            self.active_square_objects.append(
                self.canvas.create_rectangle(x + size - offset,
                                             y - size + offset,
                                             x + size - length,
                                             y - size + linewidth,
                                             width=0,
                                             fill=color))
            self.active_square_objects.append(
                self.canvas.create_rectangle(x + size - offset,
                                             y - size + offset,
                                             x + size - linewidth,
                                             y - size + length,
                                             width=0,
                                             fill=color))

            # Bottom left corner
            self.active_square_objects.append(
                self.canvas.create_rectangle(x - size + offset,
                                             y + size - offset,
                                             x - size + length,
                                             y + size - linewidth,
                                             width=0,
                                             fill=color))
            self.active_square_objects.append(
                self.canvas.create_rectangle(x - size + offset,
                                             y + size - offset,
                                             x - size + linewidth,
                                             y + size - length,
                                             width=0,
                                             fill=color))

            # Bottom right corner
            self.active_square_objects.append(
                self.canvas.create_rectangle(x + size - offset,
                                             y + size - offset,
                                             x + size - length,
                                             y + size - linewidth,
                                             width=0,
                                             fill=color))
            self.active_square_objects.append(
                self.canvas.create_rectangle(x + size - offset,
                                             y + size - offset,
                                             x + size - linewidth,
                                             y + size - length,
                                             width=0,
                                             fill=color))
コード例 #16
0
    def DrawXiangQiBoard(self):
        ChessType = 'XiangQi'
        BoardMargin = Parameters().GetBoardMargin()
        BoardSize = Parameters().GetBoardSize()
        CellSize = Parameters().GetCellSize(ChessType)
        TextMargin = Parameters().GetTextMargin(ChessType)

        BoardYStart, BoardYEnd = Parameters().GetBoardYLimits(ChessType)
        linewidth = 2
        linelength = int(0.35 * CellSize)
        offset = 2 * linewidth

        # Draw horizontal lines
        for i in range(Parameters().GetChessBoardYArray(ChessType)):
            self.chessboardObjects.append(
                self.canvas.create_line(
                    BoardMargin + CellSize - 0.5 * linewidth,
                    BoardMargin + (i + 0.5) * CellSize,
                    BoardMargin - CellSize + 0.5 * linewidth + BoardSize,
                    BoardMargin + (i + 0.5) * CellSize,
                    width=linewidth))

        # Draw vertical lines
        for i in range(Parameters().GetChessBoardXArray(ChessType)):
            if i == 0 or i == Parameters().GetChessBoardXArray(ChessType) - 1:
                self.chessboardObjects.append(
                    self.canvas.create_line(BoardMargin + (i + 1) * CellSize,
                                            BoardMargin + 0.5 * CellSize,
                                            BoardMargin + (i + 1) * CellSize,
                                            BoardMargin - 0.5 * CellSize +
                                            BoardSize,
                                            width=linewidth))
            else:
                self.chessboardObjects.append(
                    self.canvas.create_line(BoardMargin + (i + 1) * CellSize,
                                            BoardMargin + 0.5 * CellSize,
                                            BoardMargin + (i + 1) * CellSize,
                                            BoardMargin - 0.5 * CellSize +
                                            0.5 * BoardSize,
                                            width=linewidth))
                self.chessboardObjects.append(
                    self.canvas.create_line(
                        BoardMargin + (i + 1) * CellSize,
                        BoardMargin + 0.5 * CellSize + 0.5 * BoardSize,
                        BoardMargin + (i + 1) * CellSize,
                        BoardMargin - 0.5 * CellSize + BoardSize,
                        width=linewidth))

        # Draw top 'X'
        self.chessboardObjects.append(
            self.canvas.create_line(BoardMargin + 0.5 * BoardSize - CellSize,
                                    BoardMargin + 0.5 * CellSize,
                                    BoardMargin + 0.5 * BoardSize + CellSize,
                                    BoardMargin + 2.5 * CellSize,
                                    width=linewidth))
        self.chessboardObjects.append(
            self.canvas.create_line(BoardMargin + 0.5 * BoardSize - CellSize,
                                    BoardMargin + 2.5 * CellSize,
                                    BoardMargin + 0.5 * BoardSize + CellSize,
                                    BoardMargin + 0.5 * CellSize,
                                    width=linewidth))

        # Draw bottom 'X'
        self.chessboardObjects.append(
            self.canvas.create_line(BoardMargin + 0.5 * BoardSize - CellSize,
                                    BoardMargin + BoardSize - 0.5 * CellSize,
                                    BoardMargin + 0.5 * BoardSize + CellSize,
                                    BoardMargin + BoardSize - 2.5 * CellSize,
                                    width=linewidth))
        self.chessboardObjects.append(
            self.canvas.create_line(BoardMargin + 0.5 * BoardSize - CellSize,
                                    BoardMargin + BoardSize - 2.5 * CellSize,
                                    BoardMargin + 0.5 * BoardSize + CellSize,
                                    BoardMargin + BoardSize - 0.5 * CellSize,
                                    width=linewidth))

        # Draw lines for 'pao' and 'bing'
        LHSCoordinates = list()
        RHSCoordinates = list()
        for i in (1, 7):
            for j in (2, 7):
                LHSCoordinates.append((i, j))
                RHSCoordinates.append((i, j))

        for j in (3, 6):
            for i in range(2, 9, 2):
                LHSCoordinates.append((i, j))
            for i in range(0, 7, 2):
                RHSCoordinates.append((i, j))

        for coordinate in LHSCoordinates:
            x, y = Parameters().GetCellCenter(ChessType, coordinate)
            self.chessboardObjects.append(
                self.canvas.create_line(x - offset,
                                        y - offset,
                                        x - linelength,
                                        y - offset,
                                        width=linewidth))
            self.chessboardObjects.append(
                self.canvas.create_line(x - offset,
                                        y - offset,
                                        x - offset,
                                        y - linelength,
                                        width=linewidth))

            self.chessboardObjects.append(
                self.canvas.create_line(x - offset,
                                        y + offset,
                                        x - linelength,
                                        y + offset,
                                        width=linewidth))
            self.chessboardObjects.append(
                self.canvas.create_line(x - offset,
                                        y + offset,
                                        x - offset,
                                        y + linelength,
                                        width=linewidth))

        for coordinate in RHSCoordinates:
            x, y = Parameters().GetCellCenter(ChessType, coordinate)
            self.chessboardObjects.append(
                self.canvas.create_line(x + offset,
                                        y - offset,
                                        x + linelength,
                                        y - offset,
                                        width=linewidth))
            self.chessboardObjects.append(
                self.canvas.create_line(x + offset,
                                        y - offset,
                                        x + offset,
                                        y - linelength,
                                        width=linewidth))

            self.chessboardObjects.append(
                self.canvas.create_line(x + offset,
                                        y + offset,
                                        x + linelength,
                                        y + offset,
                                        width=linewidth))
            self.chessboardObjects.append(
                self.canvas.create_line(x + offset,
                                        y + offset,
                                        x + offset,
                                        y + linelength,
                                        width=linewidth))

        # Add numbers
        for i in range(Parameters().GetChessBoardXArray(ChessType)):
            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin + (i + 1) * CellSize,
                                        BoardYStart - TextMargin,
                                        text=i + 1,
                                        font=12,
                                        angle=180))
            self.chessboardObjects.append(
                self.canvas.create_text(BoardMargin + BoardSize -
                                        (i + 1) * CellSize,
                                        BoardYEnd + TextMargin,
                                        text=i + 1,
                                        font=12))