Reputation: 488
I'd like to create a Draughts' game board. At first, Everything worked fine while I was drawing squares and pawns directly on the "board" canvas. As I have to manipulate those pawns afterward, I wanted it to be more explicite by creating each square and pawn as objects. So I tried to create a Board which will contain black or white square which will contain circles (the pawns). Then everything, messed up. I don't know why. Even so it looks perfectly logical (for me).
I think it is related to the use of the pack method.
Here's the code :
from tkinter import *
class Parent(Tk):
def getRoot(self):
return(self.body)
def setTitle(self,title):
self.title(title)
def run(self):
self.mainloop()
class Drawing:
def __init__(self,root,width,height):
self.zone=Canvas(root, width=width, height=height)
def put(self,root,row,col):
self.zone.grid(root,row=row,column=col)
def getDrawing(self):
return(self.zone)
def rectangle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_rectangle(coordX1,coordY1,coordX2,coordY2,fill=color, outline="black")
def circle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_oval(coordX1,coordY1,coordX2,coordY2,fill=color,outline="black")
if __name__=="__main__":
root=Parent()
root.setTitle("Draughts")
board=Drawing(root,400,400)
size=40
logicBoard=[[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
DIMENSION=10
for i in range(DIMENSION):
for j in range(DIMENSION):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
if(not(i%2==j%2)):#if the square is black (on the board)
color="black"
else:
color="white"
case=Drawing(board.getDrawing(),40,40)
case.rectangle(coordX1,coordY1,coordX2,coordY2,color)
case.getDrawing().pack()
if(logicBoard[i][j]>0):
pawnColor="white"
elif(logicBoard[i][j]<0):
pawnColor="black"
if (not(i%2==j%2)):
pawn=Drawing(case.getDrawing(),40,40)
pawn.circle(0,0,30,30,pawnColor)
pawn.getDrawing().pack()
board.getDrawing().pack()
root.run()
Thank you !
EDIT:
This is what I get :
Upvotes: 1
Views: 1222
Reputation: 20679
The problem is that you create a new Canvas
and call pack()
on it in each iteration, instead of using the one you create at the beginning. In the end, you are using the class Drawing
to create new Drawings
. I suggest you to use only one class to represent all the board, with the methods to draw the squares and the circles.
I've changed the colors of the ovals to have a better contrast:
from tkinter import Tk, Canvas
from itertools import product
class Board(Tk):
def __init__(self, width, height, cellsize):
Tk.__init__(self)
self.cellsize = cellsize
self.canvas = Canvas(self, width=width, height=height)
self.canvas.bind("<Button-1>", self.onclick)
self.canvas.pack()
def draw_rectangle(self, x1, y1, x2, y2, color):
self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="black")
def draw_circle(self, x1, y1, x2, y2, color):
self.canvas.create_oval(x1, y1, x2, y2, fill=color, outline="black")
def onclick(self, event):
i = int(event.x / self.cellsize)
j = int(event.y / self.cellsize)
print "You clicked on cell (%s, %s)" % (i, j)
if __name__=="__main__":
size = 40
board = Board(400, 400, size)
board.title("Draughts")
logicBoard = [[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
for (i, j) in product(range(10), range(10)):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
color = "white" if i%2 == j%2 else "black"
board.draw_rectangle(coordX1, coordY1, coordX2, coordY2, color)
cell = logicBoard[i][j]
if cell != 0:
pawnColor = "red" if cell > 0 else "blue"
board.draw_circle(coordX1, coordY1, coordX2, coordY2, pawnColor)
board.mainloop()
Edit:
If you want to keep track of the clicks, it is clearer and simpler to bind a handler function to the canvas and calculate the point, instead of creating lots of canvas with their own event handler.
Upvotes: 2