import pygame
import sys
import os
# Инициализация
pygame.init()
WIDTH, HEIGHT = 600, 600
BOARD_SIZE = 8
SQUARE_SIZE = WIDTH // BOARD_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Шахматы с картинками (2 игрока)")
# Цвета доски
LIGHT_SQ = (240, 217, 181)
DARK_SQ = (181, 136, 99)
SELECTED_COLOR = (130, 151, 105)
# Кодировка фигур: первая буква - цвет (b/w), вторая - тип (R, N, B, Q, K, P)
initial_board = [
["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
["bP", "bP", "bP", "bP", "bP", "bP", "bP", "bP"],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["", "", "", "", "", "", "", ""],
["wP", "wP", "wP", "wP", "wP", "wP", "wP", "wP"],
["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]
]
# Словарь для хранения загруженных картинок
IMAGES = {}
def load_images():
"""Загрузка картинок из папки images и их масштабирование под размер клетки"""
pieces = ["wP", "wR", "wN", "wB", "wQ", "wK", "bP", "bR", "bN", "bB", "bQ", "bK"]
for piece in pieces:
path = os.path.join("images", f"{piece}.png")
if os.path.exists(path):
# Загружаем и масштабируем до размеров SQUARE_SIZE x SQUARE_SIZE
IMAGES[piece] = pygame.transform.scale(
pygame.image.load(path).convert_alpha(),
(SQUARE_SIZE, SQUARE_SIZE)
)
else:
print(f"Предупреждение: Файл {path} не найден! Вместо него будет текст.")
def draw_board(selected_sq):
"""Отрисовка доски, выделения и фигур"""
for r in range(BOARD_SIZE):
for c in range(BOARD_SIZE):
# Определяем цвет клетки
color = LIGHT_SQ if (r + c) % 2 == 0 else DARK_SQ
if selected_sq == (r, c):
color = SELECTED_COLOR
# Рисуем клетку
pygame.draw.rect(screen, color, (c * SQUARE_SIZE, r * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
# Рисуем фигуру
piece = initial_board[r][c]
if piece:
if piece in IMAGES:
# Если картинка успешно загружена — выводим её
screen.blit(IMAGES[piece], (c * SQUARE_SIZE, r * SQUARE_SIZE))
else:
# Запасной текстовый вариант на случай отсутствия картинки
font = pygame.font.SysFont("Arial", 16, bold=True)
text_color = (0, 0, 0) if piece.startswith("w") else (255, 0, 0)
text = font.render(piece, True, text_color)
screen.blit(text, (c * SQUARE_SIZE + 20, r * SQUARE_SIZE + 25))
def main():
load_images() # Загружаем картинки перед стартом цикла
selected_square = None
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
col = x // SQUARE_SIZE
row = y // SQUARE_SIZE
if selected_square is None:
# Клик 1: Выбираем фигуру
if initial_board[row][col] != "":
selected_square = (row, col)
else:
# Клик 2: Перемещаем фигуру
prev_row, prev_col = selected_square
if (prev_row, prev_col) != (row, col):
initial_board[row][col] = initial_board[prev_row][prev_col]
initial_board[prev_row][prev_col] = ""
selected_square = None
draw_board(selected_square)
pygame.display.flip()
clock.tick(60)
if __name__ == "__main__":
main()
///////////////
import sys
BOARD_SIZE = 8
def parse_board(board_str):
"""Превращает строку из 64 элементов в матрицу 8х8"""
elements = board_str.split(",")
return [elements[i*8:(i+1)*8] for i in range(BOARD_SIZE)]
def serialize_board(matrix):
"""Превращает матрицу 8х8 обратно в плоскую строку"""
flat = []
for row in matrix:
flat.extend(row)
return ",".join(flat)
def validate_and_move(board, start_r, start_c, end_r, end_c):
"""
Базовая валидация ходов.
Возвращает (True, новая_матрица) или (False, "описание ошибки")
"""
piece = board[start_r][start_c]
target = board[end_r][end_c]
if not piece:
return False, "Начальная клетка пуста."
# Проверяем, что не бьем фигуру того же цвета (w - белые, b - черные)
if target and target[0] == piece[0]:
return False, "Нельзя брать фигуру своего цвета."
piece_type = piece[1] # 'P' (пешка), 'R' (ладья), 'N' (конь) и т.д.
# --- Логика для Ладьи (R) ---
if piece_type == "R":
if start_r != end_r and start_c != end_c:
return False, "Ладья ходит только по прямым линиям."
# --- Логика для Пешки (P) ---
elif piece_type == "P":
direction = -1 if piece.startswith("w") else 1 # Белые вверх, черные вниз
# Обычный ход на 1 клетку вперед
if start_c == end_c and end_r == start_r + direction and not target:
pass
# Взятие по диагонали на 1 клетку
elif abs(start_c - end_c) == 1 and end_r == start_r + direction and target:
pass
else:
return False, "Неверный ход пешкой."
# Если проверка пройдена, делаем ход
board[end_r][end_c] = piece
board[start_r][start_c] = ""
return True, board
def main():
# Проверяем аргументы командной строки
if len(sys.argv) < 3:
print("ERROR: Передайте доску и ход.")
sys.exit(1)
board_str = sys.argv[1]
move_str = sys.argv[2]
try:
# Парсим координаты (например, "6050" -> старт (6,0), финиш (5,0))
start_r = int(move_str[0])
start_c = int(move_str[1])
end_r = int(move_str[2])
end_c = int(move_str[3])
board = parse_board(board_str)
success, result = validate_and_move(board, start_r, start_c, end_r, end_c)
if success:
print(serialize_board(result))
else:
print(f"ERROR: {result}")
except Exception as e:
print(f"ERROR: Ошибка в работе движка: {str(e)}")
if __name__ == "__main__":
main()
//////////////////////////
import pygame
import sys
import subprocess
pygame.init()
WIDTH, HEIGHT = 600, 650 # Добавили 50px снизу для вывода ошибок
BOARD_SIZE = 8
SQUARE_SIZE = WIDTH // BOARD_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Шахматный GUI (Вызов внешнего движка)")
LIGHT_SQ = (240, 217, 181)
DARK_SQ = (181, 136, 99)
SELECTED_COLOR = (130, 151, 105)
# Стартовое состояние в виде плоской строки из 64 элементов
board_state = [
"bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR",
"bP", "bP", "bP", "bP", "bP", "bP", "bP", "bP",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"wP", "wP", "wP", "wP", "wP", "wP", "wP", "wP",
"wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"
]
def draw_board(selected_sq, error_msg=""):
screen.fill((200, 200, 200)) # Фон для панели ошибок
# Рисуем доску и фигуры
for r in range(BOARD_SIZE):
for c in range(BOARD_SIZE):
color = LIGHT_SQ if (r + c) % 2 == 0 else DARK_SQ
if selected_sq == (r, c):
color = SELECTED_COLOR
pygame.draw.rect(screen, color, (c * SQUARE_SIZE, r * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
piece = board_state[r * 8 + c]
if piece:
font = pygame.font.SysFont("Arial", 22, bold=True)
# Белые фигуры — синие, Черные — красные (для наглядности без картинок)
text_color = (0, 50, 150) if piece.startswith("w") else (150, 0, 0)
text = font.render(piece, True, text_color)
text_rect = text.get_rect(center=(c * SQUARE_SIZE + SQUARE_SIZE//2, r * SQUARE_SIZE + SQUARE_SIZE//2))
screen.blit(text, text_rect)
# Вывод сообщения об ошибке в нижнюю панель
if error_msg:
font_err = pygame.font.SysFont("Arial", 16, bold=True)
text_err = font_err.render(error_msg, True, (200, 0, 0))
screen.blit(text_err, (15, WIDTH + 15))
def send_to_engine(current_board, move_str):
"""Вызывает скрипт chess_engine.py через подпроцесс ОС"""
board_arg = ",".join(current_board)
# Выполняем команду: python chess_engine.py [доска] [ход]
result = subprocess.run(
[sys.executable, "chess_engine.py", board_arg, move_str],
capture_output=True,
text=True,
encoding="utf-8"
)
return result.stdout.strip()
def main():
global board_state
selected_square = None
error_message = ""
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
# Игнорируем клики на нижней панели ошибок
if y >= WIDTH:
continue
col = x // SQUARE_SIZE
row = y // SQUARE_SIZE
if selected_square is None:
# Клик 1: Выбираем фигуру
if board_state[row * 8 + col] != "":
selected_square = (row, col)
error_message = "" # Сброс старой ошибки
else:
# Клик 2: Делаем ход
prev_row, prev_col = selected_square
if (prev_row, prev_col) != (row, col):
# Формируем строку аргумента хода, например "6050"
move_str = f"{prev_row}{prev_col}{row}{col}"
# Запрос к движку
engine_response = send_to_engine(board_state, move_str)
if engine_response.startswith("ERROR:"):
error_message = engine_response
else:
# Если всё ок, движок вернул новую строку доски — обновляем её
board_state = engine_response.split(",")
selected_square = None
draw_board(selected_square, error_message)
pygame.display.flip()
clock.tick(60)
if __name__ == "__main__":
main()
Комментариев нет:
Отправить комментарий