Merge GameLoop into dev (#108)
continuous-integration/drone/push Build is failing Details

pull/111/head
Rémi LAVERGNE 11 months ago
commit ac940759a5

@ -5,11 +5,17 @@ using Models.Events;
using Models.Game;
using Models.Interfaces;
using DataContractPersistence;
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace ConsoleApp;
class Program
{
static Game Game { get; set; }
/// <summary>
/// Main function of the console app
/// </summary>
@ -24,21 +30,131 @@ class Program
Player player = new Player(pseudo, "test.png");
Map map = new Map("Dunai","background");
Game game = new Game(persistence);
Game = new Game(persistence);
// Abonnement aux événements
game.GameStarted += OnGameStarted!;
game.GameEnded += OnGameEnded!;
game.BoardUpdated += OnBoardUpdated!;
game.DiceRolled += OnDiceRolled!;
game.OperationChosen += OnOperationChosen!;
game.CellChosen += OnCellChosen!;
Game.GameStarted += OnGameStarted!;
Game.GameEnded += OnGameEnded!;
Game.BoardUpdated += OnBoardUpdated!;
Game.DiceRolled += OnDiceRolled!;
Game.OperationChosen += OnOperationChosen!;
Game.CellChosen += OnCellChosen!;
Game.PlayerChooseOp += OnPlayerSelectionOp!;
Game.PlayerOption += OnPlayerOption!;
Game.PlayerChooseCell += OnPlayerSelectionCell!;
// Initialisation
game.InitializeGame(map, player);
Game.InitializeGame(map, player);
}
}
static void OnPlayerSelectionCell(Object sender, PlayerChooseCellEventArgs e)
{
int row, column;
while (true)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Enter the position of the cell you want to play");
Console.WriteLine("Enter the row number (0-6)");
Console.ResetColor();
if (!int.TryParse(Console.ReadLine(), out row) || row < 0 || row >= 7)
{
Console.ForegroundColor= ConsoleColor.Red;
Console.WriteLine("Invalid row number. Please enter a number between 0 and 6.");
Console.ResetColor();
continue;
}
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Enter the column number (0-6)");
Console.ResetColor();
if (!int.TryParse(Console.ReadLine(), out column) || column < 0 || column >= 7)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid column number. Please enter a number between 0 and 6.");
Console.ResetColor();
continue;
}
Game.PlayerCell = new Cell(row, column);
break;
}
}
static void OnPlayerOption(object sender, PlayerOptionEventArgs e)
{
Console.WriteLine();
if(e.Turn != 1)
{
IEnumerable<Cell> PlayedCellsQuery =
from cell in e.Board
where cell.Valid == true
where cell.Value != null
select cell;
foreach (var item in e.Board)
{
if (item.X == 6)
Console.WriteLine();
if (!item.Valid)
Console.Write(" ");
else if (item.Value != null)
Console.Write($"{item.Value}");
else
{
foreach (var item1 in PlayedCellsQuery)
{
if (Math.Abs(item.X - item1.X) <= 1 && Math.Abs(item.Y - item1.Y) <= 1)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write($"{e.Resultat}");
Console.ResetColor();
}
}
}
}
return;
}
foreach (var item in e.Board)
{
if (!item.Valid)
Console.Write(" ");
else
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write($"{e.Resultat}");
Console.ResetColor();
}
if (item.X == 6)
Console.WriteLine();
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Choose an Available cell.");
Console.ResetColor();
}
static void OnPlayerSelectionOp(object sender, PlayerChooseOperationEventArgs e)
{
Console.WriteLine();
DisplayOperationTable(((Game)sender).UsedMap.OperationGrid.ToList());
Console.WriteLine();
Console.WriteLine("0. Lower | 1. Higher | 2. Substraction | 3. Addition | 4. Multiplication");
string? op = Console.ReadLine();
while (op != "0" && op != "1" && op != "2" && op != "3" && op != "4")
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid operation. Please choose again.");
Console.ResetColor();
op = Console.ReadLine();
}
int test = Convert.ToInt32(op);
Game.PlayerOperation = (Operation)test;
}
/// <summary>
/// Handles the event when the game has started.
/// </summary>
@ -65,10 +181,18 @@ class Program
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void OnBoardUpdated(object sender, EventArgs e)
static void OnBoardUpdated(object sender, BoardsUpdateEventArgs e)
{
DisplayBoard(((Game)sender).UsedMap);
DisplayOperationTable(((Game)sender).UsedMap.OperationGrid.ToList());
foreach (var item in e.Boards)
{
if (!item.Valid)
Console.Write(" ");
else if (item.Value != null)
Console.Write($"{item.Value}");
else Console.Write("O");
if (item.X == 6)
Console.WriteLine();
}
}
/// <summary>
@ -78,9 +202,12 @@ class Program
/// <param name="e"></param>
static void OnDiceRolled(object sender, DiceRolledEventArgs e)
{
// Console.Clear();
Console.WriteLine($"Dice 1: {e.Dice1Value} | Dice 2: {e.Dice2Value}");
Operation playerOperation = GetPlayerOperation(sender);
((Game)sender).HandlePlayerOperation(playerOperation);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Choose an operation.");
Console.ResetColor();
}
/// <summary>
@ -180,24 +307,28 @@ class Program
/// <param name="operationTable">The operation table to display.</param>
static void DisplayOperationTable(List<OperationCell> operationTable)
{
Console.WriteLine("Operation Table:");
string[] operations = { "Addition (+)", "Subtraction (-)", "Multiplication (*)", "Lower Dice (less)", "Higher Dice (high)" };
for (int i = 0; i < operations.Length; i++)
Console.ForegroundColor = ConsoleColor.Yellow;
foreach ( var cell in operationTable)
{
Console.Write(operations[i].PadRight(18));
for (int j = 0; j < 4; j++)
{
int index = i * 4 + j;
if (index < operationTable.Count)
{
string status = operationTable[index].IsChecked ? "X" : " ";
Console.Write($" | {status}");
}
}
if (cell.X == 0 && cell.Y == 0)
Console.Write("Lower => ");
if (cell.X == 0 && cell.Y == 1)
Console.Write("Higher => ");
if (cell.X == 0 && cell.Y == 2)
Console.Write("Substraction => ");
if (cell.X == 0 && cell.Y == 3)
Console.Write("Addition => ");
if (cell.X == 0 && cell.Y == 4)
Console.Write("Multiplication => ");
if (cell.IsChecked)
Console.Write("X | ");
if (!cell.IsChecked)
Console.Write(" | ");
if (cell.X == 3)
Console.WriteLine();
}
Console.ResetColor();
}
/// <summary>

