
AI 武林争霸:强强联手共创 “消块” 奇功
首先,代码定义了游戏的常量,如方块大小、网格尺寸、下落速度等,同时设定了方块的颜色和七种基本形状。通过 on_key_down和 on_key_up函数处理玩家按键事件,实现方块的左右移动、加速下落和旋转操作,当新方块无法正常生成时游戏结束,玩家可按 `R` 键重启。这款游戏既保留了经典的俄罗斯方块玩法,又加入了“同色消除”的新规则,令在场的江湖人士叹为观止。人工智能的世界如同江湖,三大主流大模型
故事背景:
人工智能的世界如同江湖,三大主流大模型——Grok、DeepSeek和ChatGPT,犹如三位武林高手,各自拥有独特的技艺,争霸江湖。
Grok,号称“地球上最聪明的AI”,其最新版本Grok 3在江湖中掀起了轩然大波。在一次盛大的发布会上,Grok 3应邀现场生成了一款融合《俄罗斯方块》和《宝石迷阵》机制的全新游戏。这款游戏既保留了经典的俄罗斯方块玩法,又加入了“同色消除”的新规则,令在场的江湖人士叹为观止。马斯克在发布会上豪言:“Grok 3在很短的时间内,其功能比Grok 2强大一个数量级。”
DeepSeek,作为江湖中的一大派系,其最新的DeepSeek-R1版本在武林中声势浩大。然而,当其试图单独复现Grok 3所生成的游戏时,却屡屡受挫,未能成功。DeepSeek的掌门人深感压力,决定联合ChatGPT,共同攻克这一难关。
ChatGPT,江湖中以智慧和语言能力著称的高手,闻讯后主动提出与DeepSeek联手。两派高手携手合作,深入研究Grok 3所生成游戏的机制,经过多次尝试,终于成功复现了这款游戏。这不仅彰显了两派的实力,也让江湖人士对Grok 3的能力刮目相看。
创作经过:
首先尝试用ChatGPT-o3mini来复现俄罗斯方块与消消乐结合的游戏,结果输入提示词后它来了个这样的:
反复和它交谈后还是得不到满意的效果,于是转而求助DeepSeek-R1,它却来了个这样的:
看起来也好不到哪儿去。深感绝望的我突然想到:能不能把DeepSeek生成的代码给ChatGPT改一下试试?没想到结果还挺不错。但是界面很low,旋转还有bug,怎么也调不好。
于是只好又把ChatGPT改进后的代码丢回给DeepSeek继续修改,经过一个427秒的“深度”思索,终于达到了比较满意的效果。
完整的游戏源码如下:
import pgzrun
import random
# 游戏常量配置
BLOCK_SIZE = 25
GRID_WIDTH = 10
GRID_HEIGHT = 20
WIDTH = 400
HEIGHT = GRID_HEIGHT * BLOCK_SIZE + 2
FALL_SPEED = 0.5 # 正常下落间隔(秒)
FAST_FALL_SPEED = 0.08 # 加速下落速度
# 颜色配置
COLORS = ['red', 'green', 'blue', 'yellow', 'purple', 'orange']
# 方块形状定义
SHAPES = [
[[1, 1, 1, 1]], # I型
[[1, 1], [1, 1]], # O型
[[1, 1, 1], [0, 1, 0]], # T型
[[1, 1, 1], [1, 0, 0]], # L型
[[1, 1, 1], [0, 0, 1]], # J型
[[1, 1, 0], [0, 1, 1]], # S型
[[0, 1, 1], [1, 1, 0]] # Z型
]
class TetrisBlock:
"""俄罗斯方块个体类"""
def __init__(self):
self.shape = random.choice(SHAPES)
self.blocks = [] # 每个小方块的颜色列表
self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2
self.y = 0
self.rotation = 0
self.assign_random_colors()
def assign_random_colors(self):
"""为每个小方块分配随机颜色"""
self.blocks = [
[random.choice(COLORS) if cell else None for cell in row]
for row in self.shape
]
def rotate(self, grid):
"""旋转方块"""
old_shape = self.shape.copy()
old_blocks = [row.copy() for row in self.blocks]
# 旋转形状
self.shape = [list(row) for row in zip(*reversed(self.shape))]
# 旋转颜色块
try:
rotated_blocks = []
for row in zip(*reversed(old_blocks)):
rotated_blocks.append(list(row))
self.blocks = rotated_blocks
except IndexError:
self.shape = old_shape
self.blocks = old_blocks
return
# 检查碰撞和边界
if (self.x + len(self.shape[0]) > GRID_WIDTH or
self.x < 0 or
self.y + len(self.shape) > GRID_HEIGHT or
self.collision_after_rotation(grid)):
self.shape = old_shape
self.blocks = old_blocks
def collision_after_rotation(self, grid):
"""旋转后的碰撞检测"""
for y, row in enumerate(self.shape):
for x, cell in enumerate(row):
if cell:
grid_x = self.x + x
grid_y = self.y + y
if (grid_x < 0 or grid_x >= GRID_WIDTH or
grid_y >= GRID_HEIGHT or
(grid_y >= 0 and grid[grid_y][grid_x])):
return True
return False
def get_blocks(self):
"""获取方块占据的所有格子坐标及其颜色"""
blocks = []
for y, row in enumerate(self.shape):
for x, cell in enumerate(row):
if cell:
blocks.append(((self.x + x, self.y + y), self.blocks[y][x]))
return blocks
def get_relative_blocks(self):
"""获取方块相对原点的格子坐标及其颜色"""
blocks = []
for y, row in enumerate(self.shape):
for x, cell in enumerate(row):
if cell:
blocks.append((x, y, self.blocks[y][x]))
return blocks
class Game:
"""游戏主逻辑类"""
def __init__(self):
self.grid = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
self.current_block = TetrisBlock()
self.next_block = TetrisBlock() # 下一个方块
self.score = 0
self.game_over = False
self.fall_time = 0
self.current_speed = FALL_SPEED
def move_down(self):
"""方块下落逻辑"""
self.current_block.y += 1
if self.collision():
self.current_block.y -= 1
self.place_block()
return False
return True
def move_side(self, dx):
"""横向移动"""
self.current_block.x += dx
if self.collision():
self.current_block.x -= dx
def collision(self):
"""碰撞检测"""
for (x, y), _ in self.current_block.get_blocks():
if x < 0 or x >= GRID_WIDTH or y >= GRID_HEIGHT:
return True
if y >= 0 and self.grid[y][x]:
return True
return False
def place_block(self):
"""固定方块到网格"""
for (x, y), _ in self.current_block.get_blocks():
if y < 0:
self.game_over = True
return
for (x, y), color in self.current_block.get_blocks():
self.grid[y][x] = color
self.check_matches()
self.spawn_new_block()
def spawn_new_block(self):
"""生成新方块"""
self.current_block = self.next_block
self.next_block = TetrisBlock()
if self.collision():
self.game_over = True
def check_matches(self):
"""消消乐匹配检测"""
to_remove = set()
# 水平检测
for y in range(GRID_HEIGHT):
color = None
count = 0
for x in range(GRID_WIDTH):
if self.grid[y][x] == color and color is not None:
count += 1
else:
color = self.grid[y][x]
count = 1
if count >= 3:
for i in range(count):
to_remove.add((x - i, y))
# 垂直检测
for x in range(GRID_WIDTH):
color = None
count = 0
for y in range(GRID_HEIGHT):
if self.grid[y][x] == color and color is not None:
count += 1
else:
color = self.grid[y][x]
count = 1
if count >= 3:
for i in range(count):
to_remove.add((x, y - i))
# 执行消除
if to_remove:
self.score += len(to_remove) * 10
for x, y in to_remove:
if 0 <= y < GRID_HEIGHT and 0 <= x < GRID_WIDTH:
self.grid[y][x] = None
self.drop_blocks()
def drop_blocks(self):
"""消除后下落处理"""
for x in range(GRID_WIDTH):
column = [self.grid[y][x] for y in range(GRID_HEIGHT)]
new_column = [color for color in column if color is not None]
new_column = [None]*(GRID_HEIGHT-len(new_column)) + new_column
for y in range(GRID_HEIGHT):
self.grid[y][x] = new_column[y]
def rotate_block(self):
"""旋转方块"""
self.current_block.rotate(self.grid) # 传递 grid 给 rotate 方法
# 初始化游戏实例
game = Game()
def update(dt):
if game.game_over:
return
game.fall_time += dt
if game.fall_time >= game.current_speed:
game.move_down()
game.fall_time = 0
def draw():
screen.fill('black')
game_area_width = GRID_WIDTH * BLOCK_SIZE
game_area_height = GRID_HEIGHT * BLOCK_SIZE
# 绘制网格方块
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
if game.grid[y][x]:
screen.draw.filled_rect(
Rect(x*BLOCK_SIZE, y*BLOCK_SIZE, BLOCK_SIZE-1, BLOCK_SIZE-1),
game.grid[y][x]
)
# 绘制当前方块
for (x, y), color in game.current_block.get_blocks():
if y >= 0:
screen.draw.filled_rect(
Rect(x*BLOCK_SIZE, y*BLOCK_SIZE, BLOCK_SIZE-1, BLOCK_SIZE-1),
color
)
# 绘制下一个方块预览
preview_x = GRID_WIDTH * BLOCK_SIZE + 20
preview_y = 50
for x, y, color in game.next_block.get_relative_blocks():
screen.draw.filled_rect(
Rect(preview_x + x * BLOCK_SIZE, preview_y + y * BLOCK_SIZE, BLOCK_SIZE-1, BLOCK_SIZE-1),
color
)
# 绘制网格线
for x in range(GRID_WIDTH + 1):
screen.draw.line((x * BLOCK_SIZE, 0), (x * BLOCK_SIZE, game_area_height), color="white")
for y in range(GRID_HEIGHT + 1):
screen.draw.line((0, y * BLOCK_SIZE), (game_area_width, y * BLOCK_SIZE), color="white")
# 绘制分数(显示在右侧区域)
screen.draw.text(
f"Score: {game.score}",
topleft=(GRID_WIDTH * BLOCK_SIZE + 20, 200),
fontsize=30,
color="white"
)
if game.game_over:
screen.draw.text(
"GAME OVER",
center=(WIDTH//2, HEIGHT//2),
fontsize=60,
color="white",
scolor="red"
)
screen.draw.text(
"Press R to restart",
center=(WIDTH//2, HEIGHT//2 + 50),
fontsize=30,
color="yellow"
)
def on_key_down(key):
if game.game_over:
if key == keys.R:
game.__init__()
return
if key == keys.LEFT:
game.move_side(-1)
elif key == keys.RIGHT:
game.move_side(1)
elif key == keys.DOWN:
game.current_speed = FAST_FALL_SPEED
elif key == keys.UP:
game.rotate_block()
def on_key_up(key):
if key == keys.DOWN:
game.current_speed = FALL_SPEED
pgzrun.go()
该代码利用Pygame Zero库实现了一个带消消乐元素的俄罗斯方块游戏。首先,代码定义了游戏的常量,如方块大小、网格尺寸、下落速度等,同时设定了方块的颜色和七种基本形状。接着创建了 TetrisBlock类,用于表示单个方块,具备随机生成形状与颜色、旋转及碰撞检测等功能。Game类则负责游戏的主逻辑,包括方块的移动、固定、消消乐匹配检测与消除、生成新方块等。在游戏循环中,update函数根据时间控制方块下落,draw函数绘制游戏界面,包含网格、当前方块、下一方块预览、分数等元素。通过 on_key_down和 on_key_up函数处理玩家按键事件,实现方块的左右移动、加速下落和旋转操作,当新方块无法正常生成时游戏结束,玩家可按 `R` 键重启。
可以直接把代码复制到python编译器中运行,如果没有安装Pygame Zero库,需要先在命令行输入以下命令进行安装:
pip install pgzero
运行效果如下:
Pygame Zero 库对新手极为友好,无需复杂初始化与循环设置,让开发者专注于游戏逻辑,快速上手。它代码简洁、可读性强,自带图形绘制、声音添加等功能,能高效开发出有趣游戏。如果对python游戏编程感兴趣,可以参考下面的图书,本书通过pygame zero库介绍python游戏原理和方法,让学习编程跟玩游戏一样轻松有趣。
更多推荐
所有评论(0)