From dbd34722420b73ddce6866fb8f7eff827aea98d8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 14 Mar 2026 21:24:59 +0000
Subject: [PATCH 1/5] Initial plan
From ed12c99a842299ac7f73cd810224580b89efba00 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 14 Mar 2026 21:32:28 +0000
Subject: [PATCH 2/5] Add ClassCrawler C# .NET 8 teaching scaffold
Co-authored-by: Merlissa09 <41809281+Merlissa09@users.noreply.github.com>
---
.github/workflows/ci.yml | 30 +++++++++++
ClassCrawler.Tests/ClassCrawler.Tests.csproj | 27 ++++++++++
ClassCrawler.Tests/CombatEngineTests.cs | 12 +++++
ClassCrawler.Tests/CombatStrategyTests.cs | 12 +++++
ClassCrawler.Tests/InventoryTests.cs | 12 +++++
ClassCrawler.Tests/ItemTests.cs | 12 +++++
ClassCrawler.Tests/LootResolverTests.cs | 12 +++++
ClassCrawler.slnx | 4 ++
ClassCrawler/Characters/Character.cs | 41 +++++++++++++++
ClassCrawler/Characters/Dragon.cs | 32 ++++++++++++
ClassCrawler/Characters/Enemy.cs | 19 +++++++
ClassCrawler/Characters/Goblin.cs | 32 ++++++++++++
ClassCrawler/Characters/Orc.cs | 32 ++++++++++++
ClassCrawler/Characters/Player.cs | 51 +++++++++++++++++++
ClassCrawler/ClassCrawler.csproj | 14 +++++
ClassCrawler/Combat/CharacterFactory.cs | 21 ++++++++
ClassCrawler/Combat/CombatEngine.cs | 14 +++++
ClassCrawler/Combat/CombatOutcome.cs | 4 ++
ClassCrawler/Combat/CombatResult.cs | 4 ++
ClassCrawler/Combat/ICombatStrategy.cs | 10 ++++
ClassCrawler/Combat/LootResolver.cs | 15 ++++++
ClassCrawler/Combat/MagicStrategy.cs | 14 +++++
ClassCrawler/Combat/MeleeStrategy.cs | 14 +++++
ClassCrawler/Combat/RangedStrategy.cs | 14 +++++
ClassCrawler/Events/EnemyDefeatedEvent.cs | 9 ++++
ClassCrawler/Events/GameEvent.cs | 18 +++++++
ClassCrawler/Events/GameEventSystem.cs | 26 ++++++++++
ClassCrawler/Events/GameEventType.cs | 17 +++++++
ClassCrawler/Events/IGameEventListener.cs | 8 +++
ClassCrawler/Events/ItemPickedUpEvent.cs | 9 ++++
ClassCrawler/Events/PlayerDeathEvent.cs | 9 ++++
ClassCrawler/Events/PlayerLevelUpEvent.cs | 9 ++++
ClassCrawler/Items/Armor.cs | 17 +++++++
ClassCrawler/Items/Item.cs | 19 +++++++
ClassCrawler/Items/Potion.cs | 17 +++++++
ClassCrawler/Items/Weapon.cs | 17 +++++++
ClassCrawler/Persistence/GameState.cs | 9 ++++
ClassCrawler/Persistence/IGameRepository.cs | 17 +++++++
ClassCrawler/Persistence/LeaderboardEntry.cs | 4 ++
.../Persistence/SqliteGameRepository.cs | 33 ++++++++++++
ClassCrawler/Program.cs | 3 ++
ClassCrawler/UI/GameUI.cs | 42 +++++++++++++++
ClassCrawler/World/Dungeon.cs | 25 +++++++++
ClassCrawler/World/Room.cs | 26 ++++++++++
README.md | 51 ++++++++++++++++++-
45 files changed, 836 insertions(+), 1 deletion(-)
create mode 100644 .github/workflows/ci.yml
create mode 100644 ClassCrawler.Tests/ClassCrawler.Tests.csproj
create mode 100644 ClassCrawler.Tests/CombatEngineTests.cs
create mode 100644 ClassCrawler.Tests/CombatStrategyTests.cs
create mode 100644 ClassCrawler.Tests/InventoryTests.cs
create mode 100644 ClassCrawler.Tests/ItemTests.cs
create mode 100644 ClassCrawler.Tests/LootResolverTests.cs
create mode 100644 ClassCrawler.slnx
create mode 100644 ClassCrawler/Characters/Character.cs
create mode 100644 ClassCrawler/Characters/Dragon.cs
create mode 100644 ClassCrawler/Characters/Enemy.cs
create mode 100644 ClassCrawler/Characters/Goblin.cs
create mode 100644 ClassCrawler/Characters/Orc.cs
create mode 100644 ClassCrawler/Characters/Player.cs
create mode 100644 ClassCrawler/ClassCrawler.csproj
create mode 100644 ClassCrawler/Combat/CharacterFactory.cs
create mode 100644 ClassCrawler/Combat/CombatEngine.cs
create mode 100644 ClassCrawler/Combat/CombatOutcome.cs
create mode 100644 ClassCrawler/Combat/CombatResult.cs
create mode 100644 ClassCrawler/Combat/ICombatStrategy.cs
create mode 100644 ClassCrawler/Combat/LootResolver.cs
create mode 100644 ClassCrawler/Combat/MagicStrategy.cs
create mode 100644 ClassCrawler/Combat/MeleeStrategy.cs
create mode 100644 ClassCrawler/Combat/RangedStrategy.cs
create mode 100644 ClassCrawler/Events/EnemyDefeatedEvent.cs
create mode 100644 ClassCrawler/Events/GameEvent.cs
create mode 100644 ClassCrawler/Events/GameEventSystem.cs
create mode 100644 ClassCrawler/Events/GameEventType.cs
create mode 100644 ClassCrawler/Events/IGameEventListener.cs
create mode 100644 ClassCrawler/Events/ItemPickedUpEvent.cs
create mode 100644 ClassCrawler/Events/PlayerDeathEvent.cs
create mode 100644 ClassCrawler/Events/PlayerLevelUpEvent.cs
create mode 100644 ClassCrawler/Items/Armor.cs
create mode 100644 ClassCrawler/Items/Item.cs
create mode 100644 ClassCrawler/Items/Potion.cs
create mode 100644 ClassCrawler/Items/Weapon.cs
create mode 100644 ClassCrawler/Persistence/GameState.cs
create mode 100644 ClassCrawler/Persistence/IGameRepository.cs
create mode 100644 ClassCrawler/Persistence/LeaderboardEntry.cs
create mode 100644 ClassCrawler/Persistence/SqliteGameRepository.cs
create mode 100644 ClassCrawler/Program.cs
create mode 100644 ClassCrawler/UI/GameUI.cs
create mode 100644 ClassCrawler/World/Dungeon.cs
create mode 100644 ClassCrawler/World/Room.cs
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..5dfb42b
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,30 @@
+name: CI
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: '8.0.x'
+
+ - name: Restore dependencies
+ run: dotnet restore
+
+ - name: Build
+ run: dotnet build --no-restore
+
+ - name: Test
+ run: dotnet test --no-build
diff --git a/ClassCrawler.Tests/ClassCrawler.Tests.csproj b/ClassCrawler.Tests/ClassCrawler.Tests.csproj
new file mode 100644
index 0000000..e0c67fe
--- /dev/null
+++ b/ClassCrawler.Tests/ClassCrawler.Tests.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ClassCrawler.Tests/CombatEngineTests.cs b/ClassCrawler.Tests/CombatEngineTests.cs
new file mode 100644
index 0000000..d8a52d1
--- /dev/null
+++ b/ClassCrawler.Tests/CombatEngineTests.cs
@@ -0,0 +1,12 @@
+namespace ClassCrawler.Tests;
+
+/// Placeholder tests for CombatEngine. Students will complete these.
+public class CombatEngineTests
+{
+ [Fact(Skip = "Not yet implemented")]
+ public void RunCombat_ReturnsOutcome()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler.Tests/CombatStrategyTests.cs b/ClassCrawler.Tests/CombatStrategyTests.cs
new file mode 100644
index 0000000..729c592
--- /dev/null
+++ b/ClassCrawler.Tests/CombatStrategyTests.cs
@@ -0,0 +1,12 @@
+namespace ClassCrawler.Tests;
+
+/// Placeholder tests for combat strategies. Students will complete these.
+public class CombatStrategyTests
+{
+ [Fact(Skip = "Not yet implemented")]
+ public void MeleeStrategy_Execute_ReturnsCombatResult()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler.Tests/InventoryTests.cs b/ClassCrawler.Tests/InventoryTests.cs
new file mode 100644
index 0000000..5dac66b
--- /dev/null
+++ b/ClassCrawler.Tests/InventoryTests.cs
@@ -0,0 +1,12 @@
+namespace ClassCrawler.Tests;
+
+/// Placeholder tests for player inventory management. Students will complete these.
+public class InventoryTests
+{
+ [Fact(Skip = "Not yet implemented")]
+ public void AddItem_IncreasesInventoryCount()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler.Tests/ItemTests.cs b/ClassCrawler.Tests/ItemTests.cs
new file mode 100644
index 0000000..2dc043d
--- /dev/null
+++ b/ClassCrawler.Tests/ItemTests.cs
@@ -0,0 +1,12 @@
+namespace ClassCrawler.Tests;
+
+/// Placeholder tests for item usage. Students will complete these.
+public class ItemTests
+{
+ [Fact(Skip = "Not yet implemented")]
+ public void Potion_Use_RestoresHealth()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler.Tests/LootResolverTests.cs b/ClassCrawler.Tests/LootResolverTests.cs
new file mode 100644
index 0000000..d2e11cc
--- /dev/null
+++ b/ClassCrawler.Tests/LootResolverTests.cs
@@ -0,0 +1,12 @@
+namespace ClassCrawler.Tests;
+
+/// Placeholder tests for loot resolution. Students will complete these.
+public class LootResolverTests
+{
+ [Fact(Skip = "Not yet implemented")]
+ public void ResolveLoot_ReturnsItemList()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler.slnx b/ClassCrawler.slnx
new file mode 100644
index 0000000..e33c836
--- /dev/null
+++ b/ClassCrawler.slnx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/ClassCrawler/Characters/Character.cs b/ClassCrawler/Characters/Character.cs
new file mode 100644
index 0000000..808cf72
--- /dev/null
+++ b/ClassCrawler/Characters/Character.cs
@@ -0,0 +1,41 @@
+using ClassCrawler.Combat;
+
+namespace ClassCrawler.Characters;
+
+/// Abstract base class for all characters in the game.
+public abstract class Character
+{
+ /// The character's display name.
+ public string Name { get; set; } = string.Empty;
+
+ /// The character's current health points.
+ public int Health { get; set; }
+
+ /// The character's maximum health points.
+ public int MaxHealth { get; set; }
+
+ /// The base damage this character deals per attack.
+ public int AttackPower { get; set; }
+
+ /// Reduces incoming damage by this amount.
+ public int Defense { get; set; }
+
+ /// The character's current level.
+ public int Level { get; set; }
+
+ /// Indicates whether the character is still alive.
+ public bool IsAlive => Health > 0;
+
+ /// The combat strategy used when this character attacks.
+ public ICombatStrategy? CombatStrategy { get; set; }
+
+ /// Applies damage to this character.
+ public abstract void TakeDamage(int amount);
+
+ /// Returns a human-readable description of this character.
+ public virtual string GetDescription()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Characters/Dragon.cs b/ClassCrawler/Characters/Dragon.cs
new file mode 100644
index 0000000..104f4a6
--- /dev/null
+++ b/ClassCrawler/Characters/Dragon.cs
@@ -0,0 +1,32 @@
+namespace ClassCrawler.Characters;
+
+/// A fearsome dragon — the ultimate dungeon boss.
+public class Dragon : Enemy
+{
+ /// Initialises a Dragon with default starting stats.
+ public Dragon()
+ {
+ Name = "Dragon";
+ Health = 200;
+ MaxHealth = 200;
+ AttackPower = 35;
+ Defense = 15;
+ Level = 10;
+ ExperienceReward = 200;
+ GoldReward = 100;
+ }
+
+ /// Returns a description of the Dragon's attack.
+ public override string GetAttackDescription()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Applies damage to the Dragon, reducing its health.
+ public override void TakeDamage(int amount)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Characters/Enemy.cs b/ClassCrawler/Characters/Enemy.cs
new file mode 100644
index 0000000..35abd3d
--- /dev/null
+++ b/ClassCrawler/Characters/Enemy.cs
@@ -0,0 +1,19 @@
+using ClassCrawler.Items;
+
+namespace ClassCrawler.Characters;
+
+/// Abstract base class for all enemy characters.
+public abstract class Enemy : Character
+{
+ /// The amount of experience awarded to the player upon defeating this enemy.
+ public int ExperienceReward { get; set; }
+
+ /// The amount of gold awarded to the player upon defeating this enemy.
+ public int GoldReward { get; set; }
+
+ /// Items that may be dropped by this enemy when defeated.
+ public List- LootTable { get; set; } = new();
+
+ /// Returns a description of this enemy's attack action.
+ public abstract string GetAttackDescription();
+}
diff --git a/ClassCrawler/Characters/Goblin.cs b/ClassCrawler/Characters/Goblin.cs
new file mode 100644
index 0000000..2626175
--- /dev/null
+++ b/ClassCrawler/Characters/Goblin.cs
@@ -0,0 +1,32 @@
+namespace ClassCrawler.Characters;
+
+/// A weak but cunning enemy found in early dungeon rooms.
+public class Goblin : Enemy
+{
+ /// Initialises a Goblin with default starting stats.
+ public Goblin()
+ {
+ Name = "Goblin";
+ Health = 30;
+ MaxHealth = 30;
+ AttackPower = 5;
+ Defense = 2;
+ Level = 1;
+ ExperienceReward = 10;
+ GoldReward = 5;
+ }
+
+ /// Returns a description of the Goblin's attack.
+ public override string GetAttackDescription()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Applies damage to the Goblin, reducing its health.
+ public override void TakeDamage(int amount)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Characters/Orc.cs b/ClassCrawler/Characters/Orc.cs
new file mode 100644
index 0000000..b09113e
--- /dev/null
+++ b/ClassCrawler/Characters/Orc.cs
@@ -0,0 +1,32 @@
+namespace ClassCrawler.Characters;
+
+/// A brutish enemy with high health and strong attacks.
+public class Orc : Enemy
+{
+ /// Initialises an Orc with default starting stats.
+ public Orc()
+ {
+ Name = "Orc";
+ Health = 60;
+ MaxHealth = 60;
+ AttackPower = 12;
+ Defense = 5;
+ Level = 3;
+ ExperienceReward = 25;
+ GoldReward = 15;
+ }
+
+ /// Returns a description of the Orc's attack.
+ public override string GetAttackDescription()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Applies damage to the Orc, reducing its health.
+ public override void TakeDamage(int amount)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Characters/Player.cs b/ClassCrawler/Characters/Player.cs
new file mode 100644
index 0000000..8d27005
--- /dev/null
+++ b/ClassCrawler/Characters/Player.cs
@@ -0,0 +1,51 @@
+using ClassCrawler.Items;
+
+namespace ClassCrawler.Characters;
+
+/// Represents the player character controlled by the user.
+public class Player : Character
+{
+ /// The items currently carried by the player.
+ public List
- Inventory { get; set; } = new();
+
+ /// The total experience points earned by the player.
+ public int Experience { get; set; }
+
+ /// The amount of gold the player is carrying.
+ public int Gold { get; set; }
+
+ /// Adds an item to the player's inventory.
+ public void AddItem(Item item)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Removes an item from the player's inventory.
+ public void RemoveItem(Item item)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Uses an item from the player's inventory on this player.
+ public void UseItem(Item item)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Adds experience points and checks for level-up.
+ public void AddExperience(int amount)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Applies damage to the player, reducing their health.
+ public override void TakeDamage(int amount)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/ClassCrawler.csproj b/ClassCrawler/ClassCrawler.csproj
new file mode 100644
index 0000000..aefb7c8
--- /dev/null
+++ b/ClassCrawler/ClassCrawler.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/ClassCrawler/Combat/CharacterFactory.cs b/ClassCrawler/Combat/CharacterFactory.cs
new file mode 100644
index 0000000..830e133
--- /dev/null
+++ b/ClassCrawler/Combat/CharacterFactory.cs
@@ -0,0 +1,21 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// Provides factory methods for creating pre-configured character instances.
+public static class CharacterFactory
+{
+ /// Creates a new Player configured for the given character class.
+ public static Player CreatePlayer(string name, string characterClass)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Creates an Enemy of the specified type scaled to the given level.
+ public static Enemy CreateEnemy(string type, int scalingLevel)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Combat/CombatEngine.cs b/ClassCrawler/Combat/CombatEngine.cs
new file mode 100644
index 0000000..a976caa
--- /dev/null
+++ b/ClassCrawler/Combat/CombatEngine.cs
@@ -0,0 +1,14 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// Orchestrates a full combat encounter between a player and an enemy.
+public class CombatEngine
+{
+ /// Runs a turn-based combat loop until one combatant is defeated.
+ public CombatOutcome RunCombat(Player player, Enemy enemy)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Combat/CombatOutcome.cs b/ClassCrawler/Combat/CombatOutcome.cs
new file mode 100644
index 0000000..0b210c4
--- /dev/null
+++ b/ClassCrawler/Combat/CombatOutcome.cs
@@ -0,0 +1,4 @@
+namespace ClassCrawler.Combat;
+
+/// Represents the overall outcome of a completed combat encounter.
+public record CombatOutcome(string Winner, int TotalDamageDealt, int ExperienceEarned, int GoldEarned);
diff --git a/ClassCrawler/Combat/CombatResult.cs b/ClassCrawler/Combat/CombatResult.cs
new file mode 100644
index 0000000..f0c046e
--- /dev/null
+++ b/ClassCrawler/Combat/CombatResult.cs
@@ -0,0 +1,4 @@
+namespace ClassCrawler.Combat;
+
+/// Represents the result of a single combat action.
+public record CombatResult(int DamageDealt, string Description);
diff --git a/ClassCrawler/Combat/ICombatStrategy.cs b/ClassCrawler/Combat/ICombatStrategy.cs
new file mode 100644
index 0000000..2967cbf
--- /dev/null
+++ b/ClassCrawler/Combat/ICombatStrategy.cs
@@ -0,0 +1,10 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// Defines a strategy for executing a combat action between two characters.
+public interface ICombatStrategy
+{
+ /// Executes the combat action from attacker to target and returns the result.
+ CombatResult Execute(Character attacker, Character target);
+}
diff --git a/ClassCrawler/Combat/LootResolver.cs b/ClassCrawler/Combat/LootResolver.cs
new file mode 100644
index 0000000..28f38bd
--- /dev/null
+++ b/ClassCrawler/Combat/LootResolver.cs
@@ -0,0 +1,15 @@
+using ClassCrawler.Characters;
+using ClassCrawler.Items;
+
+namespace ClassCrawler.Combat;
+
+/// Resolves the loot dropped by a defeated enemy.
+public class LootResolver
+{
+ /// Returns the list of items dropped by the given enemy.
+ public List
- ResolveLoot(Enemy enemy)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Combat/MagicStrategy.cs b/ClassCrawler/Combat/MagicStrategy.cs
new file mode 100644
index 0000000..c07d3d7
--- /dev/null
+++ b/ClassCrawler/Combat/MagicStrategy.cs
@@ -0,0 +1,14 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// A magic-based combat strategy that uses spells to deal damage.
+public class MagicStrategy : ICombatStrategy
+{
+ /// Executes a magic attack from attacker to target.
+ public CombatResult Execute(Character attacker, Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Combat/MeleeStrategy.cs b/ClassCrawler/Combat/MeleeStrategy.cs
new file mode 100644
index 0000000..e4bcc7d
--- /dev/null
+++ b/ClassCrawler/Combat/MeleeStrategy.cs
@@ -0,0 +1,14 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// A close-range physical combat strategy.
+public class MeleeStrategy : ICombatStrategy
+{
+ /// Executes a melee attack from attacker to target.
+ public CombatResult Execute(Character attacker, Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Combat/RangedStrategy.cs b/ClassCrawler/Combat/RangedStrategy.cs
new file mode 100644
index 0000000..d4788aa
--- /dev/null
+++ b/ClassCrawler/Combat/RangedStrategy.cs
@@ -0,0 +1,14 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Combat;
+
+/// A ranged combat strategy that attacks from a distance.
+public class RangedStrategy : ICombatStrategy
+{
+ /// Executes a ranged attack from attacker to target.
+ public CombatResult Execute(Character attacker, Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Events/EnemyDefeatedEvent.cs b/ClassCrawler/Events/EnemyDefeatedEvent.cs
new file mode 100644
index 0000000..0ec23a1
--- /dev/null
+++ b/ClassCrawler/Events/EnemyDefeatedEvent.cs
@@ -0,0 +1,9 @@
+namespace ClassCrawler.Events;
+
+/// Event raised when an enemy is defeated in combat.
+public class EnemyDefeatedEvent : GameEvent
+{
+ /// Initialises an EnemyDefeatedEvent with a default message.
+ public EnemyDefeatedEvent(string message)
+ : base(GameEventType.EnemyDefeated, message) { }
+}
diff --git a/ClassCrawler/Events/GameEvent.cs b/ClassCrawler/Events/GameEvent.cs
new file mode 100644
index 0000000..f41e55b
--- /dev/null
+++ b/ClassCrawler/Events/GameEvent.cs
@@ -0,0 +1,18 @@
+namespace ClassCrawler.Events;
+
+/// Abstract base class for all game events.
+public abstract class GameEvent
+{
+ /// The category of this event.
+ public GameEventType EventType { get; }
+
+ /// A human-readable message describing what happened.
+ public string Message { get; }
+
+ /// Initialises a new GameEvent with the given type and message.
+ protected GameEvent(GameEventType eventType, string message)
+ {
+ EventType = eventType;
+ Message = message;
+ }
+}
diff --git a/ClassCrawler/Events/GameEventSystem.cs b/ClassCrawler/Events/GameEventSystem.cs
new file mode 100644
index 0000000..02f7b8e
--- /dev/null
+++ b/ClassCrawler/Events/GameEventSystem.cs
@@ -0,0 +1,26 @@
+namespace ClassCrawler.Events;
+
+/// Global publish/subscribe system for game events.
+public static class GameEventSystem
+{
+ /// Registers a listener to receive future events.
+ public static void Subscribe(IGameEventListener listener)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Removes a previously registered listener.
+ public static void Unsubscribe(IGameEventListener listener)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Broadcasts a game event to all registered listeners.
+ public static void Publish(GameEvent gameEvent)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Events/GameEventType.cs b/ClassCrawler/Events/GameEventType.cs
new file mode 100644
index 0000000..a00545c
--- /dev/null
+++ b/ClassCrawler/Events/GameEventType.cs
@@ -0,0 +1,17 @@
+namespace ClassCrawler.Events;
+
+/// Categorises the types of events that can occur during gameplay.
+public enum GameEventType
+{
+ /// Fired when the player gains enough experience to level up.
+ PlayerLevelUp,
+
+ /// Fired when an enemy is defeated in combat.
+ EnemyDefeated,
+
+ /// Fired when the player picks up an item.
+ ItemPickedUp,
+
+ /// Fired when the player's health reaches zero.
+ PlayerDeath
+}
diff --git a/ClassCrawler/Events/IGameEventListener.cs b/ClassCrawler/Events/IGameEventListener.cs
new file mode 100644
index 0000000..6f5d729
--- /dev/null
+++ b/ClassCrawler/Events/IGameEventListener.cs
@@ -0,0 +1,8 @@
+namespace ClassCrawler.Events;
+
+/// Defines a listener that can receive and react to game events.
+public interface IGameEventListener
+{
+ /// Called whenever a game event is published to the event system.
+ void OnEvent(GameEvent gameEvent);
+}
diff --git a/ClassCrawler/Events/ItemPickedUpEvent.cs b/ClassCrawler/Events/ItemPickedUpEvent.cs
new file mode 100644
index 0000000..f13e143
--- /dev/null
+++ b/ClassCrawler/Events/ItemPickedUpEvent.cs
@@ -0,0 +1,9 @@
+namespace ClassCrawler.Events;
+
+/// Event raised when the player picks up an item.
+public class ItemPickedUpEvent : GameEvent
+{
+ /// Initialises an ItemPickedUpEvent with a default message.
+ public ItemPickedUpEvent(string message)
+ : base(GameEventType.ItemPickedUp, message) { }
+}
diff --git a/ClassCrawler/Events/PlayerDeathEvent.cs b/ClassCrawler/Events/PlayerDeathEvent.cs
new file mode 100644
index 0000000..2b8b124
--- /dev/null
+++ b/ClassCrawler/Events/PlayerDeathEvent.cs
@@ -0,0 +1,9 @@
+namespace ClassCrawler.Events;
+
+/// Event raised when the player's health reaches zero.
+public class PlayerDeathEvent : GameEvent
+{
+ /// Initialises a PlayerDeathEvent with a default message.
+ public PlayerDeathEvent(string message)
+ : base(GameEventType.PlayerDeath, message) { }
+}
diff --git a/ClassCrawler/Events/PlayerLevelUpEvent.cs b/ClassCrawler/Events/PlayerLevelUpEvent.cs
new file mode 100644
index 0000000..af56362
--- /dev/null
+++ b/ClassCrawler/Events/PlayerLevelUpEvent.cs
@@ -0,0 +1,9 @@
+namespace ClassCrawler.Events;
+
+/// Event raised when the player gains a level.
+public class PlayerLevelUpEvent : GameEvent
+{
+ /// Initialises a PlayerLevelUpEvent with a default message.
+ public PlayerLevelUpEvent(string message)
+ : base(GameEventType.PlayerLevelUp, message) { }
+}
diff --git a/ClassCrawler/Items/Armor.cs b/ClassCrawler/Items/Armor.cs
new file mode 100644
index 0000000..b1a1552
--- /dev/null
+++ b/ClassCrawler/Items/Armor.cs
@@ -0,0 +1,17 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Items;
+
+/// Armor that increases the wearer's defense.
+public class Armor : Item
+{
+ /// The bonus added to the character's defense stat.
+ public int DefenseBonus { get; set; }
+
+ /// Equips this armor, applying its defense bonus to the target.
+ public override void Use(Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Items/Item.cs b/ClassCrawler/Items/Item.cs
new file mode 100644
index 0000000..8385926
--- /dev/null
+++ b/ClassCrawler/Items/Item.cs
@@ -0,0 +1,19 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Items;
+
+/// Abstract base class for all items in the game.
+public abstract class Item
+{
+ /// The item's display name.
+ public string Name { get; set; } = string.Empty;
+
+ /// A short description of the item.
+ public string Description { get; set; } = string.Empty;
+
+ /// The weight of the item in the player's inventory.
+ public int Weight { get; set; }
+
+ /// Applies this item's effect to the target character.
+ public abstract void Use(Character target);
+}
diff --git a/ClassCrawler/Items/Potion.cs b/ClassCrawler/Items/Potion.cs
new file mode 100644
index 0000000..4e6635a
--- /dev/null
+++ b/ClassCrawler/Items/Potion.cs
@@ -0,0 +1,17 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Items;
+
+/// A consumable potion that restores health to the target character.
+public class Potion : Item
+{
+ /// The number of health points restored when this potion is used.
+ public int HealAmount { get; set; }
+
+ /// Drinks this potion, restoring health to the target character.
+ public override void Use(Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Items/Weapon.cs b/ClassCrawler/Items/Weapon.cs
new file mode 100644
index 0000000..4eb09e5
--- /dev/null
+++ b/ClassCrawler/Items/Weapon.cs
@@ -0,0 +1,17 @@
+using ClassCrawler.Characters;
+
+namespace ClassCrawler.Items;
+
+/// A weapon that increases the wielder's attack power.
+public class Weapon : Item
+{
+ /// The bonus damage added to the character's attack power.
+ public int DamageBonus { get; set; }
+
+ /// Equips this weapon, applying its damage bonus to the target.
+ public override void Use(Character target)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Persistence/GameState.cs b/ClassCrawler/Persistence/GameState.cs
new file mode 100644
index 0000000..4c63944
--- /dev/null
+++ b/ClassCrawler/Persistence/GameState.cs
@@ -0,0 +1,9 @@
+namespace ClassCrawler.Persistence;
+
+/// A serializable snapshot of the current game state.
+public record GameState(
+ string PlayerName,
+ int Health,
+ int Level,
+ string CurrentRoomName,
+ List Inventory);
diff --git a/ClassCrawler/Persistence/IGameRepository.cs b/ClassCrawler/Persistence/IGameRepository.cs
new file mode 100644
index 0000000..a52d257
--- /dev/null
+++ b/ClassCrawler/Persistence/IGameRepository.cs
@@ -0,0 +1,17 @@
+namespace ClassCrawler.Persistence;
+
+/// Defines the contract for persisting and retrieving game data.
+public interface IGameRepository
+{
+ /// Persists the provided game state to storage.
+ void SaveGame(GameState gameState);
+
+ /// Loads a previously saved game state by player name.
+ GameState? LoadGame(string playerName);
+
+ /// Records a player's score on the leaderboard.
+ void SaveScore(string playerName, int score);
+
+ /// Returns all leaderboard entries ordered by score descending.
+ List GetLeaderboard();
+}
diff --git a/ClassCrawler/Persistence/LeaderboardEntry.cs b/ClassCrawler/Persistence/LeaderboardEntry.cs
new file mode 100644
index 0000000..8787359
--- /dev/null
+++ b/ClassCrawler/Persistence/LeaderboardEntry.cs
@@ -0,0 +1,4 @@
+namespace ClassCrawler.Persistence;
+
+/// A single entry in the game leaderboard.
+public record LeaderboardEntry(string PlayerName, int Score, DateTime DateAchieved);
diff --git a/ClassCrawler/Persistence/SqliteGameRepository.cs b/ClassCrawler/Persistence/SqliteGameRepository.cs
new file mode 100644
index 0000000..b09ab14
--- /dev/null
+++ b/ClassCrawler/Persistence/SqliteGameRepository.cs
@@ -0,0 +1,33 @@
+namespace ClassCrawler.Persistence;
+
+/// SQLite-backed implementation of IGameRepository.
+public class SqliteGameRepository : IGameRepository
+{
+ /// Persists the provided game state to the SQLite database.
+ public void SaveGame(GameState gameState)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Loads a previously saved game state from the SQLite database.
+ public GameState? LoadGame(string playerName)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Records a player's score in the SQLite leaderboard table.
+ public void SaveScore(string playerName, int score)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Returns all leaderboard entries from the SQLite database.
+ public List GetLeaderboard()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/Program.cs b/ClassCrawler/Program.cs
new file mode 100644
index 0000000..f90caa2
--- /dev/null
+++ b/ClassCrawler/Program.cs
@@ -0,0 +1,3 @@
+using ClassCrawler.UI;
+
+GameUI.Run();
diff --git a/ClassCrawler/UI/GameUI.cs b/ClassCrawler/UI/GameUI.cs
new file mode 100644
index 0000000..93002de
--- /dev/null
+++ b/ClassCrawler/UI/GameUI.cs
@@ -0,0 +1,42 @@
+namespace ClassCrawler.UI;
+
+/// Manages all console-based user interaction for the game.
+public class GameUI
+{
+ /// Entry point that starts the game and displays the main menu.
+ public static void Run()
+ {
+ Console.WriteLine("Welcome to ClassCrawler!");
+
+ bool running = true;
+ while (running)
+ {
+ Console.WriteLine();
+ Console.WriteLine("1. New Game");
+ Console.WriteLine("2. Load Game");
+ Console.WriteLine("3. Leaderboard");
+ Console.WriteLine("4. Quit");
+ Console.Write("> ");
+
+ string? input = Console.ReadLine();
+ switch (input)
+ {
+ case "1":
+ // TODO: Implement New Game
+ throw new NotImplementedException();
+ case "2":
+ // TODO: Implement Load Game
+ throw new NotImplementedException();
+ case "3":
+ // TODO: Implement Leaderboard
+ throw new NotImplementedException();
+ case "4":
+ running = false;
+ break;
+ default:
+ Console.WriteLine("Invalid option. Please try again.");
+ break;
+ }
+ }
+ }
+}
diff --git a/ClassCrawler/World/Dungeon.cs b/ClassCrawler/World/Dungeon.cs
new file mode 100644
index 0000000..e79001f
--- /dev/null
+++ b/ClassCrawler/World/Dungeon.cs
@@ -0,0 +1,25 @@
+namespace ClassCrawler.World;
+
+/// Represents the entire dungeon and tracks the player's current location.
+public class Dungeon
+{
+ /// All rooms that make up this dungeon.
+ public List Rooms { get; set; } = new();
+
+ /// The room the player is currently in.
+ public Room? CurrentRoom { get; set; }
+
+ /// Attempts to move the player in the given direction.
+ public bool MovePlayer(string direction)
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+
+ /// Creates a small four-room test dungeon and returns it.
+ public static Dungeon GenerateDungeon()
+ {
+ // TODO: Implement
+ throw new NotImplementedException();
+ }
+}
diff --git a/ClassCrawler/World/Room.cs b/ClassCrawler/World/Room.cs
new file mode 100644
index 0000000..b9e71ed
--- /dev/null
+++ b/ClassCrawler/World/Room.cs
@@ -0,0 +1,26 @@
+using ClassCrawler.Characters;
+using ClassCrawler.Items;
+
+namespace ClassCrawler.World;
+
+/// Represents a single room within the dungeon.
+public class Room
+{
+ /// The name of this room.
+ public string Name { get; set; } = string.Empty;
+
+ /// A description of this room's appearance.
+ public string Description { get; set; } = string.Empty;
+
+ /// Enemies currently present in this room.
+ public List Enemies { get; set; } = new();
+
+ /// Items left on the floor of this room.
+ public List
- Items { get; set; } = new();
+
+ /// Indicates whether all enemies in this room have been defeated.
+ public bool IsCleared { get; set; }
+
+ /// Maps compass directions to adjacent rooms.
+ public Dictionary Exits { get; set; } = new();
+}
diff --git a/README.md b/README.md
index 79cb922..3ac4c3d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,51 @@
# ClassCrawler
-A C# dungeon crawler where good object-oriented design is your best weapon
+
+> A C# dungeon crawler where good object-oriented design is your best weapon.
+
+## Overview
+
+ClassCrawler is a turn-based dungeon crawler built with C# and .NET 8.
+It is designed as a **teaching scaffold**: the architecture and interfaces are
+fully defined, but the core method bodies are left unimplemented — your job is
+to bring the game to life.
+
+Work through the namespaces listed below, replace every `// TODO: Implement`
+and `throw new NotImplementedException()` with working code, and watch the
+test suite go green.
+
+## Getting Started
+
+```bash
+# Clone the repository
+git clone https://github.com/Merlissa09/ClassCrawler.git
+cd ClassCrawler
+
+# Run the application
+dotnet run --project ClassCrawler
+```
+
+## Project Structure
+
+```
+ClassCrawler/
+├── ClassCrawler/ # Main console application
+│ ├── Characters/ # Character hierarchy (Player, Enemy, Goblin, Orc, Dragon)
+│ ├── Items/ # Item hierarchy (Weapon, Armor, Potion)
+│ ├── Combat/ # Combat strategies, engine, factory, loot resolver
+│ ├── World/ # Room and Dungeon classes
+│ ├── Events/ # Event system (publish / subscribe)
+│ ├── Persistence/ # Save / load and leaderboard (SQLite)
+│ ├── UI/ # Console UI entry point
+│ └── Program.cs
+├── ClassCrawler.Tests/ # xUnit test project
+│ ├── CombatEngineTests.cs
+│ ├── CombatStrategyTests.cs
+│ ├── ItemTests.cs
+│ ├── InventoryTests.cs
+│ └── LootResolverTests.cs
+└── ClassCrawler.sln
+```
+
+## Contributing
+
+
From e3739127a57883074467d99914df14cae6136c82 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 14 Mar 2026 21:33:07 +0000
Subject: [PATCH 3/5] Replace .slnx with traditional .sln format as required by
spec
Co-authored-by: Merlissa09 <41809281+Merlissa09@users.noreply.github.com>
---
ClassCrawler.sln | 48 +++++++++++++++++++++++++++++++++++++++++++++++
ClassCrawler.slnx | 4 ----
2 files changed, 48 insertions(+), 4 deletions(-)
create mode 100644 ClassCrawler.sln
delete mode 100644 ClassCrawler.slnx
diff --git a/ClassCrawler.sln b/ClassCrawler.sln
new file mode 100644
index 0000000..e27a1e5
--- /dev/null
+++ b/ClassCrawler.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCrawler", "ClassCrawler\ClassCrawler.csproj", "{94F8E38A-9D6D-44D1-866F-2461D88DF238}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCrawler.Tests", "ClassCrawler.Tests\ClassCrawler.Tests.csproj", "{A693E9EC-85B8-418A-9E54-ED5406527BFE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|x64.Build.0 = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Debug|x86.Build.0 = Debug|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|x64.ActiveCfg = Release|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|x64.Build.0 = Release|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|x86.ActiveCfg = Release|Any CPU
+ {94F8E38A-9D6D-44D1-866F-2461D88DF238}.Release|x86.Build.0 = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|x64.Build.0 = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Debug|x86.Build.0 = Debug|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|x64.ActiveCfg = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|x64.Build.0 = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|x86.ActiveCfg = Release|Any CPU
+ {A693E9EC-85B8-418A-9E54-ED5406527BFE}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ClassCrawler.slnx b/ClassCrawler.slnx
deleted file mode 100644
index e33c836..0000000
--- a/ClassCrawler.slnx
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
From 29eddac609196b543a6e2402a31265c2386dfd8d Mon Sep 17 00:00:00 2001
From: Melissa Hegney <41809281+Merlissa09@users.noreply.github.com>
Date: Sat, 14 Mar 2026 17:38:50 -0700
Subject: [PATCH 4/5] Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
ClassCrawler.sln | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ClassCrawler.sln b/ClassCrawler.sln
index e27a1e5..3637984 100644
--- a/ClassCrawler.sln
+++ b/ClassCrawler.sln
@@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCrawler", "ClassCrawler\ClassCrawler.csproj", "{94F8E38A-9D6D-44D1-866F-2461D88DF238}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassCrawler", "ClassCrawler\ClassCrawler.csproj", "{94F8E38A-9D6D-44D1-866F-2461D88DF238}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassCrawler.Tests", "ClassCrawler.Tests\ClassCrawler.Tests.csproj", "{A693E9EC-85B8-418A-9E54-ED5406527BFE}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassCrawler.Tests", "ClassCrawler.Tests\ClassCrawler.Tests.csproj", "{A693E9EC-85B8-418A-9E54-ED5406527BFE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
From a180a6ee7892372cd5614bd372e071003a533f33 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 15 Mar 2026 00:39:17 +0000
Subject: [PATCH 5/5] Reduce Program.cs to a single top-level statement
Co-authored-by: Merlissa09 <41809281+Merlissa09@users.noreply.github.com>
---
ClassCrawler/Program.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/ClassCrawler/Program.cs b/ClassCrawler/Program.cs
index f90caa2..35aca1c 100644
--- a/ClassCrawler/Program.cs
+++ b/ClassCrawler/Program.cs
@@ -1,3 +1 @@
-using ClassCrawler.UI;
-
-GameUI.Run();
+ClassCrawler.UI.GameUI.Run();