前言
利用一個簡單的演算法制作帶AI的俄羅斯方塊小游戲,讓我們愉快地開始吧~

代碼效果展示

開發工具
Python版本: 3.6.4
相關模塊:
pyqt5模塊;
以及一些Python自帶的模塊,
環境搭建
安裝Python并添加到環境變數,pip安裝需要的相關模塊即可,
原理簡介
(1)游戲制作
參見:Python制作小游戲(十一)
(2)AI原始碼實作
演算法比較簡單(就是low),基本思想就是遍歷當前可操作的俄羅斯方塊和下一個可操作的俄羅斯方塊(根據不同的策略,即選擇不同的位置和旋轉角度)下落到底部后組成的所有可能的未來場景,從這些未來場景中選擇一個最優的,其對應的當前可操作的俄羅斯方塊的行動策略即為當前解,具體的代碼實作如下:最后,如果你的時間不是很緊張,并且又想快速的提高,最重要的是不怕吃苦,建議你可以價位@762459510 ,那個真的很不錯,很多人進步都很快,需要你不怕吃苦哦!大家可以去添加上看一下~
# 簡單的AI演算法
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
未來場景優劣評定考慮的因素有:
可消除的行數;
堆積后的俄羅斯方塊內的虛洞數量;
堆積后的俄羅斯方塊內的小方塊數量;
堆積后的俄羅斯方塊的最高點;
堆積后的俄羅斯方塊的高度(每一列都有一個高度)標準差;
堆積后的俄羅斯方塊的高度一階前向差分;
堆積后的俄羅斯方塊的高度一階前向差分的標準差;
堆積后的俄羅斯方塊的最高點和最低點之差,
福利:私信回復【01】可免費獲取python入門教程視頻
代碼實作如下:
# 空位統計
hole_statistic_0 = [0] * width
hole_statistic_1 = [0] * width
# 方塊數量
num_blocks = 0
# 空位數量
num_holes = 0
# 每個x位置堆積俄羅斯方塊的最高點
roof_y = [0] * width
for y in range(height-1, -1, -1):
# 是否有空位
has_hole = False
# 是否有方塊
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
# 資料^0.7之和
num_holes = sum([i ** .7 for i in hole_statistic_1])
# 最高點
max_height = max(roof_y) - removed_lines
# roof_y做差分運算
roof_dy = [roof_y[i]-roof_y[i+1] for i in range(len(roof_y)-1)]
# 計算標準差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)
# roof_dy絕對值之和
abs_dy = sum([abs(dy) for dy in roof_dy])
# 最大值與最小值之差
max_dy = max(roof_y) - min(roof_y)
# 計算得分
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

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/305692.html
標籤:python
