/* Veidoja: Emīlija Anna Bukus Grupa: 110 Gala noslēguma darbs - "ZOMBIE APOCALYPSE RGB" Apraksts: Teksta bāzēta zombiju apokalipses spēle, kur spēlētājs cīnās pret viļņiem ar dažādiem zombijiem. Spēle piedāvā vairākus grūtības līmeņus, katrs ar unikālām īpašībām un izaicinājumiem. Spēlētājs var izvēlēties starp uzbrukumu, dziedināšanu vai bloķēšanu, lai izdzīvotu pēc iespējas ilgāk un iegūtu augstāku rezultātu. Gala versija izveidota 03.06.2026. Izmantotais Compiler: Visual Studio Code */ using System; using System.Collections.Generic; namespace ZombieApocalypseRGB { public abstract class Entity { protected int posX; protected int posY; protected ConsoleColor color; public Entity(int x, int y, ConsoleColor col) { posX = x; posY = y; color = col; } public abstract void Move(int maxX, int maxY); public int PosX { get { return posX; } set { posX = value; } } public int PosY { get { return posY; } set { posY = value; } } public ConsoleColor Color { get { return color; } set { color = value; } } } public class Player : Entity { private int health; private int maxHealth; private int stamina; private int maxStamina; private int score; private bool isAlive; public Player(int x, int y, int startHealth, int startStamina) : base(x, y, ConsoleColor.Green) { health = startHealth; maxHealth = startHealth; stamina = startStamina; maxStamina = startStamina; score = 0; isAlive = true; } public int Health { get { return health; } set { health = Math.Min(value, maxHealth); } } public int MaxHealth { get { return maxHealth; } } public int Stamina { get { return stamina; } set { stamina = Math.Max(0, Math.Min(value, maxStamina)); } } public int MaxStamina { get { return maxStamina; } } public int Score { get { return score; } set { score = value; } } public bool IsAlive { get { return isAlive; } set { isAlive = value; } } public bool TakeDamage(int damage) { health -= damage; if (health <= 0) { isAlive = false; health = 0; return false; } return true; } public void Attack(Zombie zombie, int difficulty) { int damage = 25 + (stamina / 10); zombie.TakeDamage(damage); stamina -= 10; } public void Heal() { Health += 30; Stamina += 20; } public void Block() { stamina -= 5; } public override void Move(int maxX, int maxY) { } public void MoveTo(int newX, int newY, int maxWidth, int maxHeight) { if (newX >= 0 && newX < maxWidth) posX = newX; if (newY >= 0 && newY < maxHeight) posY = newY; } } public class Zombie : Entity { private int health; private int maxHealth; private int damage; private int speed; public Zombie(int x, int y, int hp, int dmg, int spd) : base(x, y, ConsoleColor.Red) { health = hp; maxHealth = hp; damage = dmg; speed = spd; } public int Health { get { return health; } } public int Damage { get { return damage; } } public int Speed { get { return speed; } } public void TakeDamage(int amount) { health -= amount; if (health < 0) health = 0; } public bool IsAlive() { return health > 0; } public void MoveTowardsPlayer(int playerX, int playerY, int maxX, int maxY, List allZombies) { int newX = posX; int newY = posY; int diffX = playerX - posX; int diffY = playerY - posY; if (Math.Abs(diffX) > Math.Abs(diffY)) { if (diffX > 0) newX++; else if (diffX < 0) newX--; } else if (Math.Abs(diffY) > 0) { if (diffY > 0) newY++; else if (diffY < 0) newY--; } if (IsValidPosition(newX, newY, maxX, maxY, allZombies)) { posX = newX; posY = newY; } else { TryAlternativeMove(playerX, playerY, maxX, maxY, allZombies); } } private bool IsValidPosition(int x, int y, int maxX, int maxY, List allZombies) { if (x < 0 || x >= maxX || y < 0 || y >= maxY) return false; foreach (var z in allZombies) { if (z != this && z.PosX == x && z.PosY == y) return false; } return true; } private void TryAlternativeMove(int playerX, int playerY, int maxX, int maxY, List allZombies) { int[] dx = { 0, 0, -1, 1 }; int[] dy = { -1, 1, 0, 0 }; List validMoves = new List(); for (int i = 0; i < 4; i++) { int newX = posX + dx[i]; int newY = posY + dy[i]; if (IsValidPosition(newX, newY, maxX, maxY, allZombies)) { validMoves.Add(i); } } if (validMoves.Count > 0) { int bestMove = validMoves[0]; int bestDistance = int.MaxValue; foreach (int move in validMoves) { int newX = posX + dx[move]; int newY = posY + dy[move]; int dist = Math.Abs(playerX - newX) + Math.Abs(playerY - newY); if (dist < bestDistance) { bestDistance = dist; bestMove = move; } } posX += dx[bestMove]; posY += dy[bestMove]; } } public override void Move(int maxX, int maxY) { } } public class Game { private List zombieList; private Player player; private bool gameRunning; private int width; private int height; private int waveNumber; private string gameMode; private int difficulty; private int baseZombieHealth; private int baseZombieDamage; private int zombiesInNextWave; public Game(int w, int h, string mode) { width = w; height = h; gameMode = mode; zombieList = new List(); gameRunning = true; waveNumber = 1; zombiesInNextWave = 0; switch (gameMode) { case "Easy": difficulty = 1; player = new Player(w / 2, h / 2, 150, 100); baseZombieHealth = 30; baseZombieDamage = 5; zombiesInNextWave = 3; break; case "Normal": difficulty = 2; player = new Player(w / 2, h / 2, 100, 80); baseZombieHealth = 50; baseZombieDamage = 10; zombiesInNextWave = 4; break; case "Hard": difficulty = 3; player = new Player(w / 2, h / 2, 80, 60); baseZombieHealth = 75; baseZombieDamage = 15; zombiesInNextWave = 5; break; case "Nightmare": difficulty = 5; player = new Player(w / 2, h / 2, 50, 40); baseZombieHealth = 100; baseZombieDamage = 20; zombiesInNextWave = 6; break; default: difficulty = 2; player = new Player(w / 2, h / 2, 100, 80); baseZombieHealth = 50; baseZombieDamage = 10; zombiesInNextWave = 4; break; } } public int CalculateDistance(int x1, int y1, int x2, int y2) { return Math.Abs(x2 - x1) + Math.Abs(y2 - y1); } public void SpawnZombie(int count) { Random rnd = new Random(); int spawned = 0; int attempts = 0; int zombieHealth = baseZombieHealth + (waveNumber * 10 * difficulty); int zombieDamage = baseZombieDamage + (waveNumber * 2); while (spawned < count && attempts < 1000) { int x = rnd.Next(width); int y = rnd.Next(height); if (CalculateDistance(x, y, player.PosX, player.PosY) >= 5) { bool occupied = false; foreach (var z in zombieList) { if (z.PosX == x && z.PosY == y) { occupied = true; break; } } if (!occupied) { Zombie z = new Zombie(x, y, zombieHealth, zombieDamage, 1); zombieList.Add(z); spawned++; } } attempts++; } } // VILŅU PĀREJAS EKRĀNS public void ShowWaveTransition() { Console.Clear(); // Aprēķina nākamā viļņa zombiju skaitu (vairāk nekā iepriekš) zombiesInNextWave = zombiesInNextWave + 1 + difficulty; waveNumber++; // Atjauno spēlētāju player.Stamina = player.MaxStamina; player.Health = Math.Min(player.Health + 20, player.MaxHealth); Console.ForegroundColor = ConsoleColor.Yellow; // ChatGPT palīdzēja izveidot to tabulu Console.WriteLine("\n\n"); Console.WriteLine(" ╔══════════════════════════════════════════════════════════╗"); Console.WriteLine(" ║ ║"); Console.WriteLine($" ║ WAVE {waveNumber} STARTING! ║"); Console.WriteLine(" ║ ║"); Console.WriteLine(" ╠══════════════════════════════════════════════════════════╣"); Console.WriteLine($" ║ ║"); Console.WriteLine($" ║ Zombies incoming: {zombiesInNextWave,2} ║"); Console.WriteLine($" ║ Zombie HP: {baseZombieHealth + (waveNumber * 10 * difficulty),3} ║"); Console.WriteLine($" ║ Zombie DMG: {baseZombieDamage + (waveNumber * 2),2} ║"); Console.WriteLine(" ║ ║"); Console.WriteLine(" ║ Health restored: +20 ║"); Console.WriteLine(" ║ Stamina restored: FULL ║"); Console.WriteLine(" ║ ║"); Console.WriteLine(" ╚══════════════════════════════════════════════════════════╝"); Console.ResetColor(); Console.WriteLine("\n Press any key to continue..."); Console.ReadKey(true); } public void DrawControls() { Console.ForegroundColor = ConsoleColor.Cyan; // ChatGPT palīdzēja izveidot to tabulu Console.WriteLine("╔════════════════════════════════════════════════════════════════╗"); Console.WriteLine("║ MOVEMENT SYSTEM ║"); Console.WriteLine("║ [W/↑] Up [S/↓] Down [A/←] Left [D/→] Right [Q] Quit ║"); Console.WriteLine("╚════════════════════════════════════════════════════════════════╝"); Console.ResetColor(); Console.WriteLine(); } public void DrawStatus() { ConsoleColor modeColor = ConsoleColor.Green; switch (gameMode) { case "Easy": modeColor = ConsoleColor.Green; break; case "Normal": modeColor = ConsoleColor.Yellow; break; case "Hard": modeColor = ConsoleColor.Red; break; case "Nightmare": modeColor = ConsoleColor.Magenta; break; } Console.ForegroundColor = modeColor; Console.Write($" [{gameMode}] "); Console.ForegroundColor = ConsoleColor.Yellow; Console.Write($"HP: {player.Health}/{player.MaxHealth} | "); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write($"STM: {player.Stamina}/{player.MaxStamina} | "); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Score: {player.Score} | Wave: {waveNumber} | Zombies: {zombieList.Count}"); Console.ResetColor(); Console.WriteLine(); } public void Render() { Console.Clear(); DrawControls(); DrawStatus(); Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write(" ┌"); for (int i = 0; i < width; i++) Console.Write("─"); Console.WriteLine("┐"); for (int y = 0; y < height; y++) { Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write(" │"); for (int x = 0; x < width; x++) { bool zombieHere = false; foreach (var z in zombieList) { if (z.PosX == x && z.PosY == y && z.IsAlive()) { if (z.Health > 70) Console.ForegroundColor = ConsoleColor.Red; else if (z.Health > 30) Console.ForegroundColor = ConsoleColor.DarkYellow; else Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write("Z"); zombieHere = true; break; } } if (!zombieHere) { if (player.PosX == x && player.PosY == y) { Console.ForegroundColor = ConsoleColor.Green; Console.Write("P"); } else { Console.ForegroundColor = ConsoleColor.DarkGray; Console.Write("·"); } } } Console.ForegroundColor = ConsoleColor.DarkGray; Console.WriteLine("│"); } Console.Write(" └"); for (int i = 0; i < width; i++) Console.Write("─"); Console.WriteLine("┘"); Console.ResetColor(); Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(" >>> Your Turn - Press a movement key <<<"); Console.ResetColor(); } public bool Combat(Zombie zombie) { bool combatActive = true; bool playerWon = false; while (combatActive) { Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; // ChatGPT palīdzēja izveidot to tabulu Console.WriteLine("\n ╔════════════════════════════════════════════════════════════╗"); Console.WriteLine(" ║ COMBAT ║"); Console.WriteLine(" ╠════════════════════════════════════════════════════════════╣"); Console.WriteLine($" ║ ZOMBIE: {zombie.Health,3} HP | DMG: {zombie.Damage,2} ║"); Console.WriteLine($" ║ PLAYER: {player.Health,3}/{player.MaxHealth,3} HP | STM: {player.Stamina,3}/{player.MaxStamina,3} ║"); Console.WriteLine(" ╠════════════════════════════════════════════════════════════╣"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(" ║ ║"); Console.WriteLine(" ║ [1] ATTACK - Deal damage (-10 STM) ║"); Console.WriteLine(" ║ [2] HEAL - +30 HP, +20 STM ║"); Console.WriteLine(" ║ [3] BLOCK - Reduce damage by 50% (-5 STM) ║"); Console.WriteLine(" ║ ║"); Console.WriteLine(" ╚════════════════════════════════════════════════════════════╝"); Console.ResetColor(); Console.Write("\n Choose action (1-3): "); ConsoleKeyInfo choice = Console.ReadKey(true); bool blocked = false; switch (choice.KeyChar) { case '1': if (player.Stamina >= 10) { player.Attack(zombie, difficulty); Console.WriteLine("\n You attacked the zombie!"); } else { Console.WriteLine("\n Not enough stamina!"); } break; case '2': if (player.Health < player.MaxHealth) { player.Heal(); Console.WriteLine("\n You healed yourself!"); } else { Console.WriteLine("\n Full health already!"); } break; case '3': if (player.Stamina >= 5) { player.Block(); blocked = true; Console.WriteLine("\n You prepare to block!"); } else { Console.WriteLine("\n Not enough stamina!"); } break; default: continue; } if (zombie.IsAlive()) { int damage = zombie.Damage; if (blocked) damage /= 2; player.TakeDamage(damage); Console.WriteLine($" Zombie hits you for {damage} damage!"); } else { Console.WriteLine("\n Zombie defeated!"); playerWon = true; combatActive = false; } if (!player.IsAlive) { Console.WriteLine("\n You died!"); combatActive = false; } Console.WriteLine("\n Press any key to continue..."); Console.ReadKey(true); } return playerWon; } // Pārbauda vai vilnis ir beidzies (visi zombiji nogalināti) public void CheckWaveComplete() { // Skaita tikai dzīvos zombijus int aliveZombies = 0; foreach (var z in zombieList) { if (z.IsAlive()) aliveZombies++; } // Ja nav vairs dzīvu zombiju, sāk nākamo vilni if (aliveZombies == 0 && zombieList.Count > 0) { ShowWaveTransition(); SpawnZombie(zombiesInNextWave); } } public void UpdateZombies() { Zombie enemy = null; foreach (var zombie in zombieList) { if (zombie.PosX == player.PosX && zombie.PosY == player.PosY && zombie.IsAlive()) { enemy = zombie; break; } } if (enemy != null) { bool won = Combat(enemy); if (won) { // Atzīmē zombiju kā mirušu, bet neizdzēš uzreiz enemy.TakeDamage(9999); player.Score += 50; } return; } foreach (var zombie in zombieList.ToList()) { if (!zombie.IsAlive()) continue; int oldX = zombie.PosX; int oldY = zombie.PosY; zombie.MoveTowardsPlayer(player.PosX, player.PosY, width, height, zombieList); if (zombie.PosX == player.PosX && zombie.PosY == player.PosY) { bool won = Combat(zombie); if (won) { zombie.TakeDamage(9999); player.Score += 50; } } } if (!player.IsAlive) { gameRunning = false; } // Pārbauda vai vilnis ir beidzies CheckWaveComplete(); } public void HandleInput() { ConsoleKeyInfo keyInfo = Console.ReadKey(true); bool playerMoved = false; int newX = player.PosX; int newY = player.PosY; switch (keyInfo.Key) { case ConsoleKey.W: case ConsoleKey.UpArrow: if (player.PosY > 0) { newY--; playerMoved = true; } break; case ConsoleKey.S: case ConsoleKey.DownArrow: if (player.PosY < height - 1) { newY++; playerMoved = true; } break; case ConsoleKey.A: case ConsoleKey.LeftArrow: if (player.PosX > 0) { newX--; playerMoved = true; } break; case ConsoleKey.D: case ConsoleKey.RightArrow: if (player.PosX < width - 1) { newX++; playerMoved = true; } break; case ConsoleKey.Q: gameRunning = false; return; default: break; } if (playerMoved) { Zombie targetZombie = null; foreach (var z in zombieList) { if (z.PosX == newX && z.PosY == newY && z.IsAlive()) { targetZombie = z; break; } } if (targetZombie != null) { bool won = Combat(targetZombie); if (won) { targetZombie.TakeDamage(9999); player.Score += 50; } } else { player.PosX = newX; player.PosY = newY; player.Score += 1; } player.Stamina = Math.Min(player.Stamina + 5, player.MaxStamina); UpdateZombies(); // Pārbauda vilņa beigas arī pēc spēlētāja gājiena CheckWaveComplete(); } } public void Run() { SpawnZombie(zombiesInNextWave); while (gameRunning) { Render(); HandleInput(); } Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; // ChatGPT palīdzēja izveidot to tabulu Console.WriteLine("\n\n ╔════════════════════════════════════════════╗"); Console.WriteLine(" ║ GAME OVER! ║"); Console.WriteLine(" ╠════════════════════════════════════════════╣"); Console.WriteLine($" ║ Mode: {gameMode,-20} ║"); Console.WriteLine($" ║ Final Score: {player.Score,10} ║"); Console.WriteLine($" ║ Waves Survived: {waveNumber,7} ║"); Console.WriteLine(" ╚════════════════════════════════════════════╝"); Console.ResetColor(); Console.WriteLine("\n Press any key to exit..."); Console.ReadKey(true); } } class Program { static string SelectGameMode() { Console.Clear(); Console.ForegroundColor = ConsoleColor.Cyan; // ChatGPT palīdzēja izveidot to tabulu Console.WriteLine("╔════════════════════════════════════════════════════════════╗"); Console.WriteLine("║ ZOMBIE APOCALYPSE RGB ║"); Console.WriteLine("║ Select Game Mode ║"); Console.WriteLine("╠════════════════════════════════════════════════════════════╣"); Console.WriteLine("║ ║"); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("║ [1] EASY - 150 HP | 100 STM | Weak zombies ║"); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("║ [2] NORMAL - 100 HP | 80 STM | Normal zombies ║"); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("║ [3] HARD - 80 HP | 60 STM | Strong zombies ║"); Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine("║ [4] NIGHTMARE- 50 HP | 40 STM | Deadly zombies ║"); Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine("║ ║"); Console.WriteLine("╚════════════════════════════════════════════════════════════╝"); Console.ResetColor(); Console.WriteLine(); Console.Write(" Select mode (1-4): "); while (true) { ConsoleKeyInfo key = Console.ReadKey(true); switch (key.KeyChar) { case '1': return "Easy"; case '2': return "Normal"; case '3': return "Hard"; case '4': return "Nightmare"; } } } static void Main(string[] args) { Console.WriteLine("=== ZOMBIE APOCALYPSE RGB ==="); Console.WriteLine("Enter your name:"); string playerName = Console.ReadLine(); string selectedMode = SelectGameMode(); Console.WriteLine(); Console.WriteLine($"Mode selected: {selectedMode}"); Console.WriteLine("Press any key to start..."); Console.ReadKey(true); int width = 40; int height = 15; Console.Clear(); Console.WriteLine("Loading game..."); for (int i = 0; i < 20; i++) { Console.Write("█"); System.Threading.Thread.Sleep(30); } Console.WriteLine(); for (int i = 3; i > 0; i--) { Console.WriteLine($"Starting in {i}..."); System.Threading.Thread.Sleep(500); } Game game = new Game(width, height, selectedMode); game.Run(); } } }