Gerakan Langkah Bidak Catur_Nine Dengan 2 Pilihan Formasi Bidak (2 Kuda, 1 Garuda Atau 2 Garuda, 1 Kuda) Pada Papan 9x9 Petak
GERAKAN LANGKAH BIDAK CATUR_NINE DENGAN 2 PILIHAN FORMASI BIDAK (2 KUDA, 1 GARUDA Atau 2 GARUDA, 1 KUDA) PADA PAPAN 9x9 PETAK
(Oleh: SR.Pakpahan,SST)
Kita lanjutkan game catur_nine 9x9 petak ini dengan implementasi pergerakan bidak atau penambahan fitur lain, fokus kita pada bagian utama yaitu menjalankan permainan (game loop). Selain itu, juga menambahkan mekanisme interaksi, seperti pergerakan bidak, aturan permainan, atau validasi langkah, maka ada banyak hal yang perlu dikembangkan lebih lanjut untuk perbaikan atau penyempurnaan yang bisa kita dilakukan, yaitu:
-
Optimasi Timer:
- Gunakan metode
pygame.time.set_timer()
untuk mengatur interval pengurangan waktu. - Tambahkan fungsi agar waktu berhenti saat permainan selesai.
- Gunakan metode
-
Interaksi Pemain:
- Tambahkan mekanisme klik untuk memilih dan memindahkan bidak.
- Buat fungsi untuk validasi langkah bidak sesuai aturan catur Nine 9x9.
-
AI atau Multiplayer (Opsional):
- Jika ingin bermain melawan AI, bisa menambahkan algoritma minimax atau rule-based AI.
- Jika ingin multiplayer online, bisa menggunakan
pygame.networking
atau socket programming.
-
Simpan dan Muat Permainan (Opsional):
- Tambahkan fitur untuk menyimpan dan melanjutkan permainan.
- Gunakan format JSON atau SQLite untuk menyimpan status permainan.
Perbaikan dan Pengembangan Kode
1. Perbaikan Timer pada Permainan- Gunakan pygame.time.get_ticks()
Alih-alih mengandalkan perhitungan manual, gunakan pygame.time.get_ticks() untuk mendapatkan waktu dalam milidetik sejak permainan dimulai.
- Kurangi Pembaruan Berlebihan
Pastikan timer hanya diperbarui jika ada perubahan signifikan, bukan setiap frame.
- Optimalkan Loop Timer
Gunakan interval pembaruan yang efisien, misalnya dengan pygame.time.delay(100).
Dari kode sebelumnya, ada beberapa masalah yang mungkin menyebabkan timer tidak berjalan dengan baik:
- Timer berjalan terus tanpa memperhitungkan giliran pemain.
switch_turn()
tidak memperbaruicurrent_player
secara global.update_timer()
tetap berjalan setiap frame, bahkan ketika pemain belum bergerak.
Solusi
- Gunakan
pygame.time.get_ticks()
untuk menghitung waktu dengan lebih akurat. - Pastikan timer hanya berkurang saat giliran pemain yang bersangkutan.
- Modifikasi
switch_turn()
agar memperbaruilast_time
.
Perbaikan Kode:
# === WAKTU PERMAINAN ===
WHITE_TIME = 3600 # 60 menit dalam detik
BLACK_TIME = 3600
current_player = "white"
last_time = pygame.time.get_ticks() # Gunakan get_ticks()
def update_timer():
"""Mengupdate timer berdasarkan giliran pemain"""
global WHITE_TIME, BLACK_TIME, last_time
current_time = pygame.time.get_ticks()
elapsed_time = (current_time - last_time) // 1000 # Konversi ms ke detik
if elapsed_time > 0:
if current_player == "white":
WHITE_TIME -= elapsed_time
if WHITE_TIME <= 0:
print("Waktu Habis! Hitam Menang!")
pygame.quit()
sys.exit()
else:
BLACK_TIME -= elapsed_time
if BLACK_TIME <= 0:
print("Waktu Habis! Putih Menang!")
pygame.quit()
sys.exit()
last_time = current_time # Perbarui last_time setelah mengurangi waktu
def switch_turn():
"""Beralih giliran pemain"""
global current_player, last_time
current_player = "black" if current_player == "white" else "white"
last_time = pygame.time.get_ticks() # Reset last_time saat pergantian giliran
Perubahan yang Dilakukan:
✅ Menggunakan pygame.time.get_ticks()
untuk memastikan timer tetap akurat.
Pada kode sebelumnya:
# === WAKTU PERMAINAN ===
WHITE_TIME = 3600 # 60 menit dalam detik
BLACK_TIME = 3600
current_player = "white"
last_time = time.time()
Gantikan dengan kode yang ini:
# === WAKTU PERMAINAN ===
WHITE_TIME = 3600 # 60 menit dalam detik
BLACK_TIME = 3600
current_player = "white"
last_time = pygame.time.get_ticks() # Gunakan get_ticks()
✅ Fungsi update_timer(). Timer hanya berjalan saat giliran pemain berlangsung.
Pada kode sebelumnya:
def update_timer():
"""Mengupdate timer berdasarkan giliran pemain"""
global WHITE_TIME, BLACK_TIME, last_time
current_time = time.time()
elapsed_time = current_time - last_time
last_time = current_time
if current_player == "white":
WHITE_TIME -= int(elapsed_time)
if WHITE_TIME <= 0:
print("Waktu Habis! Hitam Menang!")
pygame.quit()
sys.exit()
else:
BLACK_TIME -= int(elapsed_time)
if BLACK_TIME <= 0:
print("Waktu Habis! Putih Menang!")
pygame.quit()
sys.exit()
Gantikan dengan kode yang ini:
def update_timer():
"""Mengupdate timer berdasarkan giliran pemain"""
global WHITE_TIME, BLACK_TIME, last_time
current_time = pygame.time.get_ticks()
elapsed_time = (current_time - last_time) // 1000 # Konversi ms ke detik
if elapsed_time > 0:
if current_player == "white":
WHITE_TIME -= elapsed_time
if WHITE_TIME <= 0:
print("Waktu Habis! Hitam Menang!")
pygame.quit()
sys.exit()
else:
BLACK_TIME -= elapsed_time
if BLACK_TIME <= 0:
print("Waktu Habis! Putih Menang!")
pygame.quit()
sys.exit()
last_time = current_time # Perbarui last_time setelah mengurangi waktu
✅ switch_turn()
memperbarui last_time
agar timer tidak langsung berkurang drastis.
Pada kode sebelumnya:
# === FUNGSI GILIRAN ===
def switch_turn():
"""Mengubah giliran pemain"""
global current_player
if current_player == "white":
current_player = "black"
else:
current_player = "white"
Gantikan dengan kode yang ini:
def switch_turn():
"""Beralih giliran pemain"""
global current_player, last_time
current_player = "black" if current_player == "white" else "white"
last_time = pygame.time.get_ticks() # Reset last_time saat pergantian giliran
Dengan perubahan ini, timer seharusnya berjalan optimal dan tidak berkurang saat giliran belum berpindah.
Namun, masih terlihat bahwa kode ini belum memiliki bagian utama untuk menjalankan permainan (game loop). Selain itu, juga perlu menambahkan mekanisme interaksi, seperti pergerakan bidak, aturan permainan, atau validasi langkah, maka masih ada banyak hal yang perlu dikembangkan lebih lanjut, seperti:
- Implementasi pergerakan bidak:
Tambahkan mekanisme klik untuk memilih dan memindahkan bidak.
Buat fungsi untuk validasi langkah bidak sesuai aturan catur Nine 9x9.
- AI atau Multiplayer (Opsional):
Jika ingin bermain melawan AI, bisa menambahkan algoritma minimax atau rule-based AI.
- Jika ingin multiplayer online, bisa menggunakan pygame.networking atau socket programming.
- Simpan dan Muat Permainan (Opsional):
Tambahkan fitur untuk menyimpan dan melanjutkan permainan.
Gunakan format JSON atau SQLite untuk menyimpan status permainan.
2a. Aturan Gerakan Langkah Bidak Pada Permainan Catur_Nine 9x9 Petak
Dalam Catur Nine 9x9, gerakan bidak umumnya mengikuti aturan dasar catur standar tetapi dapat mengalami penyesuaian karena papan yang lebih besar dan tambahan bidak Garuda. Berikut adalah gerakan untuk masing-masing bidak:
1. Bidak Standar
♙ Pion (Pawn)
- Langkah awal: Bisa maju 1 atau 2 petak ke depan.
- Langkah biasa: Maju 1 petak ke depan.
- Menyerang: Secara diagonal 1 petak ke depan kiri/kanan.
- Promosi: Jika mencapai baris terakhir lawan, bisa berubah menjadi Menteri (Queen), Benteng (Rook), Kuda (Knight), Gajah (Bishop), atau Garuda (jika aturan memungkinkan).
♖ Benteng (Rook)
- Dapat bergerak sejauh mungkin secara horizontal atau vertikal, selama tidak terhalang bidak lain.
- Dapat digunakan dalam rokade dengan raja.
♘ Kuda (Knight)
- Bergerak dalam pola L (2 petak satu arah, lalu 1 petak ke samping).
- Dapat melompati bidak lain.
♗ Gajah (Bishop)
- Bergerak diagonal sejauh mungkin.
- Tidak bisa melompati bidak lain.
♕ Menteri (Queen)
- Bisa bergerak horizontal, vertikal, dan diagonal sejauh mungkin.
- Tidak bisa melompati bidak lain.
♔ Raja (King)
- Bergerak 1 petak ke segala arah.
- Bisa melakukan rokade jika belum pernah bergerak dan benteng juga belum bergerak.
2. Bidak Khusus: Garuda
Garuda adalah bidak tambahan dalam Catur Nine. Gerakannya dapat berbeda tergantung aturan yang diterapkan, tetapi beberapa kemungkinan gerakannya adalah:
- Kombinasi Kuda dan Benteng: Bisa bergerak seperti Kuda (L-shape) atau Benteng (lurus vertikal & horizontal).
- Kombinasi Kuda dan Gajah: Bisa bergerak seperti Kuda (L-shape) atau Gajah (diagonal sejauh mungkin).
- Melompati bidak lain seperti Kuda jika dalam mode hybrid.
Aturan Tambahan Untuk Pion dan Garuda
Aturan tambahan (spesifik) yang diterapkan untuk Pion jalur e dan untuk Garuda memberikan variasi strategis dalam Catur Nine 9x9. Berikut adalah penjelasan lebih lanjut tentang bagaimana aturan ini memengaruhi permainan:
1. Aturan Pion dengan Petak F2P (Forboden For Pawn) di e5
-
Pion memiliki gerakan standar seperti dalam catur 8x8:
- Langkah awal: 1 atau 2 petak ke depan.
- Langkah biasa: 1 petak ke depan.
- Menyerang: Diagonal 1 petak ke kiri/kanan depan.
- Promosi: Jika mencapai baris terakhir lawan.
-
Batasan di petak e5:
- Pion di lajur e tidak dapat melewati petak e5. Jika sudah mencapai e5, pion ini tidak bisa maju lagi.
- Pion dari lajur d atau f dapat menyerang (memakan) buah catur lawan yang berada di petak e5 atau sepanjang kolom e.
- Jika pion d/f menangkap bidak lawan di e5, pion tersebut sekarang berpindah ke jalur e dan bergerak di lajur e menuju promosi.
π‘ Implikasi Strategis
- Lajur e menjadi jalur konflik utama karena pion dari lajur d/f dapat berpindah ke jalur e setelah menangkap bidak lawan di sana.
- Pemain harus memanfaatkan pion d/f untuk menyerang ke e5 agar mendapatkan kontrol jalur e.
2. Aturan Gerakan Perwira Garuda
- Garuda bergerak lurus 2 petak ke segala arah (vertikal & horizontal).
- Bisa melompati bidak lain saat bergerak.
- Contoh langkah:
- Dari g1 ke g3
- Dari g3 ke g5, atau ke i3, atau ke e3, atau kembali ke g1
π‘ Implikasi Strategis
- Mobilitas tinggi: Garuda bisa melompati bidak, menjadikannya ancaman cepat.
- Bisa menghindari hambatan pion atau perwira lain lebih mudah dibandingkan dengan benteng atau gajah.
- Posisi awal dan jalur pergerakan Garuda perlu direncanakan dengan baik agar tidak terjebak.
3. Promosi Garuda Jika Menangkap Pion di Jalur e
- Jika Garuda menangkap pion lawan yang bergerak di sepanjang lajur/kolom e, maka Garuda langsung mendapat promosi.
- Garuda bisa dipromosikan menjadi:
- Ratu (Queen)
- Benteng (Rook)
- Gajah (Bishop)
- Promosi khusus lainnya sesuai aturan tambahan
π‘ Implikasi Strategis
- Garuda dapat menjadi bidak yang lebih kuat jika berhasil menangkap pion lawan di jalur e.
- Pemain dapat mendorong lawan untuk menggerakkan pion di jalur e sebagai umpan, lalu menangkapnya dengan Garuda untuk mendapatkan promosi.
- Lajur e menjadi pusat strategi, baik untuk pion maupun Garuda.
Kesimpulan & Strategi dalam Catur Nine
- Jalur e adalah jalur kritis karena pion tidak bisa melewatinya kecuali menangkap di sana. Ini menciptakan peluang jebakan & strategi baru.
- Garuda menjadi bidak unik dengan kekuatan lompat 2 petak dan bisa mendapat promosi jika menangkap pion lawan di jalur e.
- Pemain harus merencanakan posisi pion & Garuda secara strategis, karena aturan tambahan ini membuat pion dan Garuda lebih penting daripada catur biasa.
2b. Implementasi Aturan Lengkap Game Catur_Nine pada Kode Python
Berikut aturan lengkap langkah setiap bidak dalam permainan catur, termasuk bidak Garuda, yang merupakan variasi dalam beberapa aturan catur khusus:
1. PION (Pawn)
- Langkah:
- Melangkah ke depan satu petak.
- Jika masih di baris awalnya, bisa melangkah dua petak ke depan.
- Makan Bidak Lawan:
- Makan secara diagonal satu petak ke depan.
- Promosi Pion:
- Jika mencapai baris terakhir, dapat dipromosikan menjadi Ratu, Benteng, Gajah, atau Kuda.
- En Passant:
- Jika lawan memindahkan pion dua petak ke depan dan berada di samping pion kita, kita bisa menangkapnya secara diagonal pada langkah berikutnya.
2. KUDA (Knight)
- Langkah:
- Melangkah dalam pola “L”: dua petak ke satu arah lalu satu petak ke samping, atau sebaliknya (1+2 atau 2+1).
- Melewati Bidak Lain:
- Kuda dapat melompati bidak lain, satu-satunya bidak yang memiliki kemampuan ini.
3. GAJAH (Bishop)
- Langkah:
- Bergerak diagonal sejauh yang diinginkan tanpa melewati bidak lain.
- Bidak Tetap pada Warna Asalnya:
- Jika awalnya di petak hitam, ia akan selalu berada di petak hitam, dan sebaliknya.
4. BENTENG (Rook)
- Langkah:
- Bergerak lurus ke depan, belakang, kiri, atau kanan sejauh yang diinginkan tanpa melewati bidak lain.
- Kombinasi dengan Raja (Rokade):
- Bisa melakukan rokade dengan Raja jika belum pernah bergerak sebelumnya dan tidak ada bidak di antara mereka.
5. RATU (Queen)
- Langkah:
- Kombinasi Bishop dan Rook, dapat bergerak lurus atau diagonal sejauh yang diinginkan tanpa melewati bidak lain.
6. RAJA (King)
- Langkah:
- Bergerak satu petak ke segala arah.
- Rokade:
- Jika belum pernah bergerak dan Benteng di baris yang sama juga belum bergerak, serta tidak ada bidak di antara mereka, Raja bisa berpindah dua petak ke arah Benteng, dan Benteng melompat ke sisi lain Raja.
- Skakmat:
- Raja tidak boleh melangkah ke petak yang terkena serangan lawan. Jika tidak ada langkah tersisa yang sah, permainan berakhir dalam skakmat.
7. GARUDA (Bidak Variasi)
Bidak Garuda adalah bidak tambahan yang digunakan dalam beberapa varian catur (misalnya, dalam catur Nusantara). Aturannya bisa berbeda tergantung variasi yang digunakan, tetapi biasanya memiliki karakteristik sebagai berikut:
- Langkah Umum:
- Bisa melompat seperti kuda (L-shape).
- Bisa melangkah lurus satu petak seperti raja.
- Bisa melangkah diagonal satu petak seperti ratu.
- Kemampuan Khusus:
- Bisa menyerang seperti ratu, tetapi hanya dalam satu langkah.
- Dalam beberapa aturan, Garuda dapat melompati satu bidak dan mendarat di petak di belakangnya.
Itulah aturan lengkap pergerakan semua bidak dalam permainan catur, termasuk variasi Garuda. Jika ada aturan khusus yang ingin diterapkan, bisa disesuaikan dengan versi catur yang digunakan!
Awalnya adalah kode isi file __main__.py:
import pygame
import sys
import os
import time
import catur_nine_move
# === KONFIGURASI PYGAME ===
pygame.init()
# Ukuran layar
SCREEN_WIDTH, SCREEN_HEIGHT = 900, 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Chess Nine with Timer")
# Ukuran papan catur
BOARD_SIZE = 635
TILE_SIZE = BOARD_SIZE // 9
BOARD_X = (SCREEN_WIDTH - BOARD_SIZE) // 2 - 90
BOARD_Y = (SCREEN_HEIGHT - BOARD_SIZE) // 2 - (-170)
# Warna
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
LIGHT_BROWN = (240, 217, 181)
DARK_BROWN = (181, 136, 99)
RED = (200, 50, 50)
GREEN = (50, 200, 50)
# Font
font = pygame.font.Font(None, 40)
# Direktori gambar bidak
IMAGE_DIR = "/storage/emulated/0/AppJadi/Catur/Catur_9x9/images"
# === MEMUAT GAMBAR BIDAK ===
pieces_images = {}
def load_pieces():
"""Memuat gambar bidak dari direktori"""
piece_names = ["pawn", "rook", "knight", "bishop", "queen", "king", "garuda"]
colors = ["white", "black"]
for color in colors:
for piece in piece_names:
path = os.path.join(IMAGE_DIR, f"{color}_{piece}.png")
if os.path.exists(path):
img = pygame.image.load(path)
img = pygame.transform.scale(img, (TILE_SIZE, TILE_SIZE))
pieces_images[f"{color}_{piece}"] = img
# === FORMASI AWAL BIDAK PUTIH ===
formasi_1_white = { # 2 Kuda, 1 Garuda (Menambahkan gajah di c1)
"white_knight": [(7, 8), (1, 8)],
"white_garuda": [(6, 8)],
"white_bishop": [(2, 8), (5, 8)] # Gajah putih di c1 dan f1
}
formasi_2_white = { # 2 Garuda, 1 Kuda (Menambahkan gajah di c1 dan h1)
"white_knight": [(5, 8)],
"white_garuda": [(1, 8), (6, 8)],
"white_bishop": [(2, 8), (7, 8)] # Gajah putih di c1 dan h1
}
# === FORMASI AWAL BIDAK HITAM === (Disesuaikan dengan formasi putih)
formasi_1_black = { # 2 Kuda, 1 Garuda (Menambahkan gajah di c9)
"black_knight": [(7, 0), (1, 0)],
"black_garuda": [(6, 0)],
"black_bishop": [(2, 0), (5, 0)] # Gajah hitam di c9 dan f9
}
formasi_2_black = { # 2 Garuda, 1 Kuda (Menambahkan gajah di c9 dan h9)
"black_knight": [(5, 0)],
"black_garuda": [(1, 0), (6, 0)],
"black_bishop": [(2, 0), (7, 0)] # Gajah hitam di c9 dan h9
}
# === POSISI DEFAULT (TIDAK BERUBAH) ===
default_position = {
"white_rook": [(0, 8), (8, 8)],
"white_queen": [(3, 8)],
"white_king": [(4, 8)],
"white_pawn": [(i, 7) for i in range(9)],
"black_rook": [(0, 0), (8, 0)],
"black_queen": [(3, 0)],
"black_king": [(4, 0)],
"black_pawn": [(i, 1) for i in range(9)],
}
# === WAKTU PERMAINAN ===
WHITE_TIME = 3600 # 60 menit dalam detik
BLACK_TIME = 3600
current_player = "white"
last_time = pygame.time.get_ticks() # Gunakan get_ticks()
def draw_timer():
"""Menampilkan timer di layar dengan kotak pembungkus"""
white_timer_text = font.render(f"{WHITE_TIME // 60}:{WHITE_TIME % 60:02d}", True, BLACK)
black_timer_text = font.render(f"{BLACK_TIME // 60}:{BLACK_TIME % 60:02d}", True, BLACK)
# Ukuran kotak pembungkus
box_width, box_height = 140, 50
# Posisi kotak untuk white_timer
white_box_x = BOARD_X + BOARD_SIZE - 100
white_box_y = BOARD_Y + BOARD_SIZE - box_height + 60
# Posisi kotak untuk black_timer
black_box_x = BOARD_X + BOARD_SIZE - 100
black_box_y = BOARD_Y - 60
# Gambar kotak untuk white_timer
pygame.draw.rect(screen, LIGHT_BROWN, (white_box_x, white_box_y, box_width, box_height), border_radius=10)
pygame.draw.rect(screen, BLACK, (white_box_x, white_box_y, box_width, box_height), 2, border_radius=10)
screen.blit(white_timer_text, (white_box_x + 40, white_box_y + 10))
# Gambar kotak untuk black_timer
pygame.draw.rect(screen, LIGHT_BROWN, (black_box_x, black_box_y, box_width, box_height), border_radius=10)
pygame.draw.rect(screen, BLACK, (black_box_x, black_box_y, box_width, box_height), 2, border_radius=10)
screen.blit(black_timer_text, (black_box_x + 40, black_box_y + 10))
def update_timer():
"""Mengupdate timer berdasarkan giliran pemain"""
global WHITE_TIME, BLACK_TIME, last_time
current_time = pygame.time.get_ticks()
elapsed_time = (current_time - last_time) // 1000 # Konversi ms ke detik
if elapsed_time > 0:
if current_player == "white":
WHITE_TIME -= elapsed_time
if WHITE_TIME <= 0:
print("Waktu Habis! Hitam Menang!")
pygame.quit()
sys.exit()
else:
BLACK_TIME -= elapsed_time
if BLACK_TIME <= 0:
print("Waktu Habis! Putih Menang!")
pygame.quit()
sys.exit()
last_time = current_time # Perbarui last_time setelah mengurangi waktu
# === FUNGSI GAMBAR PAPAN DAN BIDAK ===
def draw_board():
for row in range(9):
for col in range(9):
# Petak e5 (indeks array: 4,4) diwarnai putih
if row == 4 and col == 4:
color = WHITE
else:
# Warna petak papan catur normal
color = DARK_BROWN if (row + col) % 2 == 0 else LIGHT_BROWN
pygame.draw.rect(screen, color,
(BOARD_X + col * TILE_SIZE, BOARD_Y + row * TILE_SIZE, TILE_SIZE, TILE_SIZE))
def draw_pieces(starting_position):
"""Menggambar semua bidak di posisi awal"""
for piece, positions in starting_position.items():
if piece in pieces_images:
for pos in positions:
x, y = pos
screen.blit(pieces_images[piece],
(BOARD_X + x * TILE_SIZE, BOARD_Y + y * TILE_SIZE))
# === FUNGSI GILIRAN ===
def switch_turn():
"""Beralih giliran pemain"""
global current_player, last_time
current_player = "black" if current_player == "white" else "white"
last_time = pygame.time.get_ticks() # Reset last_time saat pergantian giliran
# === FUNGSI TOMBOL FORMASI ===
def draw_button(text, x, y, width, height, color):
pygame.draw.rect(screen, color, (x, y, width, height), border_radius=5)
button_text = font.render(text, True, WHITE)
screen.blit(button_text, (x + 10, y + 10))
return pygame.Rect(x, y, width, height)
def choose_white_formation():
"""Menampilkan tombol pilihan formasi untuk bidak putih sebelum permainan dimulai dengan latar papan catur."""
selected_formation = None
while selected_formation is None:
screen.fill(WHITE) # Membersihkan layar sebelum menggambar ulang
# **Gambar papan catur 9x9 sebagai latar belakang**
draw_board()
label_text = font.render("GAME CATUR_NINE 9x9 PETAK", True, BLACK)
screen.blit(label_text, (SCREEN_WIDTH // 2 - 300, SCREEN_HEIGHT // 3 - 220))
# **Tambahkan label pemilihan formasi**
title_text = font.render("Pilih Formasi Bidak Putih:", True, BLACK)
screen.blit(title_text, (SCREEN_WIDTH // 2 - 270, SCREEN_HEIGHT // 3 + 605))
# **Gambar tombol pilihan formasi**
btn_1 = draw_button("2 Kuda, 1 Garuda", SCREEN_WIDTH // 2 - 230, SCREEN_HEIGHT // 3+638, 280, 50, RED)
btn_2 = draw_button("2 Garuda, 1 Kuda", SCREEN_WIDTH // 2 - 230, SCREEN_HEIGHT // 3 + 700, 280, 50, GREEN)
# **Perbarui tampilan**
pygame.display.flip()
# **Tangani event klik tombol**
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
if btn_1.collidepoint(mouse_pos):
selected_formation = formasi_1_white
elif btn_2.collidepoint(mouse_pos):
selected_formation = formasi_2_white
return selected_formation
def choose_black_formation():
"""Menampilkan tombol pilihan formasi untuk bidak hitam sebelum permainan dimulai."""
selected_formation = None
while selected_formation is None:
screen.fill(WHITE)
# **Gambar papan catur 9x9 sebagai latar belakang**
draw_board()
label_text = font.render("GAME CATUR_NINE 9x9 PETAK", True, BLACK)
screen.blit(label_text, (SCREEN_WIDTH // 2 - 300, SCREEN_HEIGHT // 3 - 220))
ltitle_text = font.render("Pilih Formasi Bidak Hitam:", True, BLACK)
screen.blit(ltitle_text, (SCREEN_WIDTH // 2 - 270, SCREEN_HEIGHT // 10 - 20))
btn_1 = draw_button("2 Kuda, 1 Garuda", SCREEN_WIDTH // 2 - 230, SCREEN_HEIGHT // 12 + 28, 280, 50, RED)
btn_2 = draw_button("2 Garuda, 1 Kuda", SCREEN_WIDTH // 2 - 230, SCREEN_HEIGHT // 13 + 95, 280, 50, GREEN)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
if btn_1.collidepoint(mouse_pos):
selected_formation = formasi_1_black
elif btn_2.collidepoint(mouse_pos):
selected_formation = formasi_2_black
return selected_formation
def choose_formation():
"""Menampilkan tombol pilihan formasi sebelum permainan dimulai."""
selected_formation = None
while selected_formation is None:
screen.fill(WHITE)
label_text = font.render("GAME CATUR_NINE 9x9 PETAK", True, BLACK)
screen.blit(label_text, (SCREEN_WIDTH // 2 - 300, SCREEN_HEIGHT // 5 - 50))
title_text = font.render("Pilih Formasi Bidak:", True, BLACK)
screen.blit(title_text, (SCREEN_WIDTH // 2 - 135, SCREEN_HEIGHT // 3 - 50))
btn_1 = draw_button("2 Kuda, 1 Garuda", SCREEN_WIDTH // 2 - 140, SCREEN_HEIGHT // 3, 280, 50, RED)
btn_2 = draw_button("2 Garuda, 1 Kuda", SCREEN_WIDTH // 2 - 140, SCREEN_HEIGHT // 3 + 70, 280, 50, GREEN)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
if btn_1.collidepoint(mouse_pos):
selected_formation = (formasi_1_white, formasi_1_black)
elif btn_2.collidepoint(mouse_pos):
selected_formation = (formasi_2_white, formasi_2_black)
return selected_formation
# === MULAI GAME ===
clock = pygame.time.Clock()
# Muat gambar bidak
load_pieces()
# Pemain memilih formasi awal
chosen_white = choose_white_formation()
chosen_black = choose_black_formation()
# Gabungkan posisi default dengan formasi yang dipilih
starting_position = {**default_position, **chosen_white, **chosen_black}
running = True
while running:
screen.fill(WHITE)
# Update timer sebelum menggambar papan
update_timer()
draw_board()
draw_pieces(starting_position)
draw_timer()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
switch_turn() # Simulasi pergantian giliran jika ada klik mouse
pygame.display.flip()
clock.tick(30)
pygame.quit()
sys.exit()
Selanjutnya membuat kode isi file: catur_nine_move.py yang mengatur fungsi gerakan langkah sah dari setiap bidak catur_nine, agar supaya ketika kode dieksekusi dari __main__.py maka catur_nine bisa dimainkan dengan benar dan tanpa error.
Untuk mengimplementasikan gerakan bidak (logika pergerakan bidak) dalam permainan Catur Nine 9x9, kita perlu:
- Menyimpan status papan (posisi semua bidak).
- Menangani klik pemain untuk memilih dan memindahkan bidak.
- Mengecek apakah langkah valid berdasarkan aturan gerakan tiap bidak.
- Memperbarui tampilan setelah bidak bergerak.
- Menjalankan Loop Utama
Langkah 1: Menyimpan Status Papan
Buat dictionary board_state
untuk menyimpan posisi setiap bidak:
# Status awal papan (gabungan default_position dan formasi pilihan)
board_state = {}
def initialize_board():
"""Mengisi papan dengan posisi awal bidak"""
global board_state
board_state = default_position.copy() # Mulai dengan posisi default
# Tambahkan formasi yang dipilih
white_formation = choose_white_formation()
black_formation = choose_black_formation()
for piece, positions in white_formation.items():
board_state[piece] = positions
for piece, positions in black_formation.items():
board_state[piece] = positions
Kode ini lebih cocok dimasukkan ke dalam file catur_nine_move.py
, karena berfungsi untuk:
✅ Mengelola status papan (posisi bidak)
✅ Menginisialisasi papan dengan formasi default dan formasi pilihan
File catur_nine_move.py
berisi logika permainan, seperti:
- Gerakan bidak
- Validasi langkah
- Perubahan status papan
Sementara itu, file __main__.py
biasanya digunakan untuk:
- Menjalankan permainan (game loop)
- Menampilkan UI/Tampilan papan dengan Pygame
- Memanggil fungsi dari
catur_nine_move.py
untuk menangani gerakan
Jadi, dalam __main__.py
, Anda cukup memanggil initialize_board()
saat memulai game:
from catur_nine_move import initialize_board
initialize_board()
Sehingga, kode logika permainan tetap terpisah dari kode tampilan dan eksekusi utama.
Langkah 2: Menangani Klik Pemain
Pemain akan klik bidak untuk memilihnya, lalu klik petak tujuan untuk memindahkannya.
Tambahkan variabel untuk menyimpan bidak yang sedang dipilih:
selected_piece = None
selected_position = None
Kode ini lebih cocok ditempatkan di catur_nine_move.py
, karena variabel ini digunakan untuk menyimpan bidak yang dipilih dan posisinya, yang berkaitan dengan logika permainan.
File catur_nine_move.py
menangani:
✅ Pemilihan bidak
✅ Validasi gerakan
✅ Eksekusi perpindahan
Namun, jika file __main__.py
menangani interaksi pengguna (misalnya dengan Pygame), ada kemungkinan variabel ini perlu dideklarasikan di __main__.py
.
Misalnya, jika selected_piece
dan selected_position
digunakan untuk menyimpan input dari pemain saat mengklik papan catur, maka lebih cocok di __main__.py
.
Solusi Terbaik:
- Jika digunakan untuk logika gerakan →
catur_nine_move.py
- Jika digunakan untuk menyimpan input pengguna dari UI →
__main__.py
- Jika diperlukan di kedua file, gunakan global state atau objek game untuk menyimpannya secara terpusat.
Selanjutnya Tambahkan fungsi untuk menangani klik pengguna:
def handle_click(position):
"""Menangani klik pemain untuk memilih dan memindahkan bidak"""
global selected_piece, selected_position, current_player
col = (position[0] - BOARD_X) // TILE_SIZE
row = (position[1] - BOARD_Y) // TILE_SIZE
if 0 <= col < 9 and 0 <= row < 9:
clicked_piece = None
clicked_position = (col, row)
# Cek apakah ada bidak di petak yang diklik
for piece, positions in board_state.items():
if clicked_position in positions:
clicked_piece = piece
break
if selected_piece is None:
# Pemain memilih bidak miliknya
if clicked_piece and clicked_piece.startswith(current_player):
selected_piece = clicked_piece
selected_position = clicked_position
else:
# Pemain mencoba memindahkan bidak yang telah dipilih
if is_valid_move(selected_piece, selected_position, clicked_position):
move_piece(selected_piece, selected_position, clicked_position)
switch_turn() # Ganti giliran
selected_piece = None # Reset pilihan bidak
Kode ini lebih cocok ditempatkan di __main__.py
, karena fungsi handle_click(position)
menangani input pemain saat mengklik papan catur.
Alasan:
✅ __main__.py
biasanya menangani event input dari pengguna, seperti klik mouse.
✅ Fungsi ini bergantung pada koordinat tampilan (position[0] - BOARD_X
), yang berarti berhubungan dengan UI atau rendering.
✅ Fungsi ini tidak menentukan aturan gerakan (itu tugas catur_nine_move.py
), tetapi hanya menangani pemilihan dan eksekusi gerakan berdasarkan klik pemain.
Struktur yang Disarankan:
- Di
__main__.py
handle_click(position)
→ Menangani klik pemain- Menghubungkan input dengan logika permainan
- Di
catur_nine_move.py
is_valid_move(piece, start, end)
→ Mengecek apakah langkah sahmove_piece(piece, start, end)
→ Menggerakkan bidak diboard_state
- Aturan pergerakan dan validasi bidak
Jadi, kode ini lebih cocok berada di __main__.py
karena fungsinya menangani event klik dari pemain.
Langkah 3: Validasi Gerakan Bidak
Tambahkan fungsi is_valid_move()
untuk mengecek apakah langkah valid.
def is_valid_move(piece, start_pos, end_pos):
"""Memeriksa apakah gerakan bidak sesuai aturan"""
x1, y1 = start_pos
x2, y2 = end_pos
# Pastikan tujuan tidak ditempati bidak sendiri
for p, positions in board_state.items():
if end_pos in positions and p.startswith(current_player):
return False
# Aturan gerakan tiap bidak
if "pawn" in piece: # Pion
direction = -1 if "white" in piece else 1
if x1 == x2 and (y2 - y1) == direction: # Maju 1 langkah
return True
elif abs(x2 - x1) == 1 and (y2 - y1) == direction: # Makan bidak
return end_pos in [pos for p, pos_list in board_state.items() if p.startswith(opponent())]
elif "rook" in piece: # Benteng
return (x1 == x2 or y1 == y2) and is_path_clear(start_pos, end_pos)
elif "knight" in piece: # Kuda (L-shape)
return (abs(x2 - x1), abs(y2 - y1)) in [(1, 2), (2, 1)]
elif "bishop" in piece: # Gajah
return abs(x2 - x1) == abs(y2 - y1) and is_path_clear(start_pos, end_pos)
elif "queen" in piece: # Ratu (Gabungan Benteng + Gajah)
return (x1 == x2 or y1 == y2 or abs(x2 - x1) == abs(y2 - y1)) and is_path_clear(start_pos, end_pos)
elif "king" in piece: # Raja
return max(abs(x2 - x1), abs(y2 - y1)) == 1
elif "garuda" in piece: # Garuda (Gerakan khusus)
return (abs(x2 - x1) <= 2 and abs(y2 - y1) <= 2) # Bisa maju 2 langkah di segala arah
return False
Kode ini lebih cocok berada di catur_nine_move.py
.
Alasan:
✅ Fungsi is_valid_move()
menangani logika gerakan bidak berdasarkan aturan permainan.
✅ catur_nine_move.py
adalah tempat yang tepat untuk menyimpan aturan pergerakan bidak, agar terpisah dari event handling di __main__.py
.
✅ __main__.py
lebih fokus menangani interaksi pengguna, sementara aturan catur dan validasi gerakan lebih cocok dipisahkan ke dalam catur_nine_move.py
.
Struktur yang Disarankan:
- Di
__main__.py
handle_click(position)
→ Menangani input klik dari pemain- Memanggil
is_valid_move()
saat pemain mencoba bergerak
- Di
catur_nine_move.py
is_valid_move(piece, start_pos, end_pos)
→ Mengecek apakah langkah bidak sahmove_piece(piece, start_pos, end_pos)
→ Memindahkan bidak jika langkah valid- Fungsi-fungsi tambahan seperti
is_path_clear()
Jadi, kode ini lebih baik ditempatkan di catur_nine_move.py
karena berisi aturan validasi gerakan bidak.
Selanjutnya, Fungsi is_path_clear()
untuk memastikan tidak ada bidak yang menghalangi:
def is_path_clear(start, end):
"""Memeriksa apakah jalur antara dua titik bersih dari bidak lain"""
x1, y1 = start
x2, y2 = end
if x1 == x2: # Vertikal
step = 1 if y2 > y1 else -1
for y in range(y1 + step, y2, step):
if (x1, y) in [pos for positions in board_state.values() for pos in positions]:
return False
elif y1 == y2: # Horizontal
step = 1 if x2 > x1 else -1
for x in range(x1 + step, x2, step):
if (x, y1) in [pos for positions in board_state.values() for pos in positions]:
return False
elif abs(x2 - x1) == abs(y2 - y1): # Diagonal
step_x = 1 if x2 > x1 else -1
step_y = 1 if y2 > y1 else -1
for i in range(1, abs(x2 - x1)):
if (x1 + i * step_x, y1 + i * step_y) in [pos for positions in board_state.values() for pos in positions]:
return False
return True
Kode ini lebih cocok berada di catur_nine_move.py
.
Alasan:
✅ Fungsi is_path_clear()
bertugas untuk mengecek apakah jalur gerakan bidak tidak terhalang oleh bidak lain.
✅ Fungsi ini terkait dengan aturan pergerakan bidak, bukan interaksi pengguna, sehingga lebih cocok ditempatkan di catur_nine_move.py
.
✅ Fungsi ini dipanggil di dalam is_valid_move()
, yang juga berada di catur_nine_move.py
.
Struktur yang Disarankan:
- Di
__main__.py
- Menangani input klik pemain (
handle_click()
). - Memanggil
is_valid_move()
untuk mengecek apakah gerakan sah.
- Menangani input klik pemain (
- Di
catur_nine_move.py
is_valid_move(piece, start_pos, end_pos)
→ Memeriksa validitas gerakan.is_path_clear(start, end)
→ Memeriksa apakah jalur gerakan bersih.move_piece(piece, start_pos, end_pos)
→ Memindahkan bidak jika gerakan valid.
Jadi, kode ini lebih baik ditempatkan di catur_nine_move.py
, karena merupakan bagian dari logika aturan pergerakan bidak.
Langkah 4: Memindahkan Bidak
Jika langkah valid, pindahkan bidak ke petak tujuan dan hapus bidak lawan jika ada:
def move_piece(piece, start_pos, end_pos):
"""Memindahkan bidak ke posisi baru"""
board_state[piece].remove(start_pos)
board_state[piece].append(end_pos)
# Hapus bidak lawan jika ada
for p, positions in board_state.items():
if p.startswith(opponent()) and end_pos in positions:
positions.remove(end_pos)
break
Kode ini lebih cocok berada di catur_nine_move.py
.
Alasan:
✅ Fungsi move_piece()
menangani pemindahan bidak, yang merupakan bagian dari aturan permainan, bukan interaksi pengguna.
✅ Fungsi ini berhubungan langsung dengan is_valid_move()
, yang sebelumnya juga ditempatkan di catur_nine_move.py
.
✅ Bagian utama __main__.py
biasanya menangani input dan tampilan (seperti menangani klik), sedangkan catur_nine_move.py
menangani aturan permainan dan logika pemindahan bidak.
Struktur yang Disarankan:
- Di
__main__.py
- Fungsi
handle_click(position)
→ Menangani klik pemain dan memanggilis_valid_move()
.
- Fungsi
- Di
catur_nine_move.py
- Fungsi
is_valid_move(piece, start_pos, end_pos)
→ Mengecek apakah gerakan valid. - Fungsi
is_path_clear(start, end)
→ Mengecek jalur gerakan. - Fungsi
move_piece(piece, start_pos, end_pos)
→ Memindahkan bidak jika gerakan valid.
- Fungsi
Jadi, kode ini lebih baik ditempatkan di catur_nine_move.py
, karena berfungsi sebagai bagian dari aturan permainan untuk menggerakkan bidak.
Selanjutnya, tambahkan fungsi untuk menentukan giliran lawan:
def opponent():
return "white" if current_player == "black" else "black"
Kode ini lebih cocok berada di catur_nine_move.py
.
Alasan:
✅ Fungsi ini bersifat logis dan digunakan dalam aturan permainan, bukan dalam interaksi langsung dengan pengguna.
✅ Fungsi ini diperlukan dalam is_valid_move()
dan move_piece()
, yang sebelumnya juga ditempatkan di catur_nine_move.py
.
✅ __main__.py
lebih berfokus pada event handling dan UI, sedangkan aturan permainan lebih cocok ditempatkan di catur_nine_move.py
.
Struktur yang Disarankan:
- Di
__main__.py
- Menangani input pemain dan memanggil fungsi yang ada di
catur_nine_move.py
.
- Menangani input pemain dan memanggil fungsi yang ada di
- Di
catur_nine_move.py
opponent()
is_valid_move()
move_piece()
is_path_clear()
Jadi, kode ini lebih baik ditempatkan di catur_nine_move.py
, karena berkaitan dengan logika permainan.
Langkah 5: Menjalankan Game Loop
Tambahkan dalam loop utama Pygame untuk menangani klik pemain:
running = True
initialize_board()
load_pieces()
while running:
screen.fill(WHITE)
draw_board()
draw_pieces(board_state)
draw_timer()
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
handle_click(event.pos)
pygame.quit()
sys.exit()
Kode ini lebih cocok berada di __main__.py
.
Alasan:
✅ Kode ini berisi loop utama (game loop), yang bertanggung jawab atas tampilan dan event handling, seperti klik pemain dan perintah keluar dari permainan.
✅ Fungsi pygame.event.get()
digunakan untuk menangani input pemain, yang biasanya ditempatkan di __main__.py
karena mengontrol jalannya program.
✅ Fungsi draw_board()
, draw_pieces()
, dan draw_timer()
berhubungan dengan rendering tampilan, yang lebih cocok di __main__.py
daripada catur_nine_move.py
.
Struktur yang Disarankan:
- Di
__main__.py
- Game loop (seperti kode ini)
- Menangani input pemain (
handle_click() dipanggil di sini
) - Mengontrol tampilan dengan
pygame
- Di
catur_nine_move.py
- Aturan permainan (
is_valid_move()
,move_piece()
, dll.) - Logika pemrosesan gerakan bidak
- Aturan permainan (
Jadi, kode ini lebih baik ditempatkan di __main__.py
, karena bertanggung jawab untuk menjalankan loop utama dan menampilkan permainan.
Kesimpulan
Dengan implementasi ini, game Chess Nine 9x9 dapat:
✅ Menyimpan status papan
✅ Memilih bidak dengan klik
✅ Validasi gerakan bidak
✅ Memindahkan bidak & menghapus lawan
✅ Berganti giliran otomatis
Silakan dicoba,
Langkah Valid Setiap Gerakan Bidak
Berikut adalah kode Python dalam file catur_nine_move.py
, yang mengimplementasikan aturan langkah semua bidak dalam Catur Nine, termasuk Pion, Kuda, Gajah, Benteng, Ratu, Raja, dan Garuda.
Kode ini mendefinisikan kelas untuk setiap bidak, dengan metode untuk menghitung langkah-langkah yang sah.
Kode: catur_nine_move.py
class Bidak:
def __init__(self, warna):
self.warna = warna # "Putih" atau "Hitam"
def langkah_sah(self, posisi_awal):
"""Metode ini akan diimplementasikan oleh setiap bidak secara khusus."""
pass
class Pion(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah = []
# Pion Putih naik, Pion Hitam turun
arah = 1 if self.warna == "Putih" else -1
# Langkah normal
langkah.append((baris + arah, kolom))
# Langkah awal dua petak
if (self.warna == "Putih" and baris == 1) or (self.warna == "Hitam" and baris == 6):
langkah.append((baris + 2 * arah, kolom))
# Langkah makan secara diagonal
langkah.append((baris + arah, kolom - 1))
langkah.append((baris + arah, kolom + 1))
return langkah
class Kuda(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah = [
(baris + 2, kolom + 1), (baris + 2, kolom - 1),
(baris - 2, kolom + 1), (baris - 2, kolom - 1),
(baris + 1, kolom + 2), (baris + 1, kolom - 2),
(baris - 1, kolom + 2), (baris - 1, kolom - 2)
]
return langkah
class Gajah(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah = []
for i in range(1, 8):
langkah.extend([(baris + i, kolom + i), (baris + i, kolom - i),
(baris - i, kolom + i), (baris - i, kolom - i)])
return langkah
class Benteng(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah = []
for i in range(1, 8):
langkah.extend([(baris + i, kolom), (baris - i, kolom),
(baris, kolom + i), (baris, kolom - i)])
return langkah
class Ratu(Bidak):
def langkah_sah(self, posisi_awal):
langkah_gajah = Gajah(self.warna).langkah_sah(posisi_awal)
langkah_benteng = Benteng(self.warna).langkah_sah(posisi_awal)
return langkah_gajah + langkah_benteng
class Raja(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah = [
(baris + 1, kolom), (baris - 1, kolom),
(baris, kolom + 1), (baris, kolom - 1),
(baris + 1, kolom + 1), (baris + 1, kolom - 1),
(baris - 1, kolom + 1), (baris - 1, kolom - 1)
]
return langkah
class Garuda(Bidak):
def langkah_sah(self, posisi_awal):
baris, kolom = posisi_awal
langkah_kuda = Kuda(self.warna).langkah_sah(posisi_awal)
langkah_raja = Raja(self.warna).langkah_sah(posisi_awal)
return langkah_kuda + langkah_raja
# Contoh penggunaan
if __name__ == "__main__":
pion_putih = Pion("Putih")
kuda_hitam = Kuda("Hitam")
garuda_putih = Garuda("Putih")
print("Langkah Pion Putih dari (1, 3):", pion_putih.langkah_sah((1, 3)))
print("Langkah Kuda Hitam dari (4, 4):", kuda_hitam.langkah_sah((4, 4)))
print("Langkah Garuda Putih dari (5, 5):", garuda_putih.langkah_sah((5, 5)))
Penjelasan Kode:
- Setiap bidak dibuat sebagai kelas dengan metode
langkah_sah()
, yang mengembalikan daftar koordinat langkah yang diizinkan. - Implementasi langkah sesuai aturan:
- Pion: Langkah lurus ke depan, dua langkah saat pertama kali, makan secara diagonal.
- Kuda: Melangkah dalam pola "L".
- Gajah: Melangkah diagonal sejauh mungkin.
- Benteng: Bergerak vertikal atau horizontal sejauh mungkin.
- Ratu: Gabungan dari Gajah dan Benteng.
- Raja: Bergerak satu petak ke segala arah.
- Garuda: Gabungan langkah Kuda dan Raja.
- Kode contoh pemanggilan di bagian
if __name__ == "__main__":
, yang mencetak langkah sah dari beberapa bidak.
Kode ini dapat digunakan dalam permainan Catur Nine, memungkinkan pengembangan lebih lanjut seperti validasi langkah dan implementasi GUI dengan tkinter atau pygame.
Aturan Promosi Perwira (Garuda/Kuda) yang Memakan Pion di Lajur e:
Aturan tambahan berupa Promosi Perwira Tunggal Terkecil pada catur_nine, bahwa bila pemain memilih formasi 2 Garuda, 1 Kuda, maka perwira yang dapat promosi adalah Kuda (bukan garuda) bila saja Kuda dapat memakan pion lawan yang bergerak di sepanjang lajur e maka Kuda ini akan mendapat promosi bertukar menjadi ratu/benteng atau promosi lainnya yang ditentukan. Sedangkan bila pemain memilih formasi 2 Kuda 1 Garuda pada catur_nine, maka perwira yang dapat promosi adalah Garuda (bukan kuda) bila saja Garuda dapat memakan pion lawan yang bergerak di sepanjang lajur e maka Garuda ini akan mendapat promosi bertukar menjadi ratu/benteng atau promosi lainnya yang ditentukan
Berikut implementasi aturan tambahan pada Chess Nine sesuai dengan ketentuan Promosi Perwira (Garuda/Kuda) ini:
-
Jika pemain memilih formasi "2 Garuda, 1 Kuda", maka satu-satunya perwira yang dapat promosi adalah Kuda.
- Kuda hanya bisa promosi jika berhasil memakan pion lawan yang bergerak di sepanjang lajur e.
- Kuda dapat dipromosikan menjadi Ratu, Benteng, atau bidak lainnya yang dipilih pemain.
-
Jika pemain memilih formasi "2 Kuda, 1 Garuda", maka satu-satunya perwira yang dapat promosi adalah Garuda.
- Garuda hanya bisa promosi jika berhasil memakan pion lawan yang bergerak di sepanjang lajur e.
- Garuda dapat dipromosikan menjadi Ratu, Benteng, atau bidak lainnya yang dipilih pemain.
Aturan menyesuaikan kode untuk:
- Menyimpan informasi formasi pemain.
- Menentukan apakah Kuda atau Garuda berhasil memakan pion lawan di lajur e.
- Jika memenuhi syarat promosi, munculkan menu pemilihan bidak promosi.
Perbaikan kode
# === ATURAN PROMOSI KHUSUS ===
def check_promotion(piece, old_pos, new_pos, formasi):
"""Cek apakah bidak memenuhi syarat promosi berdasarkan formasi"""
old_x, old_y = old_pos
new_x, new_y = new_pos
if new_x == 4 and (old_y - new_y) == 1: # Lajur e = kolom 4
if formasi == "2 Garuda, 1 Kuda" and piece.endswith("knight"):
return True # Kuda bisa promosi
elif formasi == "2 Kuda, 1 Garuda" and piece.endswith("garuda"):
return True # Garuda bisa promosi
return False
def promote_piece(piece):
"""Menampilkan pilihan promosi untuk Kuda atau Garuda"""
color, piece_type = piece.split("_")
promo_options = [f"{color}_queen", f"{color}_rook", f"{color}_bishop"]
while True:
screen.fill(WHITE)
draw_board()
# Tampilkan opsi promosi
text = font.render(f"Pilih Promosi untuk {piece_type.capitalize()}:", True, BLACK)
screen.blit(text, (SCREEN_WIDTH // 2 - 120, SCREEN_HEIGHT // 3 - 50))
btns = []
x_offset = SCREEN_WIDTH // 2 - 150
for i, option in enumerate(promo_options):
btn = draw_button(option.split("_")[1].capitalize(), x_offset + i * 120, SCREEN_HEIGHT // 3 + 50, 100, 50, RED)
btns.append((btn, option))
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
for btn, option in btns:
if btn.collidepoint(mouse_pos):
return option # Kembalikan jenis bidak promosi
# === HANDLE PERGERAKAN BIDAK ===
def move_piece(mouse_pos):
"""Menangani pergerakan bidak"""
global selected_piece, selected_position
col = (mouse_pos[0] - BOARD_X) // TILE_SIZE
row = (mouse_pos[1] - BOARD_Y) // TILE_SIZE
if selected_piece and 0 <= row < 9 and 0 <= col < 9:
if check_promotion(selected_piece, selected_position, (col, row), player_formation):
promoted_piece = promote_piece(selected_piece)
pieces_positions.pop(selected_piece)
pieces_positions[promoted_piece] = [(col, row)]
else:
pieces_positions[selected_piece].remove(selected_position)
pieces_positions[selected_piece].append((col, row))
selected_piece = None
selected_position = None
Kode program yang telah dibuat:
✅ Membuat satu fungsi check_promotion()
untuk menentukan apakah Kuda atau Garuda memenuhi syarat promosi.
✅ Menyesuaikan menu promote_piece()
agar dapat mempromosikan baik Kuda maupun Garuda.
✅ Mengubah move_piece()
agar sistem hanya mengizinkan promosi untuk perwira yang benar yaitu Perwira Tunggal Terkecil berdasarkan formasi yang dipilih pemain.
Dengan perbaikan ini, aturan tambahan pada Chess Nine sekarang sudah diterapkan dengan benar.
Masalah Bidak Catur_Nine Tidak Bisa Digerakkan
Setelah membuat kode tapi bidak catur_nine tidak bisa digerakkan, lihat kode pada 3 file di URL Link sini: Kode Isi 3 File,
maka masalah ini kita mengidentifikasi beberapa potensi penyebab mengapa bidak dalam permainan Catur Nine belum dapat digerakkan:
-
Inisialisasi Papan dan Posisi Bidak:
- Pastikan bahwa fungsi
initialize_board()
telah dipanggil dengan benar dan bahwa variabelboard_state
telah diinisialisasi dengan posisi bidak yang sesuai.
- Pastikan bahwa fungsi
-
Penanganan Klik dan Pemilihan Bidak:
- Fungsi
handle_click(position)
- Pastikan bahwa logika untuk memilih dan memindahkan bidak telah diimplementasikan dengan benar, termasuk validasi giliran pemain dan jenis bidak yang dipilih.
- Fungsi
-
Validasi Gerakan:
- Fungsi
is_valid_move(selected_piece, from_position, to_position)
harus mengembalikan nilaiTrue
untuk gerakan yang sah danFalse
- Pastikan bahwa aturan gerakan untuk setiap jenis bidak, termasuk bidak khusus seperti "garuda", telah diimplementasikan dengan benar.
- Fungsi
-
Pembaruan Status Papan:
- Setelah gerakan divalidasi, fungsi
move_piece(piece, from_position, to_position)
harus memperbaruiboard_state
dengan posisi baru bidak yang dipindahkan.
- Setelah gerakan divalidasi, fungsi
-
Penggantian Giliran Pemain:
- Fungsi
switch_turn()
harus memastikan bahwa giliran pemain berganti setelah setiap gerakan yang valid.
- Fungsi
-
Pemilihan Formasi:
- Pastikan bahwa formasi yang dipilih oleh pemain (misalnya, 2 Garuda, 1 Kuda) telah diimplementasikan dengan benar dan bidak ditempatkan sesuai dengan formasi yang dipilih.
-
Pemrosesan Acara Pygame:
- Pastikan bahwa loop utama permainan memproses acara Pygame dengan benar, termasuk acara
MOUSEBUTTONDOWN
untuk mendeteksi klik mouse.
- Pastikan bahwa loop utama permainan memproses acara Pygame dengan benar, termasuk acara
Jika setelah memeriksa poin-poin di atas bidak masih belum dapat digerakkan, pertimbangkan untuk menambahkan pernyataan debug (seperti print()
) di berbagai bagian kode untuk melacak alur eksekusi dan memastikan bahwa setiap fungsi bekerja sesuai yang diharapkan.
Selain itu, pastikan bahwa semua gambar bidak telah dimuat dengan benar dan ditampilkan di posisi yang sesuai pada papan catur.
... selected_formation
MEMANGGIL PILIHAN FORMASI
---
load_pieces() # Memuat gambar bidak
# **Memilih formasi bidak putih sebelum memulai permainan**
chosen_white_formation = choose_white_formation()
# **Menentukan formasi bidak hitam sesuai pilihan putih**
if chosen_white_formation == formasi_1_white:
chosen_black_formation = formasi_1_black
else:
chosen_black_formation = formasi_2_black
# **Menggabungkan formasi dengan posisi default**
STARTING_POSITIONS = {**default_position, **chosen_white_formation, **chosen_black_formation}
---
Kode ini akan menampilkan layar pemilihan formasi sebelum permainan dimulai, lalu memulai permainan dengan formasi yang dipilih oleh pemain putih dan hitam.
Kode ini merupakan bagian dari inisialisasi permainan catur dengan Pygame. Kode ini sebaiknya diletakkan di bagian main loop permainan, tepat sebelum loop while running
.
Tempat yang Tepat dalam File
-
Di dalam file utama permainan
Jika Anda memiliki file utama sepertimain.py
, kode ini sebaiknya diletakkan setelah semua import, inisialisasi pygame, dan fungsi yang diperlukan. -
Sebelum loop utama permainan (
while running:
)
Kode ini berfungsi untuk memilih formasi bidak sebelum permainan dimulai, sehingga harus ditempatkan di atas loop utama agar variabelSTARTING_POSITIONS
sudah siap digunakan.
Contoh Penempatan dalam File main.py
Misalnya, jika file utama Anda bernama main.py
, letakkan kode ini setelah mendefinisikan semua variabel dan fungsi utama:
import pygame
import sys
from formations import choose_white_formation, formasi_1_white, formasi_1_black, formasi_2_black
from board import draw_board, draw_pieces
from timer import draw_timer
pygame.init()
screen = pygame.display.set_mode((800, 800))
WHITE = (255, 255, 255)
# **Memilih formasi bidak putih sebelum memulai permainan**
chosen_white_formation = choose_white_formation()
# **Menentukan formasi bidak hitam sesuai pilihan putih**
if chosen_white_formation == formasi_1_white:
chosen_black_formation = formasi_1_black
else:
chosen_black_formation = formasi_2_black
# **Menggabungkan formasi dengan posisi default**
default_position = {} # Pastikan ini sudah didefinisikan sebelumnya
STARTING_POSITIONS = {**default_position, **chosen_white_formation, **chosen_black_formation}
# **Loop utama permainan**
running = True
while running:
screen.fill(WHITE) # Bersihkan layar
draw_board() # Gambar papan
draw_pieces(STARTING_POSITIONS) # Gambar bidak
draw_timer() # Gambar timer
pygame.display.flip() # Perbarui layar
# **Event handler**
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
sys.exit()
Kesimpulan
- Letakkan kode ini sebelum loop utama permainan (
while running:
). - Pastikan semua variabel yang digunakan sudah didefinisikan.
- Jika menggunakan file terpisah untuk formasi (
formations.py
), pastikan sudah di-import di awal file.
Comments
Post a Comment