push de fin
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
.idea
|
||||
|
||||
204
GaulishVillage/Board.cs
Normal file
204
GaulishVillage/Board.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Board
|
||||
{
|
||||
public List<Building> Buildings { get; private set; } = new();
|
||||
public List<Entity> Entities { get; private set; } = new();
|
||||
public TownHall TownHall { get; private set; }
|
||||
|
||||
public Board()
|
||||
{
|
||||
TownHall = new TownHall(5, 5);
|
||||
Buildings.Add(TownHall);
|
||||
}
|
||||
|
||||
public void AddBuilding(Building b) => Buildings.Add(b);
|
||||
public void AddEntity(Entity e) => Entities.Add(e);
|
||||
|
||||
public void ProcessBuildings()
|
||||
{
|
||||
foreach (var b in Buildings)
|
||||
{
|
||||
if (b is ResourceGenerator rg)
|
||||
rg.Generate();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateEnemies()
|
||||
{
|
||||
foreach (var e in Entities)
|
||||
{
|
||||
if (e is Enemy enemy)
|
||||
enemy.Move();
|
||||
}
|
||||
}
|
||||
|
||||
/*public void Render(Player player)
|
||||
{
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
char c = '.';
|
||||
|
||||
if (player.X == x && player.Y == y)
|
||||
c = 'P';
|
||||
else if (TownHall.X == x && TownHall.Y == y)
|
||||
c = 'H';
|
||||
else
|
||||
{
|
||||
foreach (var b in Buildings)
|
||||
if (b.X == x && b.Y == y)
|
||||
c = 'B';
|
||||
foreach (var e in Entities)
|
||||
if (e.X == x && e.Y == y)
|
||||
c = 'E';
|
||||
}
|
||||
|
||||
Console.Write(c);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}*/
|
||||
/*public void Render(Player player)
|
||||
{
|
||||
Console.Clear();
|
||||
Console.ForegroundColor = ConsoleColor.DarkCyan;
|
||||
Console.WriteLine("╔══════════════════════════════╗");
|
||||
Console.WriteLine("║ Village des Gaulois ║");
|
||||
Console.WriteLine("╚══════════════════════════════╝");
|
||||
Console.ResetColor();
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
{
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
if (player.X == x && player.Y == y)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.Write("P");
|
||||
}
|
||||
else if (TownHall.X == x && TownHall.Y == y)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.Write("H");
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = '.';
|
||||
ConsoleColor color = ConsoleColor.Gray;
|
||||
|
||||
foreach (var b in Buildings)
|
||||
if (b.X == x && b.Y == y)
|
||||
{
|
||||
c = 'B';
|
||||
color = ConsoleColor.Blue;
|
||||
}
|
||||
|
||||
foreach (var e in Entities)
|
||||
if (e.X == x && e.Y == y)
|
||||
{
|
||||
c = 'E';
|
||||
color = ConsoleColor.Red;
|
||||
}
|
||||
|
||||
Console.ForegroundColor = color;
|
||||
Console.Write(c);
|
||||
}
|
||||
Console.ResetColor();
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
Console.WriteLine("────────────────────────────");
|
||||
Console.WriteLine($"Gold: {player.Gold} | Elixir: {player.Elixir} | Position: ({player.X},{player.Y})");
|
||||
Console.WriteLine("↑ ↓ ← → : bouger | G: mine | E: élixir | W: mur | B: caserne | C: collecter | T: troupe");
|
||||
}*/
|
||||
public void Render(Player player)
|
||||
{
|
||||
Console.Clear();
|
||||
|
||||
int width = 20;
|
||||
int height = 20;
|
||||
|
||||
// Affichage carte
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
char c = ' ';
|
||||
ConsoleColor color = ConsoleColor.Gray;
|
||||
|
||||
if (player.X == x && player.Y == y)
|
||||
{
|
||||
c = 'P';
|
||||
color = ConsoleColor.Green;
|
||||
}
|
||||
else if (TownHall.X == x && TownHall.Y == y)
|
||||
{
|
||||
c = 'H';
|
||||
color = ConsoleColor.Yellow;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var b in Buildings)
|
||||
{
|
||||
if (b.X == x && b.Y == y)
|
||||
{
|
||||
if (b is Wall)
|
||||
{
|
||||
c = 'W';
|
||||
color = ConsoleColor.DarkGray;
|
||||
}
|
||||
else if (b is Barrack)
|
||||
{
|
||||
c = 'B';
|
||||
color = ConsoleColor.Blue;
|
||||
}
|
||||
else if (b is GoldMine)
|
||||
{
|
||||
c = 'G';
|
||||
color = ConsoleColor.Yellow;
|
||||
}
|
||||
else if (b is ElixirCollector)
|
||||
{
|
||||
c = 'E';
|
||||
color = ConsoleColor.Magenta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var e in Entities)
|
||||
{
|
||||
if (e.X == x && e.Y == y && e is Enemy)
|
||||
{
|
||||
c = 'R';
|
||||
color = ConsoleColor.Red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.ForegroundColor = color;
|
||||
Console.Write(c);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
// Panneau info
|
||||
Console.WriteLine("────────────────────────────");
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine($"Score: {player.Gold + player.Elixir}");
|
||||
Console.WriteLine($"Gold: {player.Gold}");
|
||||
Console.WriteLine($"Elixir: {player.Elixir}");
|
||||
Console.WriteLine($"TownHall HP: {TownHall.HP}");
|
||||
Console.WriteLine($"Entities: {Entities.Count}");
|
||||
Console.ResetColor();
|
||||
|
||||
Console.WriteLine("────────────────────────────");
|
||||
Console.WriteLine("Commands: ↑↓←→ Move | G GoldMine | E Elixir | W Wall | B Barrack | C Collect | T Train | Q Quit");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
6
GaulishVillage/Buildings/Barrack.cs
Normal file
6
GaulishVillage/Buildings/Barrack.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Barrack : Building
|
||||
{
|
||||
public override string ToString() => $"🏹 Barrack";
|
||||
}
|
||||
8
GaulishVillage/Buildings/Building.cs
Normal file
8
GaulishVillage/Buildings/Building.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public abstract class Building
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int HP { get; set; } = 10;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class ElixirCollector : ResourceGenerator
|
||||
{
|
||||
public override void Generate() => Stock += 3;
|
||||
public override string ToString() => $"🧪 Elixir Collector (Stock: {Stock})";
|
||||
}
|
||||
7
GaulishVillage/Buildings/ResourceGenerator/GoldMine.cs
Normal file
7
GaulishVillage/Buildings/ResourceGenerator/GoldMine.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class GoldMine : ResourceGenerator
|
||||
{
|
||||
public override void Generate() => Stock += 5;
|
||||
public override string ToString() => $"⛏️ Gold Mine (Stock: {Stock})";
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public abstract class ResourceGenerator : Building
|
||||
{
|
||||
public int Stock { get; set; }
|
||||
public abstract void Generate();
|
||||
}
|
||||
13
GaulishVillage/Buildings/TownHall.cs
Normal file
13
GaulishVillage/Buildings/TownHall.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class TownHall : Building
|
||||
{
|
||||
public TownHall(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
HP = 50;
|
||||
}
|
||||
|
||||
public override string ToString() => $"🏛️ Town Hall (HP: {HP})";
|
||||
}
|
||||
6
GaulishVillage/Buildings/Wall.cs
Normal file
6
GaulishVillage/Buildings/Wall.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Wall : Building
|
||||
{
|
||||
public override string ToString() => $"🧱 Wall (HP: {HP})";
|
||||
}
|
||||
17
GaulishVillage/Entity/Entity.cs
Normal file
17
GaulishVillage/Entity/Entity.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public abstract class Entity
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
protected Board Board;
|
||||
|
||||
public Entity(Board board)
|
||||
{
|
||||
Board = board;
|
||||
X = 0;
|
||||
Y = 0;
|
||||
}
|
||||
|
||||
public abstract void Act();
|
||||
}
|
||||
12
GaulishVillage/Entity/Npc/Enemy/Bomberman.cs
Normal file
12
GaulishVillage/Entity/Npc/Enemy/Bomberman.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Bomberman : Enemy
|
||||
{
|
||||
public Bomberman(Board board) : base(board) {}
|
||||
|
||||
public override void Move()
|
||||
{
|
||||
Board.TownHall.HP = 0;
|
||||
Console.WriteLine("💣 Bomberman détruit instantanément le Town Hall !");
|
||||
}
|
||||
}
|
||||
9
GaulishVillage/Entity/Npc/Enemy/Enemy.cs
Normal file
9
GaulishVillage/Entity/Npc/Enemy/Enemy.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public abstract class Enemy : Entity
|
||||
{
|
||||
public Enemy(Board board) : base(board) {}
|
||||
public abstract void Move();
|
||||
|
||||
public override void Act() { Move(); }
|
||||
}
|
||||
36
GaulishVillage/Entity/Npc/Enemy/Raider.cs
Normal file
36
GaulishVillage/Entity/Npc/Enemy/Raider.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Raider : Enemy
|
||||
{
|
||||
public Raider(Board board) : base(board) {}
|
||||
|
||||
public override void Move()
|
||||
{
|
||||
Building closest = null;
|
||||
int minDist = int.MaxValue;
|
||||
|
||||
foreach (var b in Board.Buildings)
|
||||
{
|
||||
int dist = Utils.ManhattanDistance(X, Y, b.X, b.Y);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
closest = b;
|
||||
}
|
||||
}
|
||||
|
||||
if (closest != null)
|
||||
{
|
||||
if (X < closest.X) X++;
|
||||
else if (X > closest.X) X--;
|
||||
else if (Y < closest.Y) Y++;
|
||||
else if (Y > closest.Y) Y--;
|
||||
|
||||
if (X == closest.X && Y == closest.Y)
|
||||
{
|
||||
closest.HP -= 5;
|
||||
Console.WriteLine($"💥 Raider attaque {closest.GetType().Name} !");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
GaulishVillage/Entity/Npc/Trainable/Archer.cs
Normal file
7
GaulishVillage/Entity/Npc/Trainable/Archer.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
|
||||
public class Archer : Trainable
|
||||
{
|
||||
public Archer(Board board) : base(board) {}
|
||||
}
|
||||
6
GaulishVillage/Entity/Npc/Trainable/Barbarian.cs
Normal file
6
GaulishVillage/Entity/Npc/Trainable/Barbarian.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Barbarian : Trainable
|
||||
{
|
||||
public Barbarian(Board board) : base(board) {}
|
||||
}
|
||||
65
GaulishVillage/Entity/Npc/Trainable/Trainable.cs
Normal file
65
GaulishVillage/Entity/Npc/Trainable/Trainable.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
namespace GaulishVillage;
|
||||
public abstract class Trainable : Entity
|
||||
{
|
||||
public bool IsReturning = false;
|
||||
|
||||
public Trainable(Board board) : base(board) {}
|
||||
|
||||
public override void Act()
|
||||
{
|
||||
if (IsReturning)
|
||||
ReturnToTownHall();
|
||||
else
|
||||
AttackEnemies();
|
||||
}
|
||||
|
||||
protected void AttackEnemies()
|
||||
{
|
||||
Enemy closest = null;
|
||||
int minDist = int.MaxValue;
|
||||
|
||||
foreach (var e in Board.Entities)
|
||||
{
|
||||
if (e is Enemy enemy)
|
||||
{
|
||||
int dist = Utils.ManhattanDistance(X, Y, enemy.X, enemy.Y);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
closest = enemy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closest != null)
|
||||
{
|
||||
if (X < closest.X) X++;
|
||||
else if (X > closest.X) X--;
|
||||
else if (Y < closest.Y) Y++;
|
||||
else if (Y > closest.Y) Y--;
|
||||
|
||||
if (X == closest.X && Y == closest.Y)
|
||||
{
|
||||
Board.Entities.Remove(closest);
|
||||
IsReturning = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IsReturning = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ReturnToTownHall()
|
||||
{
|
||||
var th = Board.TownHall;
|
||||
|
||||
if (X < th.X) X++;
|
||||
else if (X > th.X) X--;
|
||||
else if (Y < th.Y) Y++;
|
||||
else if (Y > th.Y) Y--;
|
||||
|
||||
if (X == th.X && Y == th.Y)
|
||||
IsReturning = false;
|
||||
}
|
||||
}
|
||||
76
GaulishVillage/Entity/Player.cs
Normal file
76
GaulishVillage/Entity/Player.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class Player : Entity
|
||||
{
|
||||
public int Gold { get; private set; } = 50;
|
||||
public int Elixir { get; private set; } = 30;
|
||||
|
||||
public Player(Board board) : base(board) {}
|
||||
|
||||
public override void Act() {}
|
||||
|
||||
public void HandleInput()
|
||||
{
|
||||
var key = Console.ReadKey(true).Key;
|
||||
switch (key)
|
||||
{
|
||||
case ConsoleKey.UpArrow: Y--; break;
|
||||
case ConsoleKey.DownArrow: Y++; break;
|
||||
case ConsoleKey.LeftArrow: X--; break;
|
||||
case ConsoleKey.RightArrow: X++; break;
|
||||
case ConsoleKey.G: Build(new GoldMine()); break;
|
||||
case ConsoleKey.E: Build(new ElixirCollector()); break;
|
||||
case ConsoleKey.W: Build(new Wall()); break;
|
||||
case ConsoleKey.B: Build(new Barrack()); break;
|
||||
case ConsoleKey.C: CollectResources(); break;
|
||||
case ConsoleKey.T: TrainTroop(); break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Build(Building b)
|
||||
{
|
||||
b.X = X;
|
||||
b.Y = Y;
|
||||
Board.AddBuilding(b);
|
||||
Gold -= 10;
|
||||
}
|
||||
|
||||
private void CollectResources()
|
||||
{
|
||||
foreach (var b in Board.Buildings)
|
||||
{
|
||||
if (b.X == X && b.Y == Y && b is ResourceGenerator rg && rg.Stock > 0)
|
||||
{
|
||||
if (b is GoldMine)
|
||||
Gold += rg.Stock;
|
||||
else if (b is ElixirCollector)
|
||||
Elixir += rg.Stock;
|
||||
rg.Stock = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TrainTroop()
|
||||
{
|
||||
foreach (var b in Board.Buildings)
|
||||
{
|
||||
if (b.X == X && b.Y == Y && b is Barrack)
|
||||
{
|
||||
if (Elixir >= 10)
|
||||
{
|
||||
var troop = new Archer(Board);
|
||||
Board.AddEntity(troop);
|
||||
Elixir -= 10;
|
||||
Console.WriteLine("✅ Troupe recrutée !");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.WriteLine("❌ Pas de Barrack ou pas assez d'Elixir !");
|
||||
}
|
||||
|
||||
public void ShowStats()
|
||||
{
|
||||
Console.WriteLine($"Gold: {Gold} | Elixir: {Elixir} | Position: ({X},{Y})");
|
||||
}
|
||||
}
|
||||
55
GaulishVillage/GameEngine.cs
Normal file
55
GaulishVillage/GameEngine.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public class GameEngine
|
||||
{
|
||||
public Board Board { get; private set; }
|
||||
public Player Player { get; private set; }
|
||||
|
||||
private int turn = 0;
|
||||
private int raiderSpawnDelay = 5;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Board = new Board();
|
||||
Player = new Player(Board);
|
||||
|
||||
Board.AddEntity(Player);
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.Clear();
|
||||
Board.Render(Player);
|
||||
Player.ShowStats();
|
||||
Board.ProcessBuildings();
|
||||
ProcessEnemies();
|
||||
|
||||
Player.HandleInput();
|
||||
|
||||
if (Board.TownHall.HP <= 0)
|
||||
{
|
||||
Console.WriteLine("💥 Le Town Hall est détruit. Partie perdue !");
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(500);
|
||||
turn++;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessEnemies()
|
||||
{
|
||||
if (turn % raiderSpawnDelay == 0 && turn != 0)
|
||||
{
|
||||
Raider raider = new Raider(Board);
|
||||
Board.AddEntity(raider);
|
||||
}
|
||||
|
||||
if (turn == 200)
|
||||
{
|
||||
Bomberman bomber = new Bomberman(Board);
|
||||
Board.AddEntity(bomber);
|
||||
}
|
||||
|
||||
Board.UpdateEnemies();
|
||||
}
|
||||
}
|
||||
10
GaulishVillage/GaulishVillage.csproj
Normal file
10
GaulishVillage/GaulishVillage.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
16
GaulishVillage/GaulishVillage.sln
Normal file
16
GaulishVillage/GaulishVillage.sln
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GaulishVillage", "GaulishVillage\GaulishVillage.csproj", "{80C37C64-D7C5-46E0-9C09-291DD7B10BEE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{80C37C64-D7C5-46E0-9C09-291DD7B10BEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{80C37C64-D7C5-46E0-9C09-291DD7B10BEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{80C37C64-D7C5-46E0-9C09-291DD7B10BEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{80C37C64-D7C5-46E0-9C09-291DD7B10BEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
10
GaulishVillage/Program.cs
Normal file
10
GaulishVillage/Program.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
GameEngine game = new GameEngine();
|
||||
game.Start();
|
||||
}
|
||||
}
|
||||
9
GaulishVillage/Utils.cs
Normal file
9
GaulishVillage/Utils.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace GaulishVillage;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public static int ManhattanDistance(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
return Math.Abs(x1 - x2) + Math.Abs(y1 - y2);
|
||||
}
|
||||
}
|
||||
7
GaulishVillage/global.json
Normal file
7
GaulishVillage/global.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.0",
|
||||
"rollForward": "latestMinor",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user