Kode dari isi 2 buah file:
Kode dari isi 2 buah file:
1. 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")
print(f"Memuat gambar: {path}") # Debugging: cek path
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
else:
print(f"[ERROR] Gambar tidak ditemukan: {path}") # Debugging
# === FORMASI AWAL BIDAK ===
starting_position = {
"white": {
"rook": [(0, 8), (8, 8)],
"knight": [(2, 8), (7, 8)],
"bishop": [(3, 8), (6, 8)],
"queen": [(5, 8)],
"king": [(4, 8)],
"pawn": [(x, 7) for x in range(9)],
'garuda':[(1, 8)]
},
"black": {
"rook": [(0, 0), (8, 0)],
"knight": [(2, 0), (7, 0)],
"bishop": [(3, 0), (6, 0)],
"queen": [(5, 0)],
"king": [(4, 0)],
"pawn": [(x, 1) for x in range(9)],
'garuda':[(1, 0)]
},
}
# === 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))
# Fungsi Menggambar Bidak
def draw_pieces(starting_position):
"""Menggambar semua bidak di posisi awal"""
for color, pieces in starting_position.items(): # Iterasi warna
for piece, positions in pieces.items(): # Iterasi jenis bidak
if f"{color}_{piece}" in pieces_images: # Periksa apakah bidak ada dalam dictionary gambar
for pos in positions:
x, y = pos
screen.blit(pieces_images[f"{color}_{piece}"],
(BOARD_X + x * TILE_SIZE, BOARD_Y + y * TILE_SIZE))
else:
print(f"[ERROR] Gambar tidak ditemukan untuk {color}_{piece}") # Debugging
# === 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)
# === MULAI GAME ===
clock = pygame.time.Clock()
def main():
# Muat gambar bidak
load_pieces()
# starting_position
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)
# Jalankan permainan
if __name__ == "__main__":
main()
pygame.quit()
sys.exit()
2. Kode isi file: catur_nine_move.py
import pygame
import sys
# Ukuran papan 9x9
BOARD_SIZE = 9
# Posisi awal bidak
starting_position = {
"white": {
"rook": [(0, 8), (8, 8)],
"knight": [(1, 8), (7, 8)],
"bishop": [(3, 8), (6, 8)],
"queen": [(5, 8)],
"king": [(4, 8)],
"pawn": [(x, 7) for x in range(9)],
"garuda": [(2, 8)]
},
"black": {
"rook": [(0, 0), (8, 0)],
"knight": [(1, 0), (7, 0)],
"bishop": [(3, 0), (6, 0)],
"queen": [(5, 0)],
"king": [(4, 0)],
"pawn": [(x, 1) for x in range(9)],
"garuda": [(2, 0)]
},
}
# Menyimpan status papan
def initialize_board():
"""Menginisialisasi status papan dengan posisi awal bidak."""
board_state = {color: {piece: positions[:] for piece, positions in pieces.items()} for color, pieces in starting_position.items()}
return board_state
# Mendapatkan bidak di posisi tertentu
def get_piece_at(x, y, board_state):
"""Mengembalikan jenis bidak di posisi tertentu."""
for color, pieces in board_state.items():
for piece, positions in pieces.items():
if (x, y) in positions:
return color, piece
return None, None
# Mengecek apakah petak ditempati bidak sendiri atau lawan
def is_occupied(position, board_state):
"""Cek apakah petak ditempati oleh bidak."""
return any(position in positions for pieces in board_state.values() for positions in pieces.values())
def is_occupied_by_enemy(position, color, board_state):
"""Cek apakah petak ditempati bidak lawan."""
enemy_color = "black" if color == "white" else "white"
return any(position in positions for positions in board_state[enemy_color].values())
# Validasi gerakan bidak
def is_valid_move(piece, start, end, board_state, turn, last_move, castling_rights):
"""Validasi gerakan sesuai aturan masing-masing bidak."""
color, p_type = piece
x1, y1 = start
x2, y2 = end
if color != turn:
return False
# Jika petak tujuan ditempati bidak sendiri, langkah tidak sah
if is_occupied(end, board_state) and not is_occupied_by_enemy(end, color, board_state):
return False
# **1. Gerakan Pion**
if p_type == "pawn":
direction = -1 if color == "white" else 1
start_row = 7 if color == "white" else 1
if x1 == x2 and y2 - y1 == direction and not is_occupied(end, board_state):
return True
if x1 == x2 and y2 - y1 == 2 * direction and y1 == start_row and not is_occupied(end, board_state):
return True
if abs(x1 - x2) == 1 and y2 - y1 == direction and is_occupied_by_enemy(end, color, board_state):
return True
# En Passant
if last_move and last_move[2] == "pawn":
((lx1, ly1), (lx2, ly2), last_piece) = last_move
if abs(x1 - lx2) == 1 and y1 == ly2 and abs(ly1 - ly2) == 2:
return True
# **2. Gerakan Kuda**
elif p_type == "knight":
return (abs(x2 - x1), abs(y2 - y1)) in [(2, 1), (1, 2)]
# **3. Gerakan Benteng**
elif p_type == "rook":
return x1 == x2 or y1 == y2
# **4. Gerakan Gajah**
elif p_type == "bishop":
return abs(x2 - x1) == abs(y2 - y1)
# **5. Gerakan Ratu**
elif p_type == "queen":
return (x1 == x2 or y1 == y2) or (abs(x2 - x1) == abs(y2 - y1))
# **6. Gerakan Raja & Rokade**
elif p_type == "king":
if abs(x2 - x1) <= 1 and abs(y2 - y1) <= 1:
return True
if abs(x2 - x1) == 2 and y1 == y2 and castling_rights[color]:
return True
# **7. Gerakan Garuda**
elif p_type == "garuda":
dx = abs(x2 - x1)
dy = abs(y2 - y1)
return (dx == 2 and dy == 0) or (dx == 0 and dy == 2) or (dx == 2 and dy == 2)
return False
# Fungsi memindahkan bidak
def move_piece(piece, start, end, board_state, turn, last_move, castling_rights):
"""Memindahkan bidak ke posisi baru jika langkah sah."""
if not is_valid_move(piece, start, end, board_state, turn, last_move, castling_rights):
return False
x1, y1 = start
x2, y2 = end
# Hapus bidak dari posisi lama
board_state[turn][piece[1]].remove(start)
# Jika menangkap bidak lawan
captured_piece = get_piece_at(x2, y2, board_state)
if captured_piece[0] and captured_piece[0] != turn:
board_state[captured_piece[0]][captured_piece[1]].remove(end)
# Pindahkan bidak ke posisi baru
board_state[turn][piece[1]].append(end)
return True
# Periksa Skak
def is_king_in_check(turn, board_state):
"""Cek apakah raja sedang dalam keadaan skak."""
king_position = board_state[turn]["king"][0]
enemy_color = "black" if turn == "white" else "white"
for piece_type, positions in board_state[enemy_color].items():
for pos in positions:
if is_valid_move((enemy_color, piece_type), pos, king_position, board_state, enemy_color, None, None):
return True
return False
# Periksa Skakmat
def is_checkmate(turn, board_state):
"""Cek apakah raja dalam kondisi skakmat."""
if not is_king_in_check(turn, board_state):
return False
for piece_type, positions in board_state[turn].items():
for pos in positions:
for dx in range(-1, 2):
for dy in range(-1, 2):
new_pos = (pos[0] + dx, pos[1] + dy)
if is_valid_move((turn, piece_type), pos, new_pos, board_state, turn, None, None):
return False
return True
Comments
Post a Comment