Review past

Python implements the “bunnies and Bun” game

Python implements eight-note mini-games

Preface:

In this issue we will make a jigsaw puzzle. Let’s have a good time

Here’s what it looks like:

The development tools

**Python version: **3.6.4

Related modules:

Pygame module;

And some modules that come with Python

Environment set up

Install Python and add it to the environment variables. PIP installs the required related modules.

The principle is introduced

Game Introduction:

The image was divided into M × N rectangular blocks, and the rectangular blocks at the lower right corner of the image were replaced with blank blocks, and these rectangular blocks were randomly placed into the shape of the original image. The goal of the game is to restore a randomly placed image to its original appearance by moving a non-blank block, and the move operation is only allowed to move a non-blank block to a blank block.

As shown below:

Step by step:

Step1: The initial interface of the game

If it’s a game, there has to be an initial interface, right?

OK, let’s write an initial interface for the game:

Display the game start screen.
def ShowStartInterface(screen, width, height) :
	screen.fill(cfg.BACKGROUNDCOLOR)
	tfont = pygame.font.Font(cfg.FONTPATH, width//4)
	cfont = pygame.font.Font(cfg.FONTPATH, width//20)
	title = tfont.render('Jigsaw puzzle'.True, cfg.RED)
	content1 = cfont.render('Press H or M or L to start the game'.True, cfg.BLUE)
	content2 = cfont.render('H is 5*5 mode, M is 4*4 mode, L is 3*3 mode '.True, cfg.BLUE)
	trect = title.get_rect()
	trect.midtop = (width/2, height/10)
	crect1 = content1.get_rect()
	crect1.midtop = (width/2, height/2.2)
	crect2 = content2.get_rect()
	crect2.midtop = (width/2, height/1.8)
	screen.blit(title, trect)
	screen.blit(content1, crect1)
	screen.blit(content2, crect2)
	while True:
		for event in pygame.event.get():
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
			elif event.type == pygame.KEYDOWN:
				if event.key == ord('l') :return 3
				elif event.key == ord('m') :return 4
				elif event.key == ord('h') :return 5
		pygame.display.update()
Copy the code

According to the player’s own level, can choose different difficulty puzzles.

Step2: define the move operation

The purpose of defining the move operation is to move the puzzle. It is very simple to implement:

Move the Cell to the left of the blank Cell right to the blank Cell position.
def moveR(board, blank_cell_idx, num_cols) :
	if blank_cell_idx % num_cols == 0: return blank_cell_idx
	board[blank_cell_idx-1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-1]
	return blank_cell_idx - 1


Move the Cell to the right of the blank Cell left to the blank Cell position.
def moveL(board, blank_cell_idx, num_cols) :
	if (blank_cell_idx+1) % num_cols == 0: return blank_cell_idx
	board[blank_cell_idx+1], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+1]
	return blank_cell_idx + 1


Move the Cell above the blank Cell down to the blank Cell.
def moveD(board, blank_cell_idx, num_cols) :
	if blank_cell_idx < num_cols: return blank_cell_idx
	board[blank_cell_idx-num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx-num_cols]
	return blank_cell_idx - num_cols


Move the Cell below the blank Cell up to the blank Cell.
def moveU(board, blank_cell_idx, num_rows, num_cols) :
	if blank_cell_idx >= (num_rows-1) * num_cols: return blank_cell_idx
	board[blank_cell_idx+num_cols], board[blank_cell_idx] = board[blank_cell_idx], board[blank_cell_idx+num_cols]
	return blank_cell_idx + num_cols
Copy the code

Step3: Main interface of the game

OK, with that in mind, we can start implementing the main interface of our game.

First of all, we need to scramble the puzzle, but random scramble is likely to lead to puzzle unsolvable, so we move the puzzle randomly to achieve the effect of scrambling the puzzle, which is the main reason why we define the movement operation of the puzzle first:

Get scrambled jigsaw puzzle.
def CreateBoard(num_rows, num_cols, num_cells) :
	board = []
	for i in range(num_cells): board.append(i)
	# Remove the lower right corner
	blank_cell_idx = num_cells - 1
	board[blank_cell_idx] = -1
	for i in range(cfg.NUMRANDOM):
		# 0: left, 1: right, 2: up, 3: down
		direction = random.randint(0.3)
		if direction == 0: blank_cell_idx = moveL(board, blank_cell_idx, num_cols)
		elif direction == 1: blank_cell_idx = moveR(board, blank_cell_idx, num_cols)
		elif direction == 2: blank_cell_idx = moveU(board, blank_cell_idx, num_rows, num_cols)
		elif direction == 3: blank_cell_idx = moveD(board, blank_cell_idx, num_cols)
	return board, blank_cell_idx
Copy the code

Game main interface initialization:

Finally, display refresh and event response of the main interface are realized:

while True:
		game_board, blank_cell_idx = CreateBoard(num_rows, num_cols, num_cells)
		if not isGameOver(game_board, size):
			break
	# Game main loop
	is_running = True
	while is_running:
		# -- Event capture
		for event in pygame.event.get():
			# ---- Quit the game
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
			# ---- Keyboard operation
			elif event.type == pygame.KEYDOWN:
				if event.key == pygame.K_LEFT or event.key == ord('a'):
					blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
				elif event.key == pygame.K_RIGHT or event.key == ord('d'):
					blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
				elif event.key == pygame.K_UP or event.key == ord('w'):
					blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
				elif event.key == pygame.K_DOWN or event.key == ord('s'):
					blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
			# ---- Mouse operation
			elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
				x, y = pygame.mouse.get_pos()
				x_pos = x // cell_width
				y_pos = y // cell_height
				idx = x_pos + y_pos * num_cols
				if idx == blank_cell_idx-1:
					blank_cell_idx = moveR(game_board, blank_cell_idx, num_cols)
				elif idx == blank_cell_idx+1:
					blank_cell_idx = moveL(game_board, blank_cell_idx, num_cols)
				elif idx == blank_cell_idx+num_cols:
					blank_cell_idx = moveU(game_board, blank_cell_idx, num_rows, num_cols)
				elif idx == blank_cell_idx-num_cols:
					blank_cell_idx = moveD(game_board, blank_cell_idx, num_cols)
		# -- Determine if the game is over
		if isGameOver(game_board, size):
			game_board[blank_cell_idx] = num_cells - 1
			is_running = False
		# -- Update the screen
		screen.fill(cfg.BACKGROUNDCOLOR)
		for i in range(num_cells):
			if game_board[i] == -1:
				continue
			x_pos = i // num_cols
			y_pos = i % num_cols
			rect = pygame.Rect(y_pos*cell_width, x_pos*cell_height, cell_width, cell_height)
			img_area = pygame.Rect((game_board[i]%num_cols)*cell_width, (game_board[i]//num_cols)*cell_height, cell_width, cell_height)
			screen.blit(game_img_used, rect, img_area)
		for i in range(num_cols+1):
			pygame.draw.line(screen, cfg.BLACK, (i*cell_width, 0), (i*cell_width, game_img_used_rect.height))
		for i in range(num_rows+1):
			pygame.draw.line(screen, cfg.BLACK, (0, i*cell_height), (game_img_used_rect.width, i*cell_height))
		pygame.display.update()
		clock.tick(cfg.FPS)
Copy the code

Step4: Game end interface

When the player finishes the puzzle, the game end interface needs to be displayed, similar to the initial interface, which is relatively simple to implement:

Display game end screen
def ShowEndInterface(screen, width, height) :
	screen.fill(cfg.BACKGROUNDCOLOR)
	font = pygame.font.Font(cfg.FONTPATH, width//15)
	title = font.render('congratulations! You completed the puzzle successfully! '.True, (233.150.122))
	rect = title.get_rect()
	rect.midtop = (width/2, height/2.5)
	screen.blit(title, rect)
	pygame.display.update()
	while True:
		for event in pygame.event.get():
			if (event.type == pygame.QUIT) or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
				pygame.quit()
				sys.exit()
		pygame.display.update()
Copy the code

That’s the end of this article, thanks for watching Python24 Mini-games, next article sharing skiing mini-games

To thank you readers, I’d like to share some of my recent programming favorites to give back to each and every one of you in the hope that they can help you.

Dry goods mainly include:

① Over 2000 Python ebooks (both mainstream and classic books should be available)

②Python Standard Library (Most Complete Chinese version)

③ project source code (forty or fifty interesting and classic practice projects and source code)

④Python basic introduction, crawler, Web development, big data analysis video (suitable for small white learning)

⑤ A Roadmap for Learning Python

⑥ Two days of Python crawler boot camp live access

All done~ ~ see personal profile or private letter to obtain the complete source code.