بازی 2048 یک بازی پازل ساده و محبوب است که توسط Gabriele Cirulli توسعه یافته است. در این مقاله، به بررسی و توضیح کد پایتون این بازی با استفاده از کتابخانه Pygame میپردازیم. این بازی شامل جابجایی کاشیها با هدف دستیابی به کاشی با ارزش 2048 از طریق ترکیب کاشیهای با ارزش یکسان است.
ابتدا، کتابخانههای مورد نیاز را وارد کرده و متغیرهای پایهای را تعریف میکنیم:
python
Copy code
import pygame
import random
import sys
pygame.init()
# constants
size = 4
width = 300
height = 300
tile_size = width // size
font = pygame.font.SysFont("arial", 40)
small_font = pygame.font.SysFont("arial", 20)
background_color = (187, 173, 160)
empty_tile_color = (205, 193, 180)
tile_colors = {
2: "red",
4: "orange",
8: "pink",
16: "purple",
32: "yellow",
64: "green",
128: "khaki",
256: "blue",
512: "lightblue",
1028: "lightpurple",
2048: "black"
}
در این تابع، شبکه بازی را به عنوان یک لیست دوبعدی از صفرها تعریف کرده و دو کاشی جدید به صورت تصادفی در شبکه قرار میدهیم:
python
Copy code
class Game2048:
def __init__(self) -> None:
self.grid = [[0] * size for _ in range(size)]
self.add_new_tile()
self.add_new_tile()
این تابع یک کاشی جدید با مقدار 2 یا 4 به صورت تصادفی در یکی از خانههای خالی قرار میدهد:
python
Copy code
def add_new_tile(self):
empty_cells = [(i, j) for i in range(size) for j in range(size) if self.grid[i][j] == 0]
i, j = random.choice(empty_cells)
self.grid[i][j] = 2 if random.random() < 0.9 else 4
این تابع بررسی میکند که آیا حرکتی برای انجام دادن وجود دارد یا نه:
python
Copy code
def can_move(self):
for i in range(size):
for j in range(size):
if self.grid[i][j] == 0 or (i < size - 1 and self.grid[i][j] == self.grid[i + 1][j]) or (j < size - 1 and self.grid[i][j] == self.grid[i][j + 1]):
return True
return False
این توابع برای انجام عملیاتهای مختلف روی شبکه بازی استفاده میشوند:
commpress: فشردهسازی ردیفها به سمت چپ
merge: ترکیب کاشیهای مشابه در هر ردیف
reverse: معکوس کردن ترتیب کاشیها در هر ردیف
transpose: تبدیل سطرها به ستونها و بالعکس
python
Copy code
def commpress(self, grid):
new_grid = [[0] * size for _ in range(size)]
for i in range(size):
pos = 0
for j in range(size):
if grid[i][j] != 0:
new_grid[i][pos] = grid[i][j]
pos += 1
return new_grid
def merge(self, grid):
for i in range(size):
for j in range(size - 1):
if grid[i][j] == grid[i][j + 1] and grid[i][j] != 0:
grid[i][j] *= 2
grid[i][j + 1] = 0
return grid
def reverse(self, grid):
new_grid = [list(reversed(row)) for row in grid]
return new_grid
def transpose(self, grid):
new_grid = [[grid[j][i] for j in range(size)] for i in range(size)]
return new_grid
این توابع حرکات مختلف (چپ، راست، بالا، پایین) را انجام میدهند:
python
Copy code
def move_left(self):
new_grid = self.commpress(self.grid)
new_grid = self.merge(new_grid)
new_grid = self.commpress(new_grid)
return new_grid
def move_right(self):
new_grid = self.reverse(self.grid)
new_grid = self.commpress(new_grid)
new_grid = self.merge(new_grid)
new_grid = self.commpress(new_grid)
new_grid = self.reverse(new_grid)
return new_grid
def move_up(self):
new_grid = self.transpose(self.grid)
new_grid = self.commpress(new_grid)
new_grid = self.merge(new_grid)
new_grid = self.commpress(new_grid)
new_grid = self.transpose(new_grid)
return new_grid
def move_down(self):
new_grid = self.transpose(self.grid)
new_grid = self.reverse(new_grid)
new_grid = self.commpress(new_grid)
new_grid = self.merge(new_grid)
new_grid = self.commpress(new_grid)
new_grid = self.reverse(new_grid)
new_grid = self.transpose(new_grid)
return new_grid
این تابع جهت حرکت را دریافت کرده و شبکه بازی را به روز میکند:
python
Copy code
def move(self, direction):
if direction == "up":
new_grid = self.move_up()
elif direction == "down":
new_grid = self.move_down()
elif direction == "left":
new_grid = self.move_left()
elif direction == "right":
new_grid = self.move_right()
else:
return False
if self.grid != new_grid:
self.grid = new_grid
self.add_new_tile()
return True
return False
python
Copy code
def draw(self, screen):
screen.fill(background_color)
for i in range(size):
for j in range(size):
value = self.grid[i][j]
tile_color = tile_colors.get(value, empty_tile_color)
pygame.draw.rect(screen, tile_color, (j * tile_size, i * tile_size, tile_size, tile_size))
if value != 0:
text_surface = font.render(str(value), True, "black")
text_rect = text_surface.get_rect(center=(j * tile_size + tile_size / 2, i * tile_size + tile_size / 2))
screen.blit(text_surface, text_rect)
pygame.display.flip()
در تابع اصلی، صفحه نمایش ایجاد شده و حلقه اصلی بازی اجرا میشود. در این حلقه، رویدادهای کاربر پردازش شده و بازی رسم میشود. همچنین پایان بازی نیز مدیریت میشود:
python
Copy code
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Poulstar 2048")
game = Game2048()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
game.move("up")
elif event.key == pygame.K_DOWN:
game.move("down")
elif event.key == pygame.K_LEFT:
game.move("left")
elif event.key == pygame.K_RIGHT:
game.move("right")
game.draw(screen)
if not game.can_move():
screen.fill(background_color)
game_over_surface = font.render("Game over", True, (255, 0, 0))
game_over_rec = game_over_surface.get_rect(center=(width / 2, height / 2))
screen.blit(game_over_surface, game_over_rec)
pygame.display.flip()
pygame.time.wait(2000)
pygame.quit()
sys.exit()
این کد یک نسخه ساده از بازی 2048 را با استفاده از پایتون و Pygame پیادهسازی میکند. با استفاده از این مقاله، میتوانید به راحتی این بازی را بر روی سیستم خود اجرا کرده و از آن لذت ببرید. همچنین میتوانید با افزودن ویژگیهای جدید و بهبود کد، بازی را بهبود بخشید و تجربه بهتری از بازی ارائه دهید.