OpenWorldChess/chess_open_world.py
2025-01-31 21:15:13 +03:00

729 lines
32 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pygame
import sys
import random
import time
pygame.init()
# --- ПАРАМЕТРЫ ПОЛЯ ---
CELL_SIZE = 32
GRID_WIDTH = 30
GRID_HEIGHT = 30
WINDOW_WIDTH = CELL_SIZE * GRID_WIDTH
WINDOW_HEIGHT = CELL_SIZE * GRID_HEIGHT
# --- ЦВЕТА ---
COLOR_BG = (30, 30, 30)
COLOR_GRID = (50, 50, 50)
COLOR_FOG = (20, 20, 20)
COLOR_SELECTED = (255, 0, 0)
COLOR_MOVE = (0, 255, 0)
COLOR_WHITE_PIECE = (255, 255, 255) # Заливка белых фигур
COLOR_BLACK_PIECE = (0, 0, 0) # Заливка чёрных фигур
# Новые цвета для бонусов
COLOR_REGEN = (0, 255, 0) # Зелёный
COLOR_HP_UPGRADE = (0, 128, 255) # Синий
COLOR_DAMAGE = (255, 0, 0) # Красный
COLOR_KING_HP_UPGRADE = (255, 215, 0) # Золотой
COLOR_ADD_PIECE = (255, 255, 255) # Белый (с плюсом)
COLOR_ADD_PIECE_PINK = (255, 192, 203) # Розовый
# Цвет текущего хода
COLOR_TURN_TEXT = (255, 255, 255) # Белый
# Новый цвет для пометки клеток, которые скоро уйдут в туман войны
COLOR_PRE_FOG = (169, 169, 169) # Светло-серый
# Цвет таймера
COLOR_TIMER_NORMAL = (255, 255, 255) # Белый
COLOR_TIMER_WARNING = (255, 0, 0) # Красный
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Шахматы с открытым миром 1.0")
# Шрифты
font = pygame.font.SysFont(None, CELL_SIZE // 2)
victory_font = pygame.font.SysFont(None, 60)
turn_font = pygame.font.SysFont(None, 30)
counter_font = pygame.font.SysFont(None, 30)
timer_font = pygame.font.SysFont(None, 25)
# --- Глобальное множество открытых клеток (туман войны) ---
global_revealed = set()
# --- Словарь символов ---
piece_symbols = {
'rook': 'Л',
'knight': 'К',
'bishop': 'С',
'queen': 'Ф',
'king': 'К', # Король (можно заменить на 'K' или другой символ)
'pawn': 'П'
}
# === МЕХАНИКА БОНУСОВ ===
# Храним в глобальном словаре bonus_cells: {(x,y): {'type': ...}}
bonus_cells = {}
# Вероятности появления различных типов бонусов
base_bonus_probabilities = {
'regen': 0.42, # 42%
'hp_upgrade': 0.32, # 32%
'damage': 0.2, # 20%
'king_hp_upgrade': 0.05, # 5%
'add_piece': 0.01 # 1%
}
bonus_probabilities = base_bonus_probabilities.copy()
# Функция для выбора бонуса на основе вероятностей
def choose_bonus_type():
rand = random.random()
cumulative = 0
for bonus_type, prob in bonus_probabilities.items():
cumulative += prob
if rand < cumulative:
return bonus_type
return 'regen' # По умолчанию
# === МЕХАНИКА БОЯ ===
def resolve_combat(attacker, defender):
"""
Атакующая фигура (A) идёт на клетку защитника (B).
HP(A)=a, HP(B)=b.
- Если a < b: B теряет a (b := b-a), A погибает.
- Если a > b: A теряет b (a := a-b), B погибает.
- Если a == b: A побеждает, убивает B, а у A остаётся 1 HP.
Возвращаем кортеж: (attacker_alive, defender_alive)
при этом изменяем HP в самих объектах.
"""
a = attacker.hp
b = defender.hp
if a < b:
# Защитник теряет a HP
defender.hp = b - a
# Атакующая погибает
attacker.hp = 0
return (False, True)
elif a > b:
# Атакующая теряет b HP
attacker.hp = a - b
# Защитник погибает
defender.hp = 0
return (True, False)
else:
# a == b
# Атакующая побеждает, остаётся с 1 HP
attacker.hp = 1
defender.hp = 0
return (True, False)
# === КЛАСС ФИГУРЫ ===
class Piece:
def __init__(self, name, color, x, y):
self.name = name
self.color = color # 'white' или 'black'
self.x = x
self.y = y
self.selected = False
# Инициализация HP
if self.name == 'king':
self.max_hp = 5
self.hp = 5
elif self.name in ['rook', 'knight', 'bishop', 'queen']:
self.max_hp = 3
self.hp = 3
elif self.name == 'pawn':
self.max_hp = 1
self.hp = 1
def get_possible_moves(self, pieces):
moves = []
if self.name == 'pawn':
directions = [
(-1,-1), (0,-1), (1,-1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
]
for dx, dy in directions:
nx = self.x + dx
ny = self.y + dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
# Можем ходить, если клетка пуста или там враг
if not blocking or blocking.color != self.color:
moves.append((nx, ny))
elif self.name in ['rook', 'bishop', 'queen']:
# Ограничиваем движение до 3 клеток
if self.name == 'rook':
directions = [(-1,0),(1,0),(0,-1),(0,1)]
elif self.name == 'bishop':
directions = [(-1,-1),(1,-1),(1,1),(-1,1)]
elif self.name == 'queen':
directions = [
(-1,0),(1,0),(0,-1),(0,1),
(-1,-1),(1,-1),(1,1),(-1,1)
]
for dx, dy in directions:
for step in range(1, 4): # До 3 клеток
nx = self.x + dx * step
ny = self.y + dy * step
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
if blocking:
if blocking.color != self.color:
moves.append((nx, ny))
break
moves.append((nx, ny))
else:
break
elif self.name == 'knight':
deltas = [(-2,-1),(-1,-2),(1,-2),(2,-1),
(2,1),(1,2),(-1,2),(-2,1)]
for dx, dy in deltas:
nx, ny = self.x+dx, self.y+dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
if not blocking or blocking.color != self.color:
moves.append((nx, ny))
elif self.name == 'king':
directions = [
(-1,0),(1,0),(0,-1),(0,1),
(-1,-1),(1,-1),(1,1),(-1,1)
]
for dx, dy in directions:
nx, ny = self.x+dx, self.y+dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
blocking = next((p for p in pieces if p.x == nx and p.y == ny), None)
if not blocking or blocking.color != self.color:
moves.append((nx, ny))
return moves
# --- Инициализация фигур ---
def initialize_pieces():
"""Чёрные: y=2(back), y=3(pawns). Белые: y=27(back), y=26(pawns)."""
pieces = []
cx = GRID_WIDTH//2
# ЧЁРНЫЕ
black_back = ['rook','knight','bishop','king','queen','bishop','knight','rook']
for i,pname in enumerate(black_back):
x = cx - 3 + i
y = 2
pieces.append(Piece(pname,'black',x,y))
for i in range(8):
x = cx-3 + i
y = 3
pieces.append(Piece('pawn','black',x,y))
# БЕЛЫЕ
white_back = ['rook','knight','bishop','king','queen','bishop','knight','rook']
for i,pname in enumerate(white_back):
x = cx - 3 + i
y = 27
pieces.append(Piece(pname,'white',x,y))
for i in range(8):
x = cx-3 + i
y = 26
pieces.append(Piece('pawn','white',x,y))
return pieces
# Инициализация фигур
pieces = initialize_pieces()
# Remove initial bonus cell generation
# initialize_bonus_cells(pieces, num_each=10)
selected_piece = None
possible_moves = []
game_over = False
winner = None
# --- Туман войны ---
cell_counters = {} # {(x,y): turns_since_last_revealed}
BONUS_GENERATION_CHANCE = 0.1 # 10% шанс появления бонуса при повторном открытии
# --- Система ходов ---
current_turn = 'white' # Начинаем с белых
turn_count = 0
# --- Механика повышения вероятности красных полей ---
def update_bonus_probabilities():
global bonus_probabilities
if turn_count <= 100:
bonus_probabilities = base_bonus_probabilities.copy()
else:
# Calculate how much to increase 'damage' probability
extra_turns = turn_count - 100
# Let's say over the next 200 turns, it increases to 50%
max_extra = 200
increase_per_turn = (0.50 - base_bonus_probabilities['damage']) / max_extra
new_damage_prob = min(base_bonus_probabilities['damage'] + increase_per_turn * extra_turns, 0.50)
# Adjust other probabilities accordingly
remaining_prob = 1 - new_damage_prob
total_other_probs = sum(base_bonus_probabilities[bt] for bt in base_bonus_probabilities if bt != 'damage')
bonus_probabilities = {}
for bt, prob in base_bonus_probabilities.items():
if bt == 'damage':
bonus_probabilities[bt] = new_damage_prob
else:
bonus_probabilities[bt] = prob / total_other_probs * remaining_prob
# --- Механика времени на ход ---
TURN_TIME_LIMIT = 120 # seconds
timer_start_time = time.time()
timer_expired = False
player_timeouts = {'white': 0, 'black': 0}
def reset_timer():
global timer_start_time, timer_expired
timer_start_time = time.time()
timer_expired = False
def get_time_left():
elapsed = time.time() - timer_start_time
return max(0, TURN_TIME_LIMIT - int(elapsed))
def check_timer():
global timer_expired, game_over, winner
time_left = get_time_left()
if time_left <= 0 and not timer_expired:
timer_expired = True
player_timeouts[current_turn] += 1
if player_timeouts[current_turn] >= 2:
# Opponent wins
winner = 'black' if current_turn == 'white' else 'white'
game_over = True
else:
# Switch turn
switch_turn()
def switch_turn():
global current_turn, turn_count, timer_expired
current_turn = 'black' if current_turn == 'white' else 'white'
turn_count += 1
reset_timer()
timer_expired = False
update_bonus_probabilities()
def update_fog():
"""
Обновляет туман войны:
- Открытые клетки остаются открытыми.
- Закрытые клетки, которые не находятся рядом с любыми фигурами на расстоянии 2 клеток,
становятся закрытыми через 5 ходов.
- При повторном открытии клетки шанс на появление нового бонуса.
"""
global global_revealed, bonus_cells
# Сохраняем предыдущее состояние открытых клеток
previous_revealed = global_revealed.copy()
# Определяем все открытые клетки на основе позиций фигур
new_revealed = set()
for p in pieces:
for dx in range(-2, 3):
for dy in range(-2, 3):
nx = p.x + dx
ny = p.y + dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
new_revealed.add((nx, ny))
# Определяем только новые открытые клетки
newly_revealed = new_revealed - previous_revealed
# Обрабатываем все клетки
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pos = (x, y)
if pos in new_revealed:
# Если клетка видна, сбрасываем счетчик
cell_counters[pos] = 0
global_revealed.add(pos)
else:
# Если клетка не видна, увеличиваем счетчик
if pos in cell_counters:
cell_counters[pos] += 1
else:
cell_counters[pos] = 1
# Если счетчик достигает 5, закрываем клетку
if cell_counters[pos] >= 5:
if pos in global_revealed:
global_revealed.remove(pos)
# Удаляем бонус, если клетка закрывается и бонус не является 'damage'
if pos in bonus_cells and bonus_cells[pos]['type'] != 'damage':
del bonus_cells[pos]
# Генерируем бонусы только на новых открытых клетках
for pos in newly_revealed:
if pos not in bonus_cells and random.random() < BONUS_GENERATION_CHANCE:
bonus_type = choose_bonus_type()
# Проверяем, чтобы бонус не был под фигурой
if not any(p.x == pos[0] and p.y == pos[1] for p in pieces):
bonus_cells[pos] = {'type': bonus_type}
def draw_grid():
for x in range(0, WINDOW_WIDTH, CELL_SIZE):
pygame.draw.line(screen, COLOR_GRID, (x, 0), (x, WINDOW_HEIGHT))
for y in range(0, WINDOW_HEIGHT, CELL_SIZE):
pygame.draw.line(screen, COLOR_GRID, (0, y), (WINDOW_WIDTH, y))
def draw_fog():
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pos = (x, y)
if pos not in global_revealed:
rect = pygame.Rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, COLOR_FOG, rect)
else:
# Проверяем, будет ли клетка закрыта в следующем ходу
if cell_counters.get(pos, 0) == 4:
# Помечаем клетку светло-серым
rect = pygame.Rect(x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, COLOR_PRE_FOG, rect)
def draw_bonus_cells():
"""
Отрисовка бонусов (если клетка открыта или бонус типа 'damage').
Цвета:
- 'regen': (0,255,0) зелёный
- 'hp_upgrade': (0,128,255) синий
- 'damage': (255,0,0) красный
- 'king_hp_upgrade': (255,215,0) золотой
- 'add_piece': (255,255,255) белый с плюсом или розовый
"""
for (bx, by), info in bonus_cells.items():
# Для 'damage' бонусов отображаем всегда, иначе только если клетка видна
if info['type'] != 'damage' and (bx, by) not in global_revealed:
continue
cx = bx*CELL_SIZE + CELL_SIZE//2
cy = by*CELL_SIZE + CELL_SIZE//2
bonus_type = info['type']
if bonus_type == 'regen':
color = COLOR_REGEN
pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE//4)
elif bonus_type == 'hp_upgrade':
color = COLOR_HP_UPGRADE
pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE//4)
elif bonus_type == 'damage':
color = COLOR_DAMAGE
pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE//4)
elif bonus_type == 'king_hp_upgrade':
color = COLOR_KING_HP_UPGRADE
pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE//4)
elif bonus_type == 'add_piece':
# Проверяем, возможно ли добавить фигуру рядом
possible = False
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1), (-1,-1),(1,-1),(1,1),(-1,1)]:
nx = bx + dx
ny = by + dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
if not any(p.x == nx and p.y == ny for p in pieces):
possible = True
break
color = COLOR_ADD_PIECE if possible else COLOR_ADD_PIECE_PINK
pygame.draw.circle(screen, color, (cx, cy), CELL_SIZE//4)
# Рисуем плюс
pygame.draw.line(screen, (0,0,0), (cx - CELL_SIZE//8, cy), (cx + CELL_SIZE//8, cy), 2)
pygame.draw.line(screen, (0,0,0), (cx, cy - CELL_SIZE//8), (cx, cy + CELL_SIZE//8), 2)
def draw_pieces(pieces):
"""Рисуем фигуры, их HP и подсвечиваем ходы."""
for p in pieces:
rect = pygame.Rect(p.x*CELL_SIZE, p.y*CELL_SIZE, CELL_SIZE, CELL_SIZE)
if p.color == 'white':
pygame.draw.rect(screen, COLOR_WHITE_PIECE, rect)
symbol = piece_symbols.get(p.name,'?')
text = font.render(symbol, True, (255,0,0))
text_rect = text.get_rect(center=rect.center)
screen.blit(text, text_rect)
# HP чёрным
hp_str = f"{p.hp}/{p.max_hp}"
hp_text = font.render(hp_str, True, (0,0,0))
screen.blit(hp_text, (rect.x+2, rect.y+2))
else:
pygame.draw.rect(screen, COLOR_BLACK_PIECE, rect)
symbol = piece_symbols.get(p.name,'?')
text = font.render(symbol, True, (255,0,0))
text_rect = text.get_rect(center=rect.center)
screen.blit(text, text_rect)
# HP белым
hp_str = f"{p.hp}/{p.max_hp}"
hp_text = font.render(hp_str, True, (255,255,255))
screen.blit(hp_text, (rect.x+2, rect.y+2))
if p.selected:
pygame.draw.rect(screen, COLOR_SELECTED, rect, 2)
for (mx, my) in possible_moves:
r = pygame.Rect(mx*CELL_SIZE, my*CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, COLOR_MOVE, r, 2)
def display_victory(winner):
text = victory_font.render(f"{winner.capitalize()} победил!", True, (255, 255, 255))
text_rect = text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2))
screen.blit(text, text_rect)
def display_turn(current_turn):
text = turn_font.render(f"Текущий ход: {current_turn.capitalize()}", True, COLOR_TURN_TEXT)
screen.blit(text, (10, WINDOW_HEIGHT - 30))
def display_turn_counter():
global turn_count
if turn_count < 100:
color = (255, 255, 255)
else:
color = (255, 0, 0)
text = counter_font.render(f"Ход: {turn_count}", True, color)
text_rect = text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT - 15))
screen.blit(text, text_rect)
def display_timer():
time_left = get_time_left()
minutes = time_left // 60
seconds = time_left % 60
timer_text = f"{minutes:02}:{seconds:02}"
if timer_expired and player_timeouts[current_turn] >=1:
color = COLOR_TIMER_WARNING
else:
color = COLOR_TIMER_NORMAL
text = timer_font.render(timer_text, True, color)
text_rect = text.get_rect(bottomright=(WINDOW_WIDTH - 10, WINDOW_HEIGHT - 10))
screen.blit(text, text_rect)
def apply_bonus(piece, bonus_type, pieces):
"""Применяем эффект бонуса к фигуре piece в зависимости от типа."""
if bonus_type == 'regen':
# Регенерация (1..2) для НЕ короля
if piece.name != 'king':
amt = random.randint(1, 2)
piece.hp = min(piece.hp + amt, piece.max_hp)
elif bonus_type == 'hp_upgrade':
# Повышение max_hp только НЕ королю без восстановления HP
if piece.name != 'king':
piece.max_hp += 1
# piece.hp остается неизменным
elif bonus_type == 'king_hp_upgrade':
# Только для короля, бонус активируется другим игроком
if piece.name != 'king':
# Найти короля той же команды
king = next((p for p in pieces if p.name == 'king' and p.color == piece.color), None)
if king:
if king.hp == king.max_hp:
# Если король на полном здоровье,
# то увеличиваем max_hp на 1
king.max_hp += 1
king.hp = king.max_hp
else:
# Если король не на полном, то
# просто восстанавливаем HP до max
king.hp = min(king.hp + 1, king.max_hp)
elif bonus_type == 'damage':
# Нанесение урона (1..5)
damage = random.randint(1, 5)
piece.hp = max(piece.hp - damage, 0)
if piece.hp == 0:
# Удаляем фигуру, если HP равен 0
pieces.remove(piece)
if piece.name == 'king':
global winner, game_over
winner = 'black' if piece.color == 'white' else 'white'
game_over = True
elif bonus_type == 'add_piece':
# Добавление новой фигуры рядом, если возможно и не король
if piece.name != 'king':
# Определяем возможные соседние клетки
directions = [(-1,0),(1,0),(0,-1),(0,1), (-1,-1),(1,-1),(1,1),(-1,1)]
random.shuffle(directions)
for dx, dy in directions:
nx = piece.x + dx
ny = piece.y + dy
if 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:
# Проверяем, что клетка пуста
if not any(p.x == nx and p.y == ny for p in pieces) and (nx, ny) not in bonus_cells:
# Создаём новую фигуру того же типа
new_piece = Piece(piece.name, piece.color, nx, ny)
pieces.append(new_piece)
break
# Если не удалось разместить, бонус не активируется
# Инициализируем туман войны в начале игры
update_fog()
running = True
clock = pygame.time.Clock()
while running:
clock.tick(30)
check_timer()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN and not game_over:
mx, my = pygame.mouse.get_pos()
gx = mx // CELL_SIZE
gy = my // CELL_SIZE
clicked_piece = next((p for p in pieces if p.x == gx and p.y == gy), None)
if selected_piece:
if (gx, gy) in possible_moves:
# Проверяем бонус
if (gx, gy) in bonus_cells:
bonus_type = bonus_cells[(gx, gy)]['type']
apply_bonus(selected_piece, bonus_type, pieces)
del bonus_cells[(gx, gy)]
# Проверяем, есть ли там вражеская фигура
defender = next((p for p in pieces if p.x == gx and p.y == gy), None)
if defender:
# Проводим бой
attacker = selected_piece
attacker_alive, defender_alive = resolve_combat(attacker, defender)
if not defender_alive:
# Защитник погиб
if defender.name == 'king':
winner = attacker.color
game_over = True
pieces.remove(defender)
if not attacker_alive:
# Атакующая погибла
pieces.remove(attacker)
# Снимаем выделение
selected_piece = None
possible_moves.clear()
# После изменения позиций фигур обновляем туман войны
update_fog()
# Смена хода
switch_turn()
continue
else:
# Атакующая жива, перемещаем её
# Проверка прохождения через клетки (для длинных ходов)
path = []
if attacker.name in ['rook', 'bishop', 'queen']:
dx = gx - attacker.x
dy = gy - attacker.y
if dx != 0:
dx = dx // abs(dx)
if dy != 0:
dy = dy // abs(dy)
for step in range(1, max(abs(gx - attacker.x), abs(gy - attacker.y))):
path_x = attacker.x + dx * step
path_y = attacker.y + dy * step
path.append((path_x, path_y))
# Применяем урон при прохождении через клетки и удаляем 'damage' клетки
survived = True
for pos in path:
if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
damage = random.randint(1,5) # Исправлено на 1..5
attacker.hp = max(attacker.hp - damage, 0)
# Удаляем 'damage' клетку как использованную
del bonus_cells[pos]
if attacker.hp == 0:
pieces.remove(attacker)
selected_piece = None
possible_moves.clear()
survived = False
# Смена хода, так как игрок погиб
switch_turn()
break
if survived:
attacker.x = gx
attacker.y = gy
attacker.selected = False
selected_piece = None
possible_moves.clear()
# Смена хода
switch_turn()
else:
# Пустая клетка — просто ходим
# Проверка прохождения через клетки (для длинных ходов)
path = []
if selected_piece.name in ['rook', 'bishop', 'queen']:
dx = gx - selected_piece.x
dy = gy - selected_piece.y
if dx != 0:
dx = dx // abs(dx)
if dy != 0:
dy = dy // abs(dy)
for step in range(1, max(abs(gx - selected_piece.x), abs(gy - selected_piece.y))):
path_x = selected_piece.x + dx * step
path_y = selected_piece.y + dy * step
path.append((path_x, path_y))
# Применяем урон при прохождении через клетки и удаляем 'damage' клетки
survived = True
for pos in path:
if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
damage = random.randint(1,5) # Исправлено на 1..5
selected_piece.hp = max(selected_piece.hp - damage, 0)
# Удаляем 'damage' клетку как использованную
del bonus_cells[pos]
if selected_piece.hp == 0:
pieces.remove(selected_piece)
selected_piece = None
possible_moves.clear()
survived = False
# Смена хода, так как игрок погиб
switch_turn()
break
if survived:
selected_piece.x = gx
selected_piece.y = gy
selected_piece.selected = False
selected_piece = None
possible_moves.clear()
# Смена хода
switch_turn()
# После успешного хода обновляем туман войны
update_fog()
else:
# Клик вне возможных ходов
selected_piece.selected = False
selected_piece = None
possible_moves.clear()
else:
# Выбираем фигуру только если клетка видима и соответствует текущему ходу
if clicked_piece and (gx, gy) in global_revealed and clicked_piece.color == current_turn:
selected_piece = clicked_piece
selected_piece.selected = True
possible_moves = selected_piece.get_possible_moves(pieces)
# Отрисовка
screen.fill(COLOR_BG)
draw_grid()
draw_fog()
draw_bonus_cells()
draw_pieces(pieces)
if game_over and winner:
display_victory(winner)
else:
display_turn(current_turn)
display_turn_counter()
display_timer()
pygame.display.flip()
pygame.quit()
sys.exit()