2D game assignment: Python image processing -- character puzzle

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

Keywords: Programming Python Attribute

Added by egpis on Sat, 21 Mar 2020 12:58:00 +0200