Dual Snake Battle: Implementasi Game Snake Dua Pemain dengan AI Pathfinding
Using Python to Create a Two-Player Snake Game with AI Pathfinding

Gambaran Umum
Dual Snake Battle adalah game Snake modern yang menampilkan dua ular yang dikendalikan oleh AI yang bersaing untuk mengumpulkan makanan di arena pertempuran. Game ini mengimplementasikan algoritma pathfinding canggih untuk menciptakan pengalaman bermain yang menantang dan dinamis.
import pygame
import random
import heapq
Fitur Utama
1. Dual AI System
Dua ular dengan AI independen
Kompetisi real-time untuk makanan
Sistem skor terpisah
2. Advanced Pathfinding
Menggunakan algoritma A* untuk pencarian jalur optimal
Heuristic Manhattan Distance untuk efisiensi
Penghindaran rintangan dinamis
3. Visual Modern
Grid system yang jelas
Warna berbeda untuk setiap ular
Tampilan skor real-time
Arsitektur Program
Struktur Data Utama
# Posisi snake dan makanan
snake_a = [(5, 5), (4, 5), (3, 5)] # Ular A (biru)
snake_b = [(45, 25), (46, 25), (47, 25)] # Ular B (hijau)
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
Konfigurasi Game
GRID_SIZE = 20
GRID_WIDTH = 50
GRID_HEIGHT = 30
SCREEN_WIDTH = GRID_WIDTH * GRID_SIZE
SCREEN_HEIGHT = GRID_HEIGHT * GRID_SIZE
Algoritma A* Pathfinding
Implementasi Heuristic
def heuristic(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
Algoritma A* Search
def a_star_search(start, goal, obstacles, grid_width, grid_height):
frontier = []
heapq.heappush(frontier, (0, start))
came_from = {start: None}
cost_so_far = {start: 0}
while frontier:
_, current = heapq.heappop(frontier)
if current == goal:
break
# Explore neighbors
neighbors = [
(current[0] + 1, current[1]), # Kanan
(current[0] - 1, current[1]), # Kiri
(current[0], current[1] + 1), # Bawah
(current[0], current[1] - 1) # Atas
]
for next_node in neighbors:
if (0 <= next_node[0] < grid_width and
0 <= next_node[1] < grid_height and
next_node not in obstacles):
new_cost = cost_so_far[current] + 1
if next_node not in cost_so_far or new_cost < cost_so_far[next_node]:
cost_so_far[next_node] = new_cost
priority = new_cost + heuristic(goal, next_node)
heapq.heappush(frontier, (priority, next_node))
came_from[next_node] = current
# Reconstruct path
path = []
current = goal
while current is not None:
path.append(current)
current = came_from[current]
path.reverse()
return path if len(path) > 1 else []
Mekanisme Game
1. Perhitungan Pergerakan
# Hitung path untuk setiap snake
path_a = a_star_search(snake_a[0], food_pos, obstacles, GRID_WIDTH, GRID_HEIGHT)
path_b = a_star_search(snake_b[0], food_pos, obstacles, GRID_WIDTH, GRID_HEIGHT)
# Update posisi snake
if len(path_a) > 1:
snake_a = [path_a[1]] + snake_a[:-1]
if len(path_b) > 1:
snake_b = [path_b[1]] + snake_b[:-1]
2. Sistem Makanan dan Skor
if snake_a[0] == food_pos:
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
snake_a.append(snake_a[-1]) # Tambah panjang
score_a += 10
elif snake_b[0] == food_pos:
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
snake_b.append(snake_b[-1]) # Tambah panjang
score_b += 10
3. Game Over Conditions
# Tabrak tubuh sendiri atau lawan
if snake_a[0] in snake_b or snake_a[0] in snake_a[1:]:
running = False
print("Snake A kalah!")
if snake_b[0] in snake_a or snake_b[0] in snake_b[1:]:
running = False
print("Snake B kalah!")
Cara Menjalankan Program
Prasyarat Sistem
# Pastikan Python 3.x terinstall
python --version
# Install Pygame
pip install pygame
Langkah-langkah Menjalankan
Simpan kode sebagai
dual_snake_battle.pyJalankan melalui terminal/command prompt:
python dual_snake_battle.pyGame akan terbuka di window baru
Kontrol (jika ingin ditambahkan input manual)
# Contoh tambahan kontrol keyboard (bisa ditambahkan)
keys = pygame.key.get_pressed()
if keys[pygame.K_w]: # Snake A atas
# Implementasi kontrol manual
pass
🎨 Customization Options
Mengubah Warna
SNAKE_A_COLOR = (0, 128, 255) # Biru
SNAKE_B_COLOR = (0, 255, 128) # Hijau
FOOD_COLOR = (255, 0, 0) # Merah
BACKGROUND_COLOR = (30, 30, 30) # Dark gray
Mengubah Ukuran Grid
# Untuk arena lebih kecil
GRID_WIDTH = 30
GRID_HEIGHT = 20
GRID_SIZE = 25 # Pixel per grid
Mengubah Kecepatan Game
# Di dalam game loop
clock.tick(10) # Ubah angka untuk kecepatan (5 = lambat, 20 = cepat)
Troubleshooting
Masalah Umum dan Solusi
ModuleNotFoundError: No module named 'pygame'
pip install pygameGame terlalu cepat/lambat
- Ubah nilai
clock.tick(10)di akhir game loop
- Ubah nilai
Window tidak muncul
Pastikan tidak ada error di console
Check kompatibilitas Pygame dengan Python version
Performance issues
Kurangi ukuran grid (
GRID_WIDTHdanGRID_HEIGHT)Tutup aplikasi lain yang menggunakan resource tinggi
Potensi Pengembangan
Fitur yang Bisa Ditambahkan
Multi-level System
levels = { 1: {"speed": 10, "grid_size": 20}, 2: {"speed": 15, "grid_size": 15}, 3: {"speed": 20, "grid_size": 10} }Power-ups dan Obstacles
power_ups = [ {"type": "speed_boost", "pos": (x, y), "duration": 5}, {"type": "double_points", "pos": (x, y), "duration": 10} ]Mode Permainan Lain
Time attack
Survival mode
Team battle
Keunggulan Teknis
1. Efisiensi Algoritma
Menggunakan heap untuk priority queue
Manhattan distance untuk heuristic yang cepat
Optimasi memory dengan set untuk obstacles
2. Struktur Kode yang Bersih
Fungsi-fungsi terpisah dengan tanggung jawab jelas
Konstanta untuk mudah konfigurasi
Komentar yang informatif
3. Extensibility
Mudah ditambah fitur baru
Fleksibel untuk berbagai ukuran grid
Dapat diintegrasikan dengan AI yang lebih kompleks
Full Default Program
import pygame
import random
import heapq
# Inisialisasi Pygame
pygame.init()
# Ukuran layar dan grid (Lebih luas!)
GRID_SIZE = 20
GRID_WIDTH = 50
GRID_HEIGHT = 30
SCREEN_WIDTH = GRID_WIDTH * GRID_SIZE
SCREEN_HEIGHT = GRID_HEIGHT * GRID_SIZE
# Warna
SNAKE_A_COLOR = (0, 128, 255)
SNAKE_B_COLOR = (0, 255, 128)
FOOD_COLOR = (255, 0, 0)
BACKGROUND_COLOR = (30, 30, 30)
TEXT_COLOR = (255, 255, 255)
# Setup layar dan font
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT + 40))
pygame.display.set_caption("Dual Snake Battle with Scoring")
font = pygame.font.SysFont("Arial", 24)
# Fungsi untuk menggambar grid
def draw_grid():
for x in range(0, SCREEN_WIDTH, GRID_SIZE):
pygame.draw.line(screen, (40, 40, 40), (x, 0), (x, SCREEN_HEIGHT))
for y in range(0, SCREEN_HEIGHT, GRID_SIZE):
pygame.draw.line(screen, (40, 40, 40), (0, y), (SCREEN_WIDTH, y))
# Fungsi Heuristic (Manhattan Distance)
def heuristic(a, b):
return abs(a[0] - b[0]) + abs(a[1] - b[1])
# Algoritma A* Pathfinding
def a_star_search(start, goal, obstacles, grid_width, grid_height):
frontier = []
heapq.heappush(frontier, (0, start))
came_from = {start: None}
cost_so_far = {start: 0}
while frontier:
_, current = heapq.heappop(frontier)
if current == goal:
break
neighbors = [
(current[0] + 1, current[1]),
(current[0] - 1, current[1]),
(current[0], current[1] + 1),
(current[0], current[1] - 1)
]
for next_node in neighbors:
if (0 <= next_node[0] < grid_width and
0 <= next_node[1] < grid_height and
next_node not in obstacles):
new_cost = cost_so_far[current] + 1
if next_node not in cost_so_far or new_cost < cost_so_far[next_node]:
cost_so_far[next_node] = new_cost
priority = new_cost + heuristic(goal, next_node)
heapq.heappush(frontier, (priority, next_node))
came_from[next_node] = current
path = []
current = goal
while current is not None:
path.append(current)
current = came_from[current]
path.reverse()
return path if len(path) > 1 else []
# Inisialisasi posisi snake, makanan, dan skor
snake_a = [(5, 5), (4, 5), (3, 5)]
snake_b = [(45, 25), (46, 25), (47, 25)]
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
score_a = 0
score_b = 0
# Loop utama game
running = True
clock = pygame.time.Clock()
while running:
screen.fill(BACKGROUND_COLOR)
draw_grid()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
obstacles = set(snake_a + snake_b)
path_a = a_star_search(snake_a[0], food_pos, obstacles, GRID_WIDTH, GRID_HEIGHT)
path_b = a_star_search(snake_b[0], food_pos, obstacles, GRID_WIDTH, GRID_HEIGHT)
if len(path_a) > 1:
snake_a = [path_a[1]] + snake_a[:-1]
if len(path_b) > 1:
snake_b = [path_b[1]] + snake_b[:-1]
if snake_a[0] == food_pos:
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
snake_a.append(snake_a[-1])
score_a += 10
elif snake_b[0] == food_pos:
food_pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
snake_b.append(snake_b[-1])
score_b += 10
# Game Over Logic
if snake_a[0] in snake_b or snake_a[0] in snake_a[1:]:
running = False
print("Snake A kalah!")
if snake_b[0] in snake_a or snake_b[0] in snake_b[1:]:
running = False
print("Snake B kalah!")
# Gambar snake dan makanan
for segment in snake_a:
pygame.draw.rect(screen, SNAKE_A_COLOR, (segment[0] * GRID_SIZE, segment[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE))
for segment in snake_b:
pygame.draw.rect(screen, SNAKE_B_COLOR, (segment[0] * GRID_SIZE, segment[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE))
pygame.draw.rect(screen, FOOD_COLOR, (food_pos[0] * GRID_SIZE, food_pos[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE))
# Tampilkan skor
score_text = font.render(f"Score A: {score_a} Score B: {score_b}", True, TEXT_COLOR)
screen.blit(score_text, (10, SCREEN_HEIGHT + 5))
# Update layar
pygame.display.flip()
clock.tick(10)
pygame.quit()
Kesimpulan
Dual Snake Battle menunjukkan bagaimana konsep klasik game Snake dapat dikembangkan menjadi pengalaman yang lebih kompleks dan menarik dengan menerapkan algoritma AI modern. Program ini tidak hanya menghibur tetapi juga menjadi platform yang excellent untuk mempelajari:
Algoritma Pathfinding (A* dengan berbagai heuristic)
Game Development dengan Pygame
Artificial Intelligence dalam game
Optimasi Performance untuk real-time applications
Dengan struktur kode yang terorganisir dengan baik dan algoritma yang efisien, game ini dapat dengan mudah dikembangkan lebih lanjut menjadi produk game yang lebih kompleks dan menarik.





