preface

Using a simple algorithm to make a small game with AI Tetris, let us happily start ~

Code effect display

The development tools

Python version: 3.6.4

Related modules:

Pyqt5 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.

Introduction of the principle

(1) Game production

See also: Making a Game with Python (xi)

(2) AI source code implementation

Simpler algorithm (low), the basic idea is to iterate through the current operational tetris and the next actionable tetris (according to different strategies, that is, choose a different position and rotation Angle) after falling to the bottom of all of the possible future scenarios, from these future scenarios to choose an optimal, Its corresponding currently operable Tetris action strategy is the current solution, the specific code implementation is as follows:

# Simple AI algorithm
		for d_now in current_direction_range:
			x_now_min, x_now_max, y_now_min, y_now_max = self.inner_board.current_tetris.getRelativeBoundary(d_now)
			for x_now in range(-x_now_min, self.inner_board.width - x_now_max):
				board = self.getFinalBoardData(d_now, x_now)
				for d_next in next_direction_range:
					x_next_min, x_next_max, y_next_min, y_next_max = self.inner_board.next_tetris.getRelativeBoundary(d_next)
					distances = self.getDropDistances(board, d_next, range(-x_next_min, self.inner_board.width-x_next_max))
					for x_next in range(-x_next_min, self.inner_board.width-x_next_max):
						score = self.calcScore(copy.deepcopy(board), d_next, x_next, distances)
						if not action or action[2] < score:
							action = [d_now, x_now, score]
		return action
Copy the code

The evaluation of future scenarios takes into account the following factors: the number of lines that can be eliminated; The number of virtual holes in Tetris after stacking; The number of small cubes in Tetris after stacking; The highest point of a stacked Tetris; Standard deviation of piled Tetris height (each column has a height); Stacking tetris height first order forward difference; Standard deviation of the first order forward difference of the height of Stacked Tetris; The difference between the highest and lowest points of tetris after stacking. The code implementation is as follows:

# Vacancy statistics
		hole_statistic_0 = [0] * width
		hole_statistic_1 = [0] * width
		# Number of blocks
		num_blocks = 0
		# Number of seats
		num_holes = 0
		# Stack the highest point of Tetris at each x position
		roof_y = [0] * width
		for y in range(height-1, -1, -1) :# Is there an empty seat
			has_hole = False
			# If there are squares
			has_block = False
			for x in range(width):
				if board[x + y * width] == tetrisShape().shape_empty:
					has_hole = True
					hole_statistic_0[x] += 1
				else:
					has_block = True
					roof_y[x] = height - y
					if hole_statistic_0[x] > 0:
						hole_statistic_1[x] += hole_statistic_0[x]
						hole_statistic_0[x] = 0
					if hole_statistic_1[x] > 0:
						num_blocks += 1
			if not has_block:
				break
			if not has_hole and has_block:
				removed_lines += 1
		Sum of data ^0.7
		num_holes = sum([i ** 7. for i in hole_statistic_1])
		# a peak
		max_height = max(roof_y) - removed_lines
		# roof_y difference
		roof_dy = [roof_y[i]-roof_y[i+1] for i in range(len(roof_y)-1)]
		Standard deviation E(x^2) - E(x)^2
		if len(roof_y) <= 0:
			roof_y_std = 0
		else:
			roof_y_std = math.sqrt(sum([y**2 for y in roof_y]) / len(roof_y) - (sum(roof_y) / len(roof_y)) ** 2)
		if len(roof_dy) <= 0:
			roof_dy_std = 0
		else:
			roof_dy_std = math.sqrt(sum([dy**2 for dy in roof_dy]) / len(roof_dy) - (sum(roof_dy) / len(roof_dy)) ** 2)
		Sum of absolute values of roof_dy
		abs_dy = sum([abs(dy) for dy in roof_dy])
		# Difference between minimum and maximum
		max_dy = max(roof_y) - min(roof_y)
		# count score
		score = removed_lines * 1.8 - num_holes * 1.0 - num_blocks * 0.5 - max_height ** 1.5 * 0.02 - roof_y_std * 1e-5 - roof_dy_std * 0.01 - abs_dy * 0.2 - max_dy * 0.3
		return score
Copy the code