{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7044cd72",
   "metadata": {},
   "source": [
    "# 21-25 · Finalna wersja gry\n",
    "\n",
    "Praktyka do sekcji [„Składanie ostatecznej wersji gry” `projects/pygame/space-shooter/space_shooter.py`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cd4fd22",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Uruchom prawdziwą klasę Game z ostatniej gry, wykonaj kilka sekund symulacji i upewnij się, że wynik, życia i przedmioty zachowują się jak jedno."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ce349cd",
   "metadata": {},
   "source": [
    "## O pętli gier w tym laptopie\n",
    "\n",
    "W normalnym życiu `.py`pliku -plik, pętla gry to `while rabotaet:`to zależy od zdarzeń użytkownika (zamykanie okna, naciśnięcia klawiszy). W automatycznie wykonywanym laptopie nie ma nikogo, kto mógłby je tworzyć, więc tutaj uruchamiamy stałą liczbę klatek przez `for kadr in range(N):` — logika każdej pojedynczej klatki (ruch, kolizje, rysowanie) przy tym dokładnie taka sama, jak w prawdziwej grze z `projects/pygame/space-shooter/space_shooter.py`. Prędkość wciąż jest podana w pikselach na sekundę (px/s), a nie w pikselach na klatkę — ale aby wynik notatnika nie zależał od tego, jak szybko kod działa na konkretnym komputerze, `dt` tutaj nie jest zaczerpnięte z `clock.tick()`, ale jest ustalone z góry jako `1 / FPS`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7511c46c",
   "metadata": {},
   "source": [
    "## Sprawa robocza"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14dcf561",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import sys\n",
    "\n",
    "sys.path.insert(0, \"../../projects/pygame/space-shooter\")\n",
    "\n",
    "import space_shooter as ss\n",
    "\n",
    "game = ss.Game(rng=random.Random(11))\n",
    "game.start_new_game()\n",
    "\n",
    "for _ in range(180):   # 3 симулированные секунды\n",
    "    game.update(1 / 60)\n",
    "    game.render()\n",
    "\n",
    "print(\"Состояние:\", game.state)\n",
    "print(\"Счёт:\", game.score)\n",
    "print(\"Врагов на поле:\", len(game.enemies))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f15ddbdc",
   "metadata": {},
   "source": [
    "## Sprawdzenie wyniku"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4e0738d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert game.state in (ss.GameStatus.PLAYING, ss.GameStatus.GAME_OVER)\n",
    "assert game.score >= 0\n",
    "assert game.lives >= 0\n",
    "print(\"Верно: финальная игра проходит несколько секунд симуляции без ошибок.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75b55c95",
   "metadata": {},
   "source": [
    "## Zadanie niezależne od zadania ★★\n",
    "\n",
    "Ręcznie stwórz kolizję pocisków z wrogiem przez `game.resolve_bullet_enemy_collisions()` i upewnij się, że wynik zwiększa się dokładnie o wartość jednego wroga."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f0c33576",
   "metadata": {},
   "outputs": [],
   "source": [
    "tochka = (game.player.rect.centerx, 300.0)\n",
    "vrag = ss.Enemy(game.assets.images[\"enemy_scout\"], tochka, points=100, speed=0.0)\n",
    "game.enemies.add(vrag)\n",
    "pulya = ss.Bullet(game.assets.images[\"bullet\"], tochka)\n",
    "game.bullets.add(pulya)\n",
    "\n",
    "schet_do = game.score\n",
    "game.score += game.resolve_bullet_enemy_collisions()\n",
    "\n",
    "assert game.score == schet_do + 100\n",
    "print(\"Верно: столкновение пули и врага добавило ровно 100 очков.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
