آموزش ساخت بازی 2048 با پایتون

مقالات
یکشنبه 25 شهریور 1403
جهت مطالعه این مقاله به 10 دقیقه زمان نیاز دارید
آنچه در این مقاله خواهیم خواند:

مقدمه

بازی 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"

}


 

توابع بازی 2048

تابع init

در این تابع، شبکه بازی را به عنوان یک لیست دوبعدی از صفرها تعریف کرده و دو کاشی جدید به صورت تصادفی در شبکه قرار می‌دهیم:

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()


 

تابع 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


 

تابع can_move

این تابع بررسی می‌کند که آیا حرکتی برای انجام دادن وجود دارد یا نه:

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

این توابع برای انجام عملیات‌های مختلف روی شبکه بازی استفاده می‌شوند:

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


 

توابع move

این توابع حرکات مختلف (چپ، راست، بالا، پایین) را انجام می‌دهند:

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


 

تابع move

این تابع جهت حرکت را دریافت کرده و شبکه بازی را به روز می‌کند:

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


 

تابع draw

این تابع برای رسم شبکه بازی و کاشی‌ها بر روی صفحه نمایش استفاده می‌شود:

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 پیاده‌سازی می‌کند. با استفاده از این مقاله، می‌توانید به راحتی این بازی را بر روی سیستم خود اجرا کرده و از آن لذت ببرید. همچنین می‌توانید با افزودن ویژگی‌های جدید و بهبود کد، بازی را بهبود بخشید و تجربه بهتری از بازی ارائه دهید.