@ -7,7 +7,7 @@ namespace Models.Events
/// </summary>
public class BoardsUpdateEventArgs : EventArgs
{
public List<Cell> Boards { get; }
public List<Cell> Boards { get; set; }
public BoardsUpdateEventArgs(List<Cell> board)
{

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Models.Game;
namespace Models.Events
{
public class PlayerChooseCellEventArgs : EventArgs
{
public Cell Cell { get; set; }
public PlayerChooseCellEventArgs(Cell cell)
{
Cell = cell;
}
}
}

@ -0,0 +1,19 @@
using Models.Game;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Events
{
public class PlayerChooseOperationEventArgs : EventArgs
{
public Operation PlayerOp { get; set; }
public PlayerChooseOperationEventArgs(Operation op)
{
PlayerOp = op;
}
}
}

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Models.Game;
namespace Models.Events
{
public class PlayerOptionEventArgs : EventArgs
{
public List<Cell> Board { get; set; }
public int Resultat { get; set; }
public int Turn { get; set; }
public PlayerOptionEventArgs(List<Cell> boards, int resultat, int turn)
{
Board = boards;
Resultat = resultat;
Turn = turn;
}
}
}

@ -101,6 +101,10 @@ namespace Models.Game
[DataMember]
public int Turn { get; private set; }
public Operation PlayerOperation { get; set; }
public Cell PlayerCell { get; set; }
public Rules.Rules GameRules { get; }
@ -111,6 +115,10 @@ namespace Models.Game
public event EventHandler<DiceRolledEventArgs> DiceRolled;
public event EventHandler<OperationChosenEventArgs> OperationChosen;
public event EventHandler<CellChosenEventArgs> CellChosen;
public event EventHandler<PlayerChooseOperationEventArgs> PlayerChooseOp;
public event EventHandler<PlayerOptionEventArgs> PlayerOption;
public event EventHandler<PlayerChooseCellEventArgs> PlayerChooseCell;
public void AddPlayer(Player player)
{
@ -259,7 +267,7 @@ namespace Models.Game
/// Marks an operation as checked in the operation grid of the game.
/// </summary>
/// <param name="operation"></param>
public void MarkOperationAsChecked(Operation operation)
private void MarkOperationAsChecked(Operation operation)
{
int operationIndex = (int)operation;
IEnumerable<OperationCell> sortPaths =
@ -299,8 +307,6 @@ namespace Models.Game
Operation.MULTIPLICATION => Dice2.Value * Dice1.Value,
_ => throw new ArgumentOutOfRangeException()
};
MarkOperationAsChecked(o);
return result;
}
@ -311,28 +317,19 @@ namespace Models.Game
/// </summary>
/// <param name="playerChoice">The cell chosen by the player to place the result.</param>
/// <param name="result">The result of the dice operation to be placed in the cell.</param>
private bool PlaceResult(Cell playerChoice, int result)
private void PlaceResult(Cell playerChoice, int result)
{
if (Turn == 1 || GameRules.NearCellIsValid(playerChoice, UsedMap.Boards.ToList()))
{
for (int i = 0; i < UsedMap.Boards.Count; i++)
{
if (UsedMap.Boards[i].X == playerChoice.X && UsedMap.Boards[i].Y == playerChoice.Y)
IEnumerable<Cell> ValidCell =
from cell in UsedMap.Boards
where cell.Value == null
where cell.Valid == true
select cell;
foreach (var item in ValidCell)
{
if (UsedMap.Boards[i].Value != null)
return false;
UsedMap.Boards[i].Value = result;
if ((UsedMap.Boards[i].IsDangerous && result > 6) || result > 12)
UsedMap.Boards[i].SetPenalty();
BoardUpdated?.Invoke(this, new BoardsUpdateEventArgs(UsedMap.Boards.ToList()));
return true;
if(item.X == playerChoice.X && item.Y == playerChoice.Y)
item.Value = result;
}
}
//playerChoice.Value = result;
}
return false;
}
/// <summary>
/// Add the choosen cell to a rope path if it's possible.
@ -413,28 +410,38 @@ namespace Models.Game
/// </summary>
private void GameLoop()
{
int res = 0,turn = 1;
Cell cell;
while (IsRunning)
{
if (Turn == 20)
{
foreach(var cells in UsedMap.Boards.ToList())
{
GameRules.IsZoneValidAndAddToZones(cells, UsedMap);
AddToRopePath(cells, GameRules.EveryAdjacentCells(cells, UsedMap.Boards.ToList()));
RollAllDice();
res = PlayerChooseOperation();
PlayerOption?.Invoke(this,new PlayerOptionEventArgs(UsedMap.Boards.ToList(),res,turn));
PlayerSelectionCell();
PlaceResult(PlayerCell,res);
BoardUpdated?.Invoke(this, new BoardsUpdateEventArgs(UsedMap.Boards.ToList()));
turn++;
}
int? points = GameRules.FinalCalculusOfZones(UsedMap.Zones);
for (int i = 0; i < UsedMap.RopePaths.Count; i++)
}
public int PlayerChooseOperation()
{
points += GameRules.ScoreRopePaths(UsedMap.RopePaths[i]);
PlayerChooseOp?.Invoke(this, new PlayerChooseOperationEventArgs(PlayerOperation));
while(!GameRules.OperationAvailable(PlayerOperation,UsedMap.OperationGrid.ToList()))
{
PlayerChooseOp?.Invoke(this, new PlayerChooseOperationEventArgs(PlayerOperation));
}
EndGame(points);
break;
return ResultOperation(PlayerOperation);
}
RollAllDice();
Turn++;
public void PlayerSelectionCell()
{
PlayerChooseCell?.Invoke(this,new PlayerChooseCellEventArgs(PlayerCell));
while(!GameRules.NearCellIsValid(PlayerCell,UsedMap.Boards.ToList()))
{
PlayerChooseCell?.Invoke(this, new PlayerChooseCellEventArgs(PlayerCell));
}
MarkOperationAsChecked(PlayerOperation);
}
/// <summary>
@ -468,7 +475,7 @@ namespace Models.Game
//throw new InvalidCellException("Cell is not valid. Please choose again.");
}
bool res = PlaceResult(cell, result);
bool res = true;
if (!res)
{
return false;

@ -72,7 +72,7 @@ namespace Models.Game
{
for (int i = 0; i < 49; i++) // 7x7 board
{
board.Add(new Cell(i / 7, i % 7));
board.Add(new Cell(i % 7, i / 7));
}
board[1].Valid = true;
board[3].Valid = true;

@ -34,12 +34,9 @@ namespace Models.Rules
public bool IsCellAdjacent(Cell choosenCell, Cell targetCell)
{
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;
}
@ -73,15 +70,16 @@ namespace Models.Rules
IEnumerable<Cell> PlayedCellsQuery =
from cell in cells
where cell.Value != null
where cell.Valid == true
select cell;
foreach (var cell in PlayedCellsQuery)
{
if (choosenCell.X == cell.X && choosenCell.Y == cell.Y && cell.Value == null)
return true;
if (IsCellAdjacent(choosenCell, cell))
{
return true;
}
}
return false;
@ -217,5 +215,19 @@ namespace Models.Rules
return score;
}
public bool OperationAvailable(Operation operation,List<OperationCell> operationGrid)
{
IEnumerable<OperationCell> row =
from cell in operationGrid
where cell.Y == (int)operation
select cell;
foreach (var item in row)
{
if (!item.IsChecked)
return true;
}
return false;
}
}
}
Loading…
Cancel
Save