diff --git a/source/Trek-12/ConsoleApp/Program.cs b/source/Trek-12/ConsoleApp/Program.cs index 117e7cb..cb57385 100644 --- a/source/Trek-12/ConsoleApp/Program.cs +++ b/source/Trek-12/ConsoleApp/Program.cs @@ -55,6 +55,7 @@ class Program static void OnGameEnded(object sender, GameEndedEventArgs e) { Console.WriteLine($"The game has ended! Player: {e.CurrentPlayer.Pseudo}"); + Console.WriteLine($"Points: {e.Point}"); } /// @@ -76,7 +77,7 @@ class Program static void OnDiceRolled(object sender, DiceRolledEventArgs e) { Console.WriteLine($"Dice 1: {e.Dice1Value} | Dice 2: {e.Dice2Value}"); - Operation playerOperation = GetPlayerOperation(); + Operation playerOperation = GetPlayerOperation(sender); ((Game)sender).HandlePlayerOperation(playerOperation); } @@ -90,6 +91,19 @@ class Program Console.WriteLine($"Operation: {e.Operation}, Result: {e.Result}"); DisplayOperationTable(((Game)sender).UsedMap.OperationGrid); Cell playerChoice = GetPlayerChoice(); + bool test = ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); + if(!test) + { + Console.WriteLine("Invalid cell. Please choose again."); + Console.WriteLine(); + Console.WriteLine(); + DisplayBoard(((Game)sender).UsedMap); + OnOperationChosen(sender, e); + } + + + + /* try { ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); @@ -106,6 +120,13 @@ class Program playerChoice = GetPlayerChoice(); ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); } + catch (InvalidPlaceResultException err) + { + Console.WriteLine(err.Message); + playerChoice = GetPlayerChoice(); + ((Game)sender).HandlePlayerChoice(playerChoice, e.Result); + } + */ } /// @@ -210,7 +231,7 @@ class Program /// /// /// - static Operation GetPlayerOperation() + static Operation GetPlayerOperation(object? sender) { DisplayOperationOptions(); string? op = Console.ReadLine(); @@ -219,6 +240,20 @@ class Program Console.WriteLine("Invalid operation. Please choose again."); op = Console.ReadLine(); } + int test = Convert.ToInt32(op); + + while(((Game)sender).UsedMap.CheckOperationPossible(test-1)) + { + Console.WriteLine("Invalid operation. Please choose again."); + Console.WriteLine(); + op = Console.ReadLine(); + while (op != "1" && op != "2" && op != "3" && op != "4" && op != "5") + { + Console.WriteLine("Invalid operation. Please choose again."); + op = Console.ReadLine(); + } + test = Convert.ToInt32(op); + } return op switch { diff --git a/source/Trek-12/Models/Events/BoardsUpdateEventArgs.cs b/source/Trek-12/Models/Events/BoardsUpdateEventArgs.cs new file mode 100644 index 0000000..22e205f --- /dev/null +++ b/source/Trek-12/Models/Events/BoardsUpdateEventArgs.cs @@ -0,0 +1,17 @@ +using Models.Game; + +namespace Models.Events +{ + /// + /// Event arguments for when the board change. + /// + public class BoardsUpdateEventArgs : EventArgs + { + public List Boards { get; } + + public BoardsUpdateEventArgs(List board) + { + Boards = board; + } + } +} diff --git a/source/Trek-12/Models/Events/GameEndedEventArgs.cs b/source/Trek-12/Models/Events/GameEndedEventArgs.cs index 7148eeb..fd6ce0c 100644 --- a/source/Trek-12/Models/Events/GameEndedEventArgs.cs +++ b/source/Trek-12/Models/Events/GameEndedEventArgs.cs @@ -9,9 +9,12 @@ namespace Models.Events { public Player CurrentPlayer { get; } - public GameEndedEventArgs(Player winner) + public int? Point { get; } + + public GameEndedEventArgs(Player winner, int? point) { CurrentPlayer = winner; + Point = point; } } } diff --git a/source/Trek-12/Models/Exceptions/InvalidPlaceResultException.cs b/source/Trek-12/Models/Exceptions/InvalidPlaceResultException.cs new file mode 100644 index 0000000..de8fdd0 --- /dev/null +++ b/source/Trek-12/Models/Exceptions/InvalidPlaceResultException.cs @@ -0,0 +1,11 @@ +namespace Models.Exceptions +{ + /// + /// Exception for when the cell is invalid. + /// + public class InvalidPlaceResultException : Exception + { + public InvalidPlaceResultException(string message) : base(message) { } + } +} + diff --git a/source/Trek-12/Models/Game/Game.cs b/source/Trek-12/Models/Game/Game.cs index 11902b0..982b2af 100644 --- a/source/Trek-12/Models/Game/Game.cs +++ b/source/Trek-12/Models/Game/Game.cs @@ -42,7 +42,7 @@ namespace Models.Game // == Events == public event EventHandler GameStarted; public event EventHandler GameEnded; - public event EventHandler BoardUpdated; + public event EventHandler BoardUpdated; public event EventHandler DiceRolled; public event EventHandler OperationChosen; public event EventHandler CellChosen; @@ -159,7 +159,7 @@ namespace Models.Game /// If the operation is MULTIPLICATION, it returns the product of the values of the two dice. /// If the operation is not one of the operations, it throws an ArgumentOutOfRangeException. /// - private int ResultOperation(Operation o) + public int ResultOperation(Operation o) { int result = o switch { @@ -182,13 +182,25 @@ namespace Models.Game /// /// The cell chosen by the player to place the result. /// The result of the dice operation to be placed in the cell. - private void PlaceResult(Cell playerChoice, int result) + private bool PlaceResult(Cell playerChoice, int result) { if (Turn == 1 || GameRules.NearCellIsValid(playerChoice, UsedMap.Boards)) { - playerChoice.Value = result; - BoardUpdated?.Invoke(this, EventArgs.Empty); + for (int i = 0; i < UsedMap.Boards.Count; i++) + { + if (UsedMap.Boards[i].X == playerChoice.X && UsedMap.Boards[i].Y == playerChoice.Y) + { + if (UsedMap.Boards[i].Value != null) + return false; + UsedMap.Boards[i].Value = result; + BoardUpdated?.Invoke(this, new BoardsUpdateEventArgs(UsedMap.Boards)); + return true; + } + } + //playerChoice.Value = result; } + return false; + } /// @@ -242,10 +254,10 @@ namespace Models.Game /// /// Ends the game. /// - private void EndGame() + private void EndGame(int? pts) { _isRunning = false; - GameEnded?.Invoke(this, new GameEndedEventArgs(CurrentPlayer)); + GameEnded?.Invoke(this, new GameEndedEventArgs(CurrentPlayer, pts)); } /// @@ -257,7 +269,17 @@ namespace Models.Game { if (Turn == 20) { - EndGame(); + foreach(var cells in UsedMap.Boards) + { + GameRules.IsZoneValidAndAddToZones(cells, UsedMap); + AddToRopePath(cells, GameRules.EveryAdjacentCells(cells, UsedMap.Boards)); + } + int? points = GameRules.FinalCalculusOfZones(UsedMap.Zones); + for (int i = 0; i < UsedMap.RopePaths.Count; i++) + { + points += GameRules.ScoreRopePaths(UsedMap.RopePaths[i]); + } + EndGame(points); break; } @@ -284,23 +306,31 @@ namespace Models.Game /// /// /// - public void HandlePlayerChoice(Cell cell, int result) + public bool HandlePlayerChoice(Cell cell, int result) { if (cell.X < 0 || cell.X >= UsedMap.Boards.Count / 6 || cell.Y < 0 || cell.Y >= 6) { - throw new InvalidCellCoordinatesException("Invalid cell coordinates. Please choose again."); + return false; + //throw new InvalidCellCoordinatesException("Invalid cell coordinates. Please choose again."); } if (!GameRules.IsCellValid(cell, UsedMap.Boards)) { - throw new InvalidCellException("Cell is not valid. Please choose again."); + return false; + //throw new InvalidCellException("Cell is not valid. Please choose again."); } - PlaceResult(cell, result); + bool res = PlaceResult(cell, result); + if (!res) + { + return false; + //throw new InvalidPlaceResultException("Cell is not valid for place result. Please choose again."); + } GameRules.IsZoneValidAndAddToZones(cell, UsedMap); AddToRopePath(cell, GameRules.EveryAdjacentCells(cell, UsedMap.Boards)); CellChosen?.Invoke(this, new CellChosenEventArgs(cell, result)); - BoardUpdated?.Invoke(this, EventArgs.Empty); + return true; + //BoardUpdated?.Invoke(this, EventArgs.Empty); } } } diff --git a/source/Trek-12/Models/Game/Map.cs b/source/Trek-12/Models/Game/Map.cs index 56dbb69..ccc327b 100644 --- a/source/Trek-12/Models/Game/Map.cs +++ b/source/Trek-12/Models/Game/Map.cs @@ -74,5 +74,10 @@ } return operationGrid; } + + public bool CheckOperationPossible(int x) + { + return OperationGrid[x * 4 + 3].IsChecked; + } } } \ No newline at end of file diff --git a/source/Trek-12/Models/Game/OperationCell.cs b/source/Trek-12/Models/Game/OperationCell.cs index d8ac6da..4667ff0 100644 --- a/source/Trek-12/Models/Game/OperationCell.cs +++ b/source/Trek-12/Models/Game/OperationCell.cs @@ -17,6 +17,7 @@ namespace Models.Game /// public OperationCell(int x, int y) : base(x, y) { + IsChecked = false; } /// diff --git a/source/Trek-12/Models/Rules/Rules.cs b/source/Trek-12/Models/Rules/Rules.cs index 8a7dc43..bd8c8cf 100644 --- a/source/Trek-12/Models/Rules/Rules.cs +++ b/source/Trek-12/Models/Rules/Rules.cs @@ -29,25 +29,39 @@ namespace Models.Rules return true; } + //public bool IsCellAdjacent(Cell choosenCell, Cell targetCell) + //{ + // if (Math.Abs(choosenCell.X - targetCell.X) > 1 || Math.Abs(choosenCell.Y - targetCell.Y) > 1) + // return false; + // if (Math.Abs(choosenCell.X - targetCell.X) > 1 && Math.Abs(choosenCell.Y - targetCell.Y) > 1) + // return false; + // if (choosenCell.X == 0 && targetCell.X == 4) + // return false; + // if (choosenCell.Y == 0 && targetCell.Y == 4) + // return false; + // if (choosenCell.X == 4 && targetCell.X == 0) + // return false; + // if (choosenCell.Y == 4 && targetCell.Y == 0) + // return false; + // if (choosenCell.X == targetCell.X && choosenCell.Y == targetCell.Y) + // return false; + + // return true; + //} + public bool IsCellAdjacent(Cell choosenCell, Cell targetCell) { - if (Math.Abs(choosenCell.X - targetCell.X) > 1 || Math.Abs(choosenCell.Y - targetCell.Y) > 1) - return false; - if (Math.Abs(choosenCell.X - targetCell.X) > 1 && Math.Abs(choosenCell.Y - targetCell.Y) > 1) - return false; - if (choosenCell.X == 0 && targetCell.X == 4) - return false; - if (choosenCell.Y == 0 && targetCell.Y == 4) - return false; - if (choosenCell.X == 4 && targetCell.X == 0) - return false; - if (choosenCell.Y == 4 && targetCell.Y == 0) - return false; - if (choosenCell.X == targetCell.X && choosenCell.Y == targetCell.Y) - return false; + if (Math.Abs(choosenCell.X - targetCell.X) <= 1 && Math.Abs(choosenCell.Y - targetCell.Y) <= 1) + { + if (choosenCell.X != targetCell.X || choosenCell.Y != targetCell.Y) + { + return true; + } + } + + return false; + } - return true; - } public bool IsInRopePaths (Cell adjacente,List> ropePaths,int index) { @@ -70,10 +84,29 @@ namespace Models.Rules } return false; } + //public bool NearCellIsValid(Cell choosenCell, List cells) + //{ + // if (choosenCell == null || cells == null) return false; + + // IEnumerable PlayedCellsQuery = + // from cell in cells + // where cell.Value != null + // select cell; + + // foreach (var cell in PlayedCellsQuery) + // { + // if(!IsCellAdjacent(choosenCell, cell)) continue; + + // return true; + // } + + // return false; + //} + public bool NearCellIsValid(Cell choosenCell, List cells) { if (choosenCell == null || cells == null) return false; - + IEnumerable PlayedCellsQuery = from cell in cells where cell.Value != null @@ -81,14 +114,16 @@ namespace Models.Rules foreach (var cell in PlayedCellsQuery) { - if(!IsCellAdjacent(choosenCell, cell)) continue; - - return true; + if (IsCellAdjacent(choosenCell, cell)) + { + return true; + } } return false; } + public void IsZoneValidAndAddToZones(Cell chosenCell, Map map) { if (chosenCell == null ||chosenCell.Value == null) return; @@ -201,5 +236,22 @@ namespace Models.Rules return calculus; } + public int? ScoreRopePaths(List paths) + { + int? score = 0; + IEnumerable sortPaths = + from cell in paths + orderby cell.Value descending + select cell; + foreach (var item in sortPaths) + { + if (score == 0) + score += item.Value; + else + score++; + } + return score; + } + } } \ No newline at end of file