1. Game introduction
A jigsaw puzzle divides a picture into several pieces and randomly scrambles them. When all the pieces are put back to their original positions, the puzzle is finished (the end of the game). This character puzzle game is composed of three lines and three columns. The blocks are arranged in random order. The player clicks around the blank blocks to exchange their positions until all the blocks return to their original positions. Jigsaw game operation interface
2. Program design ideas
The game program first divides the pictures into three rows and three columns, and numbers them in order. Dynamically generate a 3 x 3 list board to store the numbers 0-8, where each number represents a block, and the number 8 block is not displayed.
3. Procedure design steps
Python handles image cutting
Use the crop() method in PIL to crop a specified area from an image. The area is specified by using a quad whose coordinates are (left, top, right, bottom). The upper left coordinate of the coordinate system specified in PIL is (0,0)
In this game, you need to divide the picture into three columns of picture blocks. On the basis of the above, you can specify different areas to crop and save. In order to facilitate the use, split image (src, rownum, colnum, dstpath) function can be written to separate the specified src image file into rownumxcolnum number of small image blocks.
The realization of game logic
1. Define constants and load images
2. Image block (collage)
Each image block (collage) is a Square object with draw function, so this collage picture can be drawn to Canvas. The orderID attribute is the number of each image block (collage).
3. Initialize game
random.shuffle(board) can only scramble two-dimensional list by lines, so it uses one-dimensional list to realize the function of scrambling image blocks, and then generates corresponding image blocks (collages) into the board list according to the number.
4. Draw the elements of the game interface
There are also various elements in the game interface, such as black boxes,
5. Mouse event
Convert the click position to the chessboard coordinate on the puzzle board. If you click the empty position, all image blocks will not move; otherwise, check whether there are empty positions on the top, bottom, left and right of the current image block that you click in turn, and if so, move the current image block.
6. Judge win or lose
Determines whether the number of the collage is in order. If not, returns False.
7. Reset game
8. Click event for restart button
4. Code reference
from tkinter import * from tkinter.messagebox import * import random root=Tk('Jigsaw puzzle') root.title("Jigsaw puzzle") Pics= for i in range(9): filename="girl"+str(i)+'.png' Pics.append(PhotoImage(file=filename)) WIDTH=575 HEIGHT=575 IMAGE_WIDTH=WIDTH//3 IMAGE_HEIGHT=HEIGHT//3 ROWS=3 COLS=3 steps=0 board=[[0,1,2],[3,4,5],[6,7,8]] class Square: def __init__(self,orderID): self.orderID=orderID def draw(self,canvas,board_pos): img=Pics[self.orderID] canvas.create_image(board_pos,image=img) def init_board(): L=list(range(8)) L.append(None) random.shuffle(L) for i in range(ROWS): for j in range(COLS): idx=i*ROWS+j orderID=L[idx] if orderID is None: board[i][j]=None else: board[i][j]=Square(orderID) def play_game(): global steps steps=0 init_board() def drawBoard(canvas): canvas.create_polygon((0,0,WIDTH,0,WIDTH,HEIGHT,0,HEIGHT),width=1,outline='Black',fill='green') for i in range(ROWS): for j in range(COLS): if board[i][j] is not None: board[i][j].draw(canvas,(IMAGE_WIDTH*(j+0.5),IMAGE_HEIGHT*(i+0.5))) def mouseclick(pos): global steps r=int(pos.y//IMAGE_HEIGHT) c=int(pos.x//IMAGE_WIDTH) print(r,c) if r<3 and c<3: if board[r][c] is None: return else: current_square=board[r][c] if r-1>=0 and board[r-1][c] is None: board[r][c]=None board[r-1][c]=current_square steps+=1 elif c+1<=2 and board[r][c+1] is None: board[r][c]=None board[r][c+1]=current_square steps+=1 elif r+1<=2 and board[r+1][c] is None: board[r][c]=None board[r+1][c]=current_square steps+=1 elif c-1>=0 and board[r][c-1] is None: board[r][c]=None board[r][c-1]=current_square steps+=1 Label1["text"]=str(steps) cv.delete('all') drawBoard(cv) if win(): showinfo(title="Congratulations",message="You did it!") def win(): for i in range(ROWS): for j in range(COLS): if board[i][j] is not None and board[i][j].orderID!=i*ROWS+j: return False return True def callBack2(): print("Restart") play_game() cv.delete('all') drawBoard(cv) cv=Canvas(root,bg='white',width=WIDTH,height=HEIGHT) b1=Button(root,text="Restart",command=callBack2,width=20) Label1=Label(root,text="0",fg='red',width=20) Label1.pack() cv.bind('<Button-1>',mouseclick) cv.pack() b1.pack() play_game() drawBoard(cv) root.mainloop()
5. Result display