diff --git a/Data/levels/level_07.json b/Data/levels/level_07.json new file mode 100644 index 0000000..c7b86eb --- /dev/null +++ b/Data/levels/level_07.json @@ -0,0 +1,28 @@ +{ + "id": 7, + "name": "La Dame Blanche", + "description": "La Dame entre en jeu. Sa portee sur 8 directions en fait une piece logistique supreme.", + "width": 10, + "height": 10, + "productions": [ + { "col": 0, "row": 0, "name": "Scierie", "cargo": "wood" }, + { "col": 9, "row": 0, "name": "Carriere", "cargo": "stone" } + ], + "demands": [ + { "col": 9, "row": 9, "name": "Chateau", "cargo": "wood", "amount": 4, "deadline": 50 }, + { "col": 0, "row": 9, "name": "Forge Royale", "cargo": "stone", "amount": 4, "deadline": 50 } + ], + "walls": [ + { "col": 3, "row": 3 }, { "col": 3, "row": 4 }, { "col": 3, "row": 5 }, { "col": 3, "row": 6 }, + { "col": 6, "row": 3 }, { "col": 6, "row": 4 }, { "col": 6, "row": 5 }, { "col": 6, "row": 6 }, + { "col": 4, "row": 6 }, { "col": 5, "row": 6 }, + { "col": 4, "row": 3 }, { "col": 5, "row": 3 } + ], + "stock": [ + { "kind": "pawn", "count": 10 }, + { "kind": "rook", "count": 4 }, + { "kind": "bishop", "count": 2 }, + { "kind": "knight", "count": 2 }, + { "kind": "queen", "count": 1 } + ] +} diff --git a/Data/levels/level_08.json b/Data/levels/level_08.json new file mode 100644 index 0000000..3228b58 --- /dev/null +++ b/Data/levels/level_08.json @@ -0,0 +1,33 @@ +{ + "id": 8, + "name": "Le Grand Reseau", + "description": "Quatre productions, quatre demandes. Construisez un reseau logistique complet a travers un terrain hostile.", + "width": 12, + "height": 10, + "productions": [ + { "col": 0, "row": 0, "name": "Scierie Ouest", "cargo": "wood" }, + { "col": 11, "row": 0, "name": "Carriere Sud", "cargo": "stone" }, + { "col": 0, "row": 9, "name": "Scierie Nord", "cargo": "wood" }, + { "col": 11, "row": 9, "name": "Carriere Nord", "cargo": "stone" } + ], + "demands": [ + { "col": 5, "row": 0, "name": "Depot Sud", "cargo": "wood", "amount": 3, "deadline": 60 }, + { "col": 6, "row": 9, "name": "Depot Nord", "cargo": "stone", "amount": 3, "deadline": 60 }, + { "col": 5, "row": 5, "name": "Forge Centrale", "cargo": "stone", "amount": 4, "deadline": 60 }, + { "col": 6, "row": 4, "name": "Chantier Central", "cargo": "wood", "amount": 4, "deadline": 60 } + ], + "walls": [ + { "col": 3, "row": 2 }, { "col": 3, "row": 3 }, { "col": 3, "row": 4 }, + { "col": 3, "row": 5 }, { "col": 3, "row": 6 }, { "col": 3, "row": 7 }, + { "col": 8, "row": 2 }, { "col": 8, "row": 3 }, { "col": 8, "row": 4 }, + { "col": 8, "row": 5 }, { "col": 8, "row": 6 }, { "col": 8, "row": 7 }, + { "col": 4, "row": 4 }, { "col": 7, "row": 5 } + ], + "stock": [ + { "kind": "pawn", "count": 16 }, + { "kind": "rook", "count": 6 }, + { "kind": "bishop", "count": 3 }, + { "kind": "knight", "count": 4 }, + { "kind": "queen", "count": 2 } + ] +} diff --git a/Scripts/Main.cs b/Scripts/Main.cs index ce303ab..2df6376 100644 --- a/Scripts/Main.cs +++ b/Scripts/Main.cs @@ -46,7 +46,7 @@ public partial class Main : Node2D private bool _running; private bool _panning; - private static readonly string[] LevelFiles = ["level_01.json", "level_02.json", "level_03.json", "level_04.json", "level_05.json", "level_06.json"]; + private static readonly string[] LevelFiles = ["level_01.json", "level_02.json", "level_03.json", "level_04.json", "level_05.json", "level_06.json", "level_07.json", "level_08.json"]; private const float SidePanelWidth = 280f; private const float ControlBarHeight = 48f; diff --git a/Scripts/Pieces/PieceView.cs b/Scripts/Pieces/PieceView.cs index edc934a..68f61f6 100644 --- a/Scripts/Pieces/PieceView.cs +++ b/Scripts/Pieces/PieceView.cs @@ -22,6 +22,7 @@ public partial class PieceView : Node2D private static readonly Color RookColor = new("#3D6B8E"); // deep teal private static readonly Color BishopColor = new("#8E5A6B"); // dusty rose private static readonly Color KnightColor = new("#8E7A3D"); // burnt sienna + private static readonly Color QueenColor = new("#8E3D5A"); // deep burgundy private static readonly Color WoodCargoColor = new("#A67C32"); private static readonly Color StoneCargoColor = new("#7A7A7A"); private static readonly Color ShadowColor = new Color(0, 0, 0, 0.18f); @@ -77,6 +78,7 @@ public partial class PieceView : Node2D PieceKind.Rook => "T", PieceKind.Bishop => "F", PieceKind.Knight => "C", + PieceKind.Queen => "D", _ => "?" }, HorizontalAlignment = HorizontalAlignment.Center, @@ -113,6 +115,7 @@ public partial class PieceView : Node2D PieceKind.Rook => RookColor, PieceKind.Bishop => BishopColor, PieceKind.Knight => KnightColor, + PieceKind.Queen => QueenColor, _ => Colors.White }; diff --git a/Scripts/UI/DetailPanel.cs b/Scripts/UI/DetailPanel.cs index 5ffb0ea..db4e95b 100644 --- a/Scripts/UI/DetailPanel.cs +++ b/Scripts/UI/DetailPanel.cs @@ -66,6 +66,7 @@ public partial class DetailPanel : PanelContainer PieceKind.Rook => "Tour II", PieceKind.Bishop => "Fou II", PieceKind.Knight => "Cavalier", + PieceKind.Queen => "Dame", _ => piece.Kind.ToString() }; diff --git a/Scripts/UI/LevelSelectScreen.cs b/Scripts/UI/LevelSelectScreen.cs index a96df39..51ab53e 100644 --- a/Scripts/UI/LevelSelectScreen.cs +++ b/Scripts/UI/LevelSelectScreen.cs @@ -15,7 +15,9 @@ public partial class LevelSelectScreen : Control ("Le Col", "Franchissez le mur et gerez deux types de cargaison."), ("Le Carrefour", "Deux productions, deux demandes, et un carrefour au centre."), ("Le Labyrinthe", "Un couloir etroit serpente a travers les murs."), - ("Trois Royaumes", "Trois productions, trois demandes. Gerez un reseau complet.") + ("Trois Royaumes", "Trois productions, trois demandes. Gerez un reseau complet."), + ("La Dame Blanche", "La Dame entre en jeu. Portee supreme sur 8 directions."), + ("Le Grand Reseau", "Quatre productions, quatre demandes. Reseau complet.") ]; public override void _Ready() diff --git a/Scripts/UI/PieceStockPanel.cs b/Scripts/UI/PieceStockPanel.cs index dc40b83..e2ec0f6 100644 --- a/Scripts/UI/PieceStockPanel.cs +++ b/Scripts/UI/PieceStockPanel.cs @@ -154,6 +154,7 @@ public partial class PieceStockPanel : VBoxContainer PieceKind.Rook => "Tour II", PieceKind.Bishop => "Fou II", PieceKind.Knight => "Cavalier", + PieceKind.Queen => "Dame", _ => kind.ToString() }; } diff --git a/chessistics-engine/Loading/LevelLoader.cs b/chessistics-engine/Loading/LevelLoader.cs index b1aff21..da09b91 100644 --- a/chessistics-engine/Loading/LevelLoader.cs +++ b/chessistics-engine/Loading/LevelLoader.cs @@ -56,6 +56,7 @@ public static class LevelLoader "rook" => PieceKind.Rook, "bishop" => PieceKind.Bishop, "knight" => PieceKind.Knight, + "queen" => PieceKind.Queen, _ => throw new JsonException($"Unknown piece kind: '{kind}'") }; diff --git a/chessistics-engine/Model/PieceKind.cs b/chessistics-engine/Model/PieceKind.cs index c507773..188ab6e 100644 --- a/chessistics-engine/Model/PieceKind.cs +++ b/chessistics-engine/Model/PieceKind.cs @@ -5,5 +5,6 @@ public enum PieceKind Pawn, Rook, Bishop, - Knight + Knight, + Queen } diff --git a/chessistics-engine/Model/PieceRules.cs b/chessistics-engine/Model/PieceRules.cs index ea0c19c..76c2e12 100644 --- a/chessistics-engine/Model/PieceRules.cs +++ b/chessistics-engine/Model/PieceRules.cs @@ -8,6 +8,7 @@ public static class PieceRules PieceKind.Rook => 5, PieceKind.Bishop => 3, PieceKind.Knight => 3, + PieceKind.Queen => 7, _ => throw new ArgumentOutOfRangeException(nameof(kind)) }; @@ -17,6 +18,7 @@ public static class PieceRules PieceKind.Rook => 2, PieceKind.Bishop => 2, PieceKind.Knight => 0, // Knight uses L-shape, not range + PieceKind.Queen => 2, _ => throw new ArgumentOutOfRangeException(nameof(kind)) }; } diff --git a/chessistics-engine/Rules/MoveValidator.cs b/chessistics-engine/Rules/MoveValidator.cs index fd5805d..7f79f4a 100644 --- a/chessistics-engine/Rules/MoveValidator.cs +++ b/chessistics-engine/Rules/MoveValidator.cs @@ -6,6 +6,7 @@ public static class MoveValidator { private static readonly (int dc, int dr)[] OrthogonalDirs = [(0, 1), (0, -1), (1, 0), (-1, 0)]; private static readonly (int dc, int dr)[] DiagonalDirs = [(1, 1), (1, -1), (-1, 1), (-1, -1)]; + private static readonly (int dc, int dr)[] AllDirs = [(0, 1), (0, -1), (1, 0), (-1, 0), (1, 1), (1, -1), (-1, 1), (-1, -1)]; private static readonly (int dc, int dr)[] KnightOffsets = [ (1, 2), (2, 1), (2, -1), (1, -2), @@ -23,6 +24,7 @@ public static class MoveValidator PieceKind.Rook => GetSlidingMoves(start, OrthogonalDirs, 2, board), PieceKind.Bishop => GetSlidingMoves(start, DiagonalDirs, 2, board), PieceKind.Knight => GetKnightMoves(start, board), + PieceKind.Queen => GetSlidingMoves(start, AllDirs, 2, board), _ => [] }; } diff --git a/docs/GDD_prototype.md b/docs/GDD_prototype.md index d47080f..4c23f3a 100644 --- a/docs/GDD_prototype.md +++ b/docs/GDD_prototype.md @@ -145,6 +145,24 @@ C'est tout. Pas de programmation, pas de route multi-etapes. La piece fait l'all - **Saute par-dessus** les murs et les autres pieces - Statut social : **3** +#### Dame + +``` + X X X + X X X + X X X + X X X [Dame] X X X + X X X + X X X + X X X +``` + +- Se deplace de **1 ou 2 cases** dans les **8 directions** (horizontal, vertical et diagonal) +- Combine les mouvements de la Tour et du Fou +- Ne peut pas traverser les murs ni les autres pieces +- Statut social : **7** (le plus eleve — prioritaire sur toutes les autres pieces) +- Piece la plus puissante mais rare — force des choix strategiques + > A statut egal, la piece de **niveau le plus eleve** est consideree superieure (ex: Tour II > Tour I, Fou III > Cavalier II). En cas d'egalite parfaite, le departage se fait par **direction en sens horaire** depuis la piece qui donne (voir 4.3). ### 3.3 Occupation et collision @@ -188,6 +206,7 @@ Quand plusieurs transferts sont possibles au meme point, la priorite determine l ``` Hierarchie de statut social (proto) : + Dame 7 Tour 5 Fou 3 Cavalier 3