Ver 1.1
This commit is contained in:
parent
d0fd828c39
commit
e0ba49f02e
182
README.md
182
README.md
@ -1,126 +1,144 @@
|
||||
# Шахматы с Открытым Миром (HP + Бонусы + Бой)
|
||||
# Шахматы с Открытым Миром 1.1
|
||||
|
||||
**Версия:** 1.5
|
||||
**Дата Обновления:** 2025-04-27
|
||||
Добро пожаловать в **Шахматы с Открытым Миром 1.1** – инновационную версию классической игры, обогащённую новыми механиками, бонусами и динамическим туманом войны. Погрузитесь в захватывающий мир стратегии, где каждое решение может изменить ход партии!
|
||||
|
||||
## Обзор
|
||||
## Содержание
|
||||
|
||||
**Шахматы с Открытым Миром (HP + Бонусы + Бой)** — это инновационная вариация классических шахмат, сочетающая в себе элементы RPG, такие как здоровье (HP) фигур, различные бонусы и боевые столкновения. Дополнительно в игре реализован механизм **тумана войны**, который добавляет стратегическую глубину и динамику игровому процессу.
|
||||
1. [Основные Правила](#основные-правила)
|
||||
2. [Механики Игры](#механики-игры)
|
||||
- [Туман Войны](#туман-войны)
|
||||
- [Бонусные Поля](#бонусные-поля)
|
||||
- [Бои и HP Фигур](#бои-и-hp-фигур)
|
||||
3. [Механика Времени](#механика-времени)
|
||||
4. [Процедурная Генерация Бонусов](#процедурная-генерация-бонусов)
|
||||
5. [Баланс Фигур](#баланс-фигур)
|
||||
6. [Обновления и Изменения](#обновления-и-изменения)
|
||||
|
||||
## Основные Особенности
|
||||
---
|
||||
|
||||
- **Здоровье (HP) Фигур:** Каждая фигура обладает текущим и максимальным здоровьем. Фигуры могут получать урон и восстанавливаться.
|
||||
- **Бонусные Клетки:** На игровом поле случайным образом появляются бонусы, которые могут повышать здоровье, наносить урон или предоставлять другие преимущества.
|
||||
- **Туман Войны:** Некоторые части игрового поля скрыты от игроков и открываются по мере продвижения фигур. Бонусы могут появляться как в видимых, так и в скрытых областях через механизм тумана войны.
|
||||
- **Бой:** При столкновении фигур происходит бой, исход которого зависит от их текущего здоровья.
|
||||
- **Смена Ходов:** Игра пошаговая. Белые ходят первыми, затем ходят чёрные.
|
||||
- **Победа:** Побеждает тот, чей король останется последним на поле.
|
||||
## Основные Правила
|
||||
|
||||
## Правила Игры
|
||||
**Шахматы с Открытым Миром** сохраняют основные принципы классической шахматной игры:
|
||||
|
||||
### 1. Цель Игры
|
||||
- **Фигуры и Расстановка**: Игра включает короля, ферзя, ладьи, слонов, коней и пешек для каждой стороны.
|
||||
- **Цель Игры**: Захватить короля противника.
|
||||
|
||||
Целью игры является уничтожение короля противника. Как только король одного из игроков погибает, игра завершается победой противоположного игрока.
|
||||
Однако, в этой версии добавлены уникальные механики, которые делают игру более динамичной и стратегически глубокой.
|
||||
|
||||
### 2. Здоровье Фигур
|
||||
---
|
||||
|
||||
- **Король:** Максимальное здоровье — 5 HP.
|
||||
- **Ладья, Конь, Слон, Ферзь:** Максимальное здоровье — 3 HP.
|
||||
- **Пешка:** Максимальное здоровье — 1 HP.
|
||||
## Механики Игры
|
||||
|
||||
Фигуры могут получать урон во время боя или при прохождении через специальные бонусные клетки. Если здоровье фигуры падает до 0, она удаляется с поля.
|
||||
### Туман Войны
|
||||
|
||||
### 3. Бонусные Клетки
|
||||
Туман войны добавляет элемент неопределённости на поле боя:
|
||||
|
||||
На игровом поле случайным образом генерируются бонусные клетки различных типов:
|
||||
- **Открытые и Закрытые Клетки**: Изначально большая часть поля скрыта. Клетки открываются, когда фигуры приближаются.
|
||||
- **Обновление Тумана**: Каждая клетка, не находящаяся в радиусе 2 клеток от любой фигуры, через 5 ходов становится закрытой.
|
||||
- **Предварительное Закрытие**: Клетки, которые скоро закроются, отмечаются светло-серым цветом.
|
||||
|
||||
- **`regen` (Регенерация):** Восстанавливает 1–2 HP выбранной фигуры (не короля).
|
||||
- **`hp_upgrade` (Повышение HP):** Увеличивает максимальное здоровье фигуры на 1 без восстановления текущего HP (не королю).
|
||||
- **`damage` (Урон):** Наносит случайный урон (0–5) фигуре, проходящей через клетку.
|
||||
- **`king_hp_upgrade` (Повышение HP Короля):** Повышает максимальное здоровье короля или восстанавливает его HP до максимума.
|
||||
- **`add_piece` (Добавление Фигуры):** Позволяет добавить новую фигуру того же типа рядом с текущей фигурой, если это возможно.
|
||||
### Бонусные Поля
|
||||
|
||||
**Важно:**
|
||||
Поле содержит специальные клетки, предоставляющие бонусы:
|
||||
|
||||
- При **начальной генерации** бонусы **не** появляются под стартовыми позициями фигур.
|
||||
- В дальнейшем бонусы могут появляться в **любых** свободных клетках, включая стартовые ряды, через механизм тумана войны.
|
||||
- **Типы Бонусов**:
|
||||
- **Регенерация (regen)**: Восстанавливает 1-2 HP фигуре (кроме короля).
|
||||
- **Повышение HP (hp_upgrade)**: Увеличивает максимальный HP фигуры на 1 (кроме короля).
|
||||
- **Урон (damage)**: Наносит 1-5 урона фигуре.
|
||||
- **Повышение HP Короля (king_hp_upgrade)**: Увеличивает или восстанавливает HP короля.
|
||||
- **Добавление Фигуры (add_piece)**: Добавляет новую фигуру рядом с текущей, если возможно.
|
||||
|
||||
### 4. Туман Войны
|
||||
- **Генерация Бонусов**:
|
||||
- Бонусные поля генерируются процедурно при выходе клеток из тумана войны.
|
||||
- Шанс появления бонуса составляет **10%** для каждой новой открытой клетки.
|
||||
- Тип бонуса определяется следующими вероятностями:
|
||||
- Регенерация: 42%
|
||||
- Повышение HP: 32%
|
||||
- Урон: 20%
|
||||
- Повышение HP Короля: 5%
|
||||
- Добавление Фигуры: 1%
|
||||
|
||||
- **Механика:**
|
||||
- Клетки, находящиеся в зоне видимости фигур (расстояние до 2 клеток), остаются открытыми.
|
||||
- Клетки, выходящие за пределы зоны видимости, скрываются под туманом войны через **5 ходов** после последнего обнаружения.
|
||||
- Перед закрытием клетки помечаются светло-серым цветом, указывая на предстоящее сокрытие.
|
||||
### Бои и HP Фигур
|
||||
|
||||
- **Бонусы через Туман Войны:**
|
||||
- При повторном открытии клеток через туман войны существует **10%** шанс появления нового бонуса, если клетка свободна и не занята фигурой.
|
||||
Каждая фигура имеет **HP (здоровье)**, определяющее её выживаемость:
|
||||
|
||||
### 5. Бой
|
||||
- **Инициализация HP**:
|
||||
- **Король**: 5 HP
|
||||
- **Ферзь, Ладья, Слон, Конь**: 3 HP
|
||||
- **Пешка**: 1 HP
|
||||
|
||||
Когда фигура перемещается на клетку, занятую вражеской фигурой, происходит бой:
|
||||
- **Взаимодействие Фигур**:
|
||||
- **Атака**: Когда фигура перемещается на клетку с вражеской фигурой, начинается бой.
|
||||
- **Исход Боя**:
|
||||
- Если HP атакующего меньше HP защитника: Защитник теряет HP атакующего, атакующий погибает.
|
||||
- Если HP атакующего больше HP защитника: Атакующий теряет HP защитника, защитник погибает.
|
||||
- Если HP равны: Атакующий остаётся с 1 HP, защитник погибает.
|
||||
|
||||
- **Исход боя:**
|
||||
- **Если HP атакующей < HP защитника:** Защитник теряет HP равный HP атакующей, атакующая погибает.
|
||||
- **Если HP атакующей > HP защитника:** Атакующая теряет HP равный HP защитника, защитник погибает.
|
||||
- **Если HP атакующей == HP защитника:** Атакующая побеждает, защитник погибает, а атакующая остается с 1 HP.
|
||||
- **Убийство Короля**: Захват короля противника завершает игру.
|
||||
|
||||
- **Примеры:**
|
||||
- **Атакующая (HP=2) vs Защитник (HP=3):** Защитник становится с HP=1, атакующая уничтожается.
|
||||
- **Атакующая (HP=4) vs Защитник (HP=2):** Атакующая остается с HP=2, защитник уничтожается.
|
||||
- **Атакующая (HP=3) vs Защитник (HP=3):** Защитник уничтожается, атакующая остается с HP=1.
|
||||
---
|
||||
|
||||
### 6. Специальные Бонусы
|
||||
## Механика Времени
|
||||
|
||||
- **`regen`:** Восстанавливает 1–2 HP выбранной фигуры (не короля).
|
||||
- **`hp_upgrade`:** Увеличивает максимальное здоровье фигуры на 1 без восстановления текущего HP (не королю).
|
||||
- **`king_hp_upgrade`:** Повышает максимальное здоровье короля или восстанавливает его HP до максимума.
|
||||
- **`damage`:** Наносит случайный урон (0–5) фигуре, проходящей через клетку.
|
||||
- **`add_piece`:** Позволяет добавить новую фигуру того же типа рядом с текущей фигурой, если это возможно.
|
||||
**Время на ход** добавляет дополнительное давление и стратегию в игру:
|
||||
|
||||
### 7. Смена Ходов
|
||||
- **Лимит Времени**: Каждый игрок имеет **2 минуты** на свой ход.
|
||||
- **Отсчёт Времени**:
|
||||
- Таймер отображается в правом нижнем углу.
|
||||
- При истечении времени, таймер становится красным.
|
||||
- **Повторный Пропуск**: Если игрок снова пропустит свой ход, он автоматически проигрывает.
|
||||
- **Переключение Хода**: После каждого хода время сбрасывается для следующего игрока.
|
||||
|
||||
Игра является пошаговой:
|
||||
---
|
||||
|
||||
1. **Ход Белых:**
|
||||
- Выбирается фигура белых, доступная для хода.
|
||||
- Выбирается возможная клетка для перемещения.
|
||||
- Выполняется перемещение и применяются эффекты бонусов/боя.
|
||||
## Процедурная Генерация Бонусов
|
||||
|
||||
2. **Ход Чёрных:**
|
||||
- Аналогично, выбирается фигура чёрных и выполняется ход.
|
||||
Бонусные поля генерируются динамически, делая каждую игру уникальной:
|
||||
|
||||
Смена хода происходит после завершения всех действий текущего игрока.
|
||||
- **Когда Генерируются Бонусы**:
|
||||
- При выходе клетки из тумана войны, с вероятностью **10%** может появиться бонусное поле.
|
||||
|
||||
### 8. Победа
|
||||
- **Тип Бонуса**:
|
||||
- Тип бонуса выбирается на основе текущих вероятностей.
|
||||
- После **100 ходов**, вероятность появления бонусов типа "урон" (красные поля) постепенно увеличивается до **50%**, делая игру более опасной.
|
||||
|
||||
Побеждает тот, чей король остаётся последним на поле. Игра завершается, когда король одного из игроков погибает.
|
||||
---
|
||||
|
||||
## Установка и Запуск
|
||||
## Баланс Фигур
|
||||
|
||||
### Требования
|
||||
Для поддержания баланса и динамики игры, движение некоторых фигур было изменено:
|
||||
|
||||
- **Python 3.x**
|
||||
- **Pygame** библиотека
|
||||
- **Ферзь и Ладья**:
|
||||
- **Ранее**: Могли перемещаться до **5 клеток** за ход.
|
||||
- **Сейчас**: Могут перемещаться до **3 клеток** за ход.
|
||||
|
||||
### Установка
|
||||
Это изменение делает игру более стратегичной, ограничивая возможности мощных фигур и стимулируя разнообразие тактик.
|
||||
|
||||
1. **Клонирование Репозитория:**
|
||||
---
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ваш-репозиторий/шахматы-с-открытым-миром.git
|
||||
```
|
||||
## Обновления и Изменения
|
||||
|
||||
2. **Установка Зависимостей:**
|
||||
### Версия 1.1
|
||||
|
||||
Убедитесь, что у вас установлен Python 3 и Pygame. Установить Pygame можно с помощью pip:
|
||||
1. **Баланс Красных Полей**:
|
||||
- **Урон**: Теперь красные поля наносят от **1 до 5 урона**, исключая возможность отсутствия урона.
|
||||
- **Исправление Бага**: При прохождении через красное поле и гибели фигуры, ход корректно переходит к противнику.
|
||||
|
||||
```bash
|
||||
pip install pygame
|
||||
```
|
||||
2. **Процедурная Генерация Бонусов**:
|
||||
- Бонусные поля теперь генерируются **процедурно** при выходе клеток из тумана войны.
|
||||
- **Вероятность Появления**: Каждая новая открытая клетка имеет **10%** шанс стать бонусной.
|
||||
- **Тип Бонуса**: Выбор типа бонуса осуществляется согласно текущим вероятностям.
|
||||
|
||||
### Запуск Игры
|
||||
3. **Баланс Фигур с Свободным Передвижением**:
|
||||
- **Ферзь и Ладья** теперь могут перемещаться до **3 клеток** вместо 5, обеспечивая более сбалансированную игру.
|
||||
|
||||
Перейдите в директорию с клонированным репозиторием и запустите игру:
|
||||
4. **Механика Повышения Вероятности Красных Полей**:
|
||||
- После **100 ходов**, вероятность появления бонусных полей типа "урон" постепенно увеличивается до **50%**.
|
||||
- **Отображение Ходов**: Внизу экрана отображается счётчик ходов. После 100 ходов счётчик становится красным, сигнализируя о начале увеличения опасности.
|
||||
|
||||
```bash
|
||||
python chess_game.py
|
||||
5. **Механика Времени на Ход**:
|
||||
- Каждый игрок имеет **2 минуты** на свой ход.
|
||||
- **Отображение Таймера**: Таймер находится в правом нижнем углу экрана.
|
||||
- **Переполнение Времени**:
|
||||
- При первом переполнении таймер становится красным.
|
||||
- При втором переполнении, игрок автоматически проигрывает.
|
||||
|
@ -1,6 +1,7 @@
|
||||
import pygame
|
||||
import sys
|
||||
import random
|
||||
import time
|
||||
|
||||
pygame.init()
|
||||
|
||||
@ -35,6 +36,10 @@ 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")
|
||||
|
||||
@ -42,6 +47,8 @@ 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()
|
||||
@ -61,7 +68,7 @@ piece_symbols = {
|
||||
bonus_cells = {}
|
||||
|
||||
# Вероятности появления различных типов бонусов
|
||||
bonus_probabilities = {
|
||||
base_bonus_probabilities = {
|
||||
'regen': 0.42, # 42%
|
||||
'hp_upgrade': 0.32, # 32%
|
||||
'damage': 0.2, # 20%
|
||||
@ -69,6 +76,8 @@ bonus_probabilities = {
|
||||
'add_piece': 0.01 # 1%
|
||||
}
|
||||
|
||||
bonus_probabilities = base_bonus_probabilities.copy()
|
||||
|
||||
# Функция для выбора бонуса на основе вероятностей
|
||||
def choose_bonus_type():
|
||||
rand = random.random()
|
||||
@ -79,87 +88,6 @@ def choose_bonus_type():
|
||||
return bonus_type
|
||||
return 'regen' # По умолчанию
|
||||
|
||||
def initialize_bonus_cells(pieces, num_each=10):
|
||||
"""
|
||||
Создаём случайно бонусных клеток.
|
||||
Включает три типа изначально: 'hp_upgrade', 'regen', 'king_hp_upgrade'.
|
||||
Бонусы не размещаются под стартовыми позициями фигур.
|
||||
"""
|
||||
global bonus_cells
|
||||
all_positions = [(x, y) for x in range(GRID_WIDTH) for y in range(GRID_HEIGHT)]
|
||||
random.shuffle(all_positions)
|
||||
i_pos = 0
|
||||
types = ['hp_upgrade', 'regen', 'king_hp_upgrade']
|
||||
for t in types:
|
||||
for _ in range(num_each):
|
||||
while i_pos < len(all_positions):
|
||||
(xx, yy) = all_positions[i_pos]
|
||||
i_pos += 1
|
||||
# Проверка, чтобы клетка не занята фигурой
|
||||
if not any(p.x == xx and p.y == yy for p in pieces):
|
||||
bonus_cells[(xx, yy)] = {'type': t}
|
||||
break
|
||||
|
||||
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':
|
||||
# Нанесение урона (0..5)
|
||||
damage = random.randint(0, 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
|
||||
# Если не удалось разместить, бонус не активируется
|
||||
|
||||
# === МЕХАНИКА БОЯ ===
|
||||
def resolve_combat(attacker, defender):
|
||||
"""
|
||||
@ -233,7 +161,7 @@ class Piece:
|
||||
moves.append((nx, ny))
|
||||
|
||||
elif self.name in ['rook', 'bishop', 'queen']:
|
||||
# Ограничиваем движение до 5 клеток
|
||||
# Ограничиваем движение до 3 клеток
|
||||
if self.name == 'rook':
|
||||
directions = [(-1,0),(1,0),(0,-1),(0,1)]
|
||||
elif self.name == 'bishop':
|
||||
@ -244,7 +172,7 @@ class Piece:
|
||||
(-1,-1),(1,-1),(1,1),(-1,1)
|
||||
]
|
||||
for dx, dy in directions:
|
||||
for step in range(1, 6): # До 5 клеток
|
||||
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:
|
||||
@ -311,9 +239,11 @@ def initialize_pieces():
|
||||
|
||||
return pieces
|
||||
|
||||
# Инициализация фигур до инициализации бонусов
|
||||
# Инициализация фигур
|
||||
pieces = initialize_pieces()
|
||||
initialize_bonus_cells(pieces, num_each=10)
|
||||
|
||||
# Remove initial bonus cell generation
|
||||
# initialize_bonus_cells(pieces, num_each=10)
|
||||
|
||||
selected_piece = None
|
||||
possible_moves = []
|
||||
@ -326,6 +256,66 @@ 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():
|
||||
"""
|
||||
@ -491,14 +481,98 @@ def display_turn(current_turn):
|
||||
text = turn_font.render(f"Текущий ход: {current_turn.capitalize()}", True, COLOR_TURN_TEXT)
|
||||
screen.blit(text, (10, WINDOW_HEIGHT - 30))
|
||||
|
||||
running = True
|
||||
clock = pygame.time.Clock()
|
||||
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
|
||||
@ -539,7 +613,7 @@ while running:
|
||||
# После изменения позиций фигур обновляем туман войны
|
||||
update_fog()
|
||||
# Смена хода
|
||||
current_turn = 'black' if current_turn == 'white' else 'white'
|
||||
switch_turn()
|
||||
continue
|
||||
else:
|
||||
# Атакующая жива, перемещаем её
|
||||
@ -560,7 +634,7 @@ while running:
|
||||
survived = True
|
||||
for pos in path:
|
||||
if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
|
||||
damage = random.randint(0,5)
|
||||
damage = random.randint(1,5) # Исправлено на 1..5
|
||||
attacker.hp = max(attacker.hp - damage, 0)
|
||||
# Удаляем 'damage' клетку как использованную
|
||||
del bonus_cells[pos]
|
||||
@ -569,6 +643,8 @@ while running:
|
||||
selected_piece = None
|
||||
possible_moves.clear()
|
||||
survived = False
|
||||
# Смена хода, так как игрок погиб
|
||||
switch_turn()
|
||||
break
|
||||
if survived:
|
||||
attacker.x = gx
|
||||
@ -577,7 +653,7 @@ while running:
|
||||
selected_piece = None
|
||||
possible_moves.clear()
|
||||
# Смена хода
|
||||
current_turn = 'black' if current_turn == 'white' else 'white'
|
||||
switch_turn()
|
||||
|
||||
else:
|
||||
# Пустая клетка — просто ходим
|
||||
@ -598,7 +674,7 @@ while running:
|
||||
survived = True
|
||||
for pos in path:
|
||||
if pos in bonus_cells and bonus_cells[pos]['type'] == 'damage':
|
||||
damage = random.randint(0,5)
|
||||
damage = random.randint(1,5) # Исправлено на 1..5
|
||||
selected_piece.hp = max(selected_piece.hp - damage, 0)
|
||||
# Удаляем 'damage' клетку как использованную
|
||||
del bonus_cells[pos]
|
||||
@ -607,6 +683,8 @@ while running:
|
||||
selected_piece = None
|
||||
possible_moves.clear()
|
||||
survived = False
|
||||
# Смена хода, так как игрок погиб
|
||||
switch_turn()
|
||||
break
|
||||
if survived:
|
||||
selected_piece.x = gx
|
||||
@ -615,7 +693,7 @@ while running:
|
||||
selected_piece = None
|
||||
possible_moves.clear()
|
||||
# Смена хода
|
||||
current_turn = 'black' if current_turn == 'white' else 'white'
|
||||
switch_turn()
|
||||
|
||||
# После успешного хода обновляем туман войны
|
||||
update_fog()
|
||||
@ -642,6 +720,8 @@ while running:
|
||||
display_victory(winner)
|
||||
else:
|
||||
display_turn(current_turn)
|
||||
display_turn_counter()
|
||||
display_timer()
|
||||
pygame.display.flip()
|
||||
|
||||
pygame.quit()
|
||||
|
Loading…
x
Reference in New Issue
Block a user