Compare commits

..

No commits in common. 'master' and 'PageBoard' have entirely different histories.

@ -1,15 +0,0 @@
**© 2024 - Tous droits réservés.**
Les éléments de conception et de documentation regroupent:
- Les diagrammes
- Les éléments de design
- Tout écrit réalisé dans le cadre de l'application et présent sur ce même [wiki](https://codefirst.iut.uca.fr/git/remi.lavergne/Trek-12/wiki).
Le terme "code" tel que définit constitue tout ou partie de texte permettant la formation, le fonctionnement et le lancement de l'application et présent dans le [dépôt CodeFirst](https://codefirst.iut.uca.fr/git/remi.lavergne/Trek-12).
Tous les éléments de conception et de documentation, ainsi que le code dans son intégralité sont la propriété des utilisateurs enregistrés sous les comptes CodeFirst/Gitea suivants: @remi.lavergne, @remi.neveu & @lucas.duflot.
Le jeu de société du nom "Trek 12" ainsi que tous ses logos associés sont la propriété de [🪓 LUMBERJACKS [Studio]](https://lumberjacks-studio.com/fr/trek12/)
**Utilisation et distribution :** Toute reproduction, distribution, ou utilisation non autorisée des éléments protégés est strictement interdite sans l'autorisation écrite préalable des propriétaires respectifs. Les utilisateurs peuvent demander des autorisations spécifiques en contactant les propriétaires via leurs comptes mentionnés.
**Avis de non-responsabilité :** Ce copyright ne s'étend pas aux éléments tiers utilisés sous licence. Toutes les marques commerciales et logos appartiennent à leurs propriétaires respectifs. Les propriétaires des comptes mentionnés ne sauraient être tenus responsables de l'utilisation abusive des éléments protégés par des tiers.

@ -1,4 +1,4 @@
![Static Badge](https://img.shields.io/badge/Trek12-Disponible_au_public-yellow) ![Static Badge](https://img.shields.io/badge/Trek12-En_Production-red)
<details> <details>
<summary>Sonarcube Ratings</summary> <summary>Sonarcube Ratings</summary>
@ -27,29 +27,4 @@ Auteurs:
<br> <br>
> ### **📼 Vidéo de présentation sur [Opencast](https://opencast.dsi.uca.fr/paella/ui/watch.html?id=b08a0497-0fc3-420f-a98d-5f5a2b226252).** > ### **📕 Toute la documentation est présente sur le [Wiki](https://codefirst.iut.uca.fr/git/remi.lavergne/Trek-12/wiki) !**
> ### **📕 Toute la conception et le fonctionnement est présent sur le [Wiki](https://codefirst.iut.uca.fr/git/remi.lavergne/Trek-12/wiki) !**
> ### **📄 Documentation du code sur [CodeDoc](https://codefirst.iut.uca.fr/documentation/remi.lavergne/Trek-12/doxygen/index.html).**
<br>
*Persistance locale en XML ou JSON disponible. La persistance en SQLite est créée mais nécessite encore du développement pour fonctionner.*<br/>
*Pour changer de mode de persistance, se rendre dans le fichier App.xaml.cs*
<br><br>
## 📦 Générer un exécutable
Pour générer un exécutable, il suffit de lancer la commande suivante dans le terminal :
```bash
# Pour un exécutable MSIX (Windows Store):
dotnet publish -f net8.0-windows10.0.19041.0 -p:WindowsPackageType=MSIX
# Ou pour un exécutable "classique":
dotnet publish -c Release -r win-x64 --self-contained
```
<br>
***Avant de fork le projet ou autre, merci de lire attentivement la [LICENCE](LICENSE.md)***

@ -1,4 +1,4 @@
// See https://aka.ms/new-console-template for more information // See https://aka.ms/new-console-template for more information
using Models; using Models;
using Models.Events; using Models.Events;
@ -86,7 +86,7 @@ class Program
static void OnPlayerOption(object sender, PlayerOptionEventArgs e) static void OnPlayerOption(object sender, PlayerOptionEventArgs e)
{ {
Console.WriteLine(); Console.WriteLine();
if (e.Turn != 1) if(e.Turn != 1)
{ {
IEnumerable<Cell> PlayedCellsQuery = IEnumerable<Cell> PlayedCellsQuery =
from cell in e.Board from cell in e.Board
@ -111,7 +111,6 @@ class Program
Console.Write($"{e.Resultat}"); Console.Write($"{e.Resultat}");
Console.ResetColor(); Console.ResetColor();
} }
} }
} }
} }

@ -6,10 +6,6 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Models\Models.csproj" /> <ProjectReference Include="..\Models\Models.csproj" />
</ItemGroup> </ItemGroup>

@ -1,69 +0,0 @@
using SQLite;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
namespace DataContractPersistence
{
using Models.Game;
using Models.Interfaces;
public class SqLitePersistence : IPersistence
{
private readonly SQLiteConnection _database;
private readonly string _databasePath;
public SqLitePersistence()
{
_databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Trek_12.db");
_database = new SQLiteConnection(_databasePath);
_database.CreateTable<Player>();
_database.CreateTable<Map>();
_database.CreateTable<Game>();
_database.CreateTable<BestScore>();
}
public (ObservableCollection<Player>, ObservableCollection<Game>, ObservableCollection<Map>, ObservableCollection<BestScore>) LoadData()
{
var players = new ObservableCollection<Player>(_database.Table<Player>());
var games = new ObservableCollection<Game>(_database.Table<Game>());
var maps = new ObservableCollection<Map>(_database.Table<Map>());
var bestScores = new ObservableCollection<BestScore>(_database.Table<BestScore>());
return (players, games, maps, bestScores);
}
public void SaveData(ObservableCollection<Player> players, ObservableCollection<Game> games, ObservableCollection<Map> maps, ObservableCollection<BestScore> bestScores)
{
_database.RunInTransaction(() =>
{
_database.DeleteAll<Player>();
_database.DeleteAll<Game>();
_database.DeleteAll<Map>();
_database.DeleteAll<BestScore>();
});
foreach (var player in players)
{
_database.Insert(player);
}
foreach (var game in games)
{
_database.Insert(game);
}
foreach (var map in maps)
{
_database.Insert(map);
}
foreach (var bestScore in bestScores)
{
_database.Insert(bestScore);
}
}
}
}

@ -5,20 +5,15 @@ using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using SQLite;
namespace Models.Game namespace Models.Game
{ {
/// <summary> /// <summary>
/// This class represents the best score of a player. /// This class represents the best score of a player.
/// </summary> /// </summary>
[DataContract, SQLite.Table("BestScores")] [DataContract]
public class BestScore public class BestScore
{ {
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
/// <summary> /// <summary>
/// Name of the map. /// Name of the map.
/// </summary> /// </summary>
@ -74,11 +69,6 @@ namespace Models.Game
Score = score; Score = score;
} }
/// <summary>
/// SQLite constructor
/// </summary>
public BestScore() { }
/// <summary> /// <summary>
/// Increment the number of games played by the user. /// Increment the number of games played by the user.
/// </summary> /// </summary>

@ -1,6 +1,4 @@
using System.ComponentModel; using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace Models.Game namespace Models.Game
{ {
@ -8,7 +6,7 @@ namespace Models.Game
/// The Cell class represents a cell in the application. /// The Cell class represents a cell in the application.
/// </summary> /// </summary>
[DataContract] [DataContract]
public class Cell : Position, IEquatable<Cell>, INotifyPropertyChanged public class Cell : Position, IEquatable<Cell>
{ {
/// <summary> /// <summary>
/// The value of the cell. /// The value of the cell.
@ -24,8 +22,6 @@ namespace Models.Game
throw new Exception("La valeur doit être supérieure à 0"); throw new Exception("La valeur doit être supérieure à 0");
} }
this._value = value; this._value = value;
OnPropertyChanged();
} }
} }
@ -80,13 +76,5 @@ namespace Models.Game
if (this.X == other.X && this.Y == other.Y) return true; if (this.X == other.X && this.Y == other.Y) return true;
return false; return false;
} }
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }

@ -13,7 +13,6 @@ using System.Threading.Tasks.Dataflow;
using Models.Events; using Models.Events;
using Models.Interfaces; using Models.Interfaces;
using Models.Rules; using Models.Rules;
using SQLite;
namespace Models.Game namespace Models.Game
{ {
@ -21,21 +20,14 @@ namespace Models.Game
/// The Game class represents a game session in the application. /// The Game class represents a game session in the application.
/// It contains all the necessary properties and methods to manage a game, including the game loop, dice rolling, and use of the game rules. /// It contains all the necessary properties and methods to manage a game, including the game loop, dice rolling, and use of the game rules.
/// </summary> /// </summary>
[DataContract, SQLite.Table("Games")] [DataContract]
public class Game : INotifyPropertyChanged public class Game : INotifyPropertyChanged
{ {
public bool IsPreviousGameNotFinished { get; private set; }
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
/* Persistence Interface */ /* Persistence Interface */
[Ignore]
public IPersistence PersistenceManager { get; set; } public IPersistence PersistenceManager { get; set; }
/* List for the game and persistence */ /* List for the game and persistence */
private ObservableCollection<Player> _players; private ObservableCollection<Player> _players;
[Ignore]
public ObservableCollection<Player> Players public ObservableCollection<Player> Players
{ {
get => _players; get => _players;
@ -47,7 +39,6 @@ namespace Models.Game
} }
private ObservableCollection<Game> _games; private ObservableCollection<Game> _games;
[Ignore]
public ObservableCollection<Game> Games public ObservableCollection<Game> Games
{ {
get => _games; get => _games;
@ -59,7 +50,6 @@ namespace Models.Game
} }
private ObservableCollection<Map> _maps; private ObservableCollection<Map> _maps;
[Ignore]
public ObservableCollection<Map> Maps public ObservableCollection<Map> Maps
{ {
get => _maps; get => _maps;
@ -71,7 +61,6 @@ namespace Models.Game
} }
private ObservableCollection<BestScore> _bestScores; private ObservableCollection<BestScore> _bestScores;
[Ignore]
public ObservableCollection<BestScore> BestScores public ObservableCollection<BestScore> BestScores
{ {
get => _bestScores; get => _bestScores;
@ -105,43 +94,18 @@ namespace Models.Game
} }
} }
[Ignore]
public Dice Dice1 { get; private set;} public Dice Dice1 { get; private set;}
[Ignore]
public Dice Dice2 { get; private set; } public Dice Dice2 { get; private set; }
[DataMember] [DataMember]
public int Turn { get; set; } public int Turn { get; private set; }
[Ignore]
public Operation PlayerOperation { get; set; } public Operation PlayerOperation { get; set; }
private Cell _playerCell; public Cell PlayerCell { get; set; }
[Ignore] public int Resultat { get; set; }
public Cell PlayerCell {
get => _playerCell;
set
{
_playerCell = value;
OnPropertyChanged(nameof(PlayerCell));
}
}
private int _resultat;
public int Resultat {
get => _resultat;
set
{
_resultat = value;
OnPropertyChanged(nameof(Resultat));
}
}
public bool DiceRolledFlag { get; private set; }
public bool OperationChosenFlag { get; private set; }
[Ignore]
public Rules.Rules GameRules { get; } public Rules.Rules GameRules { get; }
@ -172,45 +136,25 @@ namespace Models.Game
Maps.Add(map); Maps.Add(map);
} }
/// <summary>
/// Adds a new best score to the list of best scores. Or updates it if it already exists.
/// </summary>
/// <param name="finalScore">The final score of the game.</param>
public void AddBestScore(int finalScore) public void AddBestScore(int finalScore)
{ {
BestScore bs = new BestScore(UsedMap.Name, CurrentPlayer, 1, finalScore); BestScore bs = new BestScore(UsedMap.Name, CurrentPlayer, 1, finalScore);
var existingScore = BestScores.FirstOrDefault(score => score.Equals(bs)); foreach (var score in BestScores)
if (existingScore != null)
{
existingScore.IncrGamesPlayed();
existingScore.UpdateScore(finalScore);
}
else
{ {
BestScores.Add(bs); if (!bs.Equals(score)) continue;
}
// Sorting the best scores score.IncrGamesPlayed();
List<BestScore> sortedScores = BestScores.OrderByDescending(score => score.Score).ToList(); score.UpdateScore(finalScore);
return;
for (int i = 0; i < sortedScores.Count; i++)
{
if (!BestScores[i].Equals(sortedScores[i]))
{
BestScores.Move(BestScores.IndexOf(sortedScores[i]), i);
}
} }
BestScores.Add(bs);
BestScores.OrderByDescending(p => p.Score);
} }
/// <summary>
/// Removes a player from the list of players.
/// </summary>
/// <param name="playerName"></param>
/// <returns>True if the player was removed successfully, false otherwise.</returns>
public bool RemovePlayer(string playerName) public bool RemovePlayer(string playerName)
{ {
Player? player = Players.FirstOrDefault(p => p.Pseudo == playerName); Player player = Players.FirstOrDefault(p => p.Pseudo == playerName);
if (player == null) if (player == null)
{ {
return false; return false;
@ -220,12 +164,6 @@ namespace Models.Game
return true; return true;
} }
/// <summary>
/// Modifies the pseudo of a player.
/// </summary>
/// <param name="pseudo"></param>
/// <param name="newpseudo"></param>
/// <returns></returns>
public bool ModifyPlayer(string pseudo, string newpseudo) public bool ModifyPlayer(string pseudo, string newpseudo)
{ {
foreach (var index in Players) foreach (var index in Players)
@ -241,10 +179,6 @@ namespace Models.Game
return false; return false;
} }
/// <summary>
/// Removes a game from the list of games.
/// </summary>
/// <param name="playerName"></param>
public void CheckAndRemoveBestScoresDependencies(string playerName) public void CheckAndRemoveBestScoresDependencies(string playerName)
{ {
List<BestScore> bs = new List<BestScore>(); List<BestScore> bs = new List<BestScore>();
@ -260,12 +194,7 @@ namespace Models.Game
BestScores.Remove(score); BestScores.Remove(score);
} }
} }
/// <summary>
/// Modifies the pseudo of a player in the best scores.
/// </summary>
/// <param name="playerName"></param>
/// <param name="newPlayerName"></param>
public void CheckAndChangeBestScoresDependencies(string playerName, string newPlayerName) public void CheckAndChangeBestScoresDependencies(string playerName, string newPlayerName)
{ {
foreach (var bestScore in BestScores) foreach (var bestScore in BestScores)
@ -285,10 +214,6 @@ namespace Models.Game
} }
foreach (var game in data.Item2) foreach (var game in data.Item2)
{ {
if (game.IsRunning)
{
IsPreviousGameNotFinished = true;
}
Games.Add(game); Games.Add(game);
} }
foreach (var map in data.Item3) foreach (var map in data.Item3)
@ -336,11 +261,7 @@ namespace Models.Game
{ {
Dice1.Roll(); Dice1.Roll();
Dice2.Roll(); Dice2.Roll();
DiceRolledFlag = true;
OperationChosenFlag = false;
DiceRolled?.Invoke(this, new DiceRolledEventArgs(Dice1.Value, Dice2.Value)); DiceRolled?.Invoke(this, new DiceRolledEventArgs(Dice1.Value, Dice2.Value));
OnPropertyChanged(nameof(Dice1));
OnPropertyChanged(nameof(Dice2));
} }
/// <summary> /// <summary>
@ -408,13 +329,7 @@ namespace Models.Game
{ {
if (item.X == playerChoice.X && item.Y == playerChoice.Y) if (item.X == playerChoice.X && item.Y == playerChoice.Y)
{ {
if (result > 12 || (result > 6 && item.IsDangerous == true))
{
item.SetPenalty();
PlayerCell.SetPenalty();
}
item.Value = result; item.Value = result;
OnPropertyChanged(nameof(UsedMap.Boards));
return; return;
} }
@ -427,32 +342,35 @@ namespace Models.Game
/// </summary> /// </summary>
/// <param name="playerChoice"></param> /// <param name="playerChoice"></param>
/// <param name="adjacentes"></param> /// <param name="adjacentes"></param>
private void AddToRopePath(Cell playerChoice) private void AddToRopePath(Cell playerChoice,List<Cell> adjacentes)
{ {
int index =0;
if(Turn==1) return; foreach (var cells in adjacentes.Where(cells => cells.Value - playerChoice.Value == 1 || cells.Value - playerChoice.Value == -1))
int index = 0; {
// Le cas si il n'existe aucun chemin de corde
if (UsedMap.RopePaths.Count == 0)
{
// Creer un nouveau chemin de corde avec la cellule choisi par le joueur et celle adjacente
UsedMap.RopePaths.Add(new List<Cell> {playerChoice, cells});
}
IEnumerable<Cell> ValidCell =
from cell in UsedMap.Boards
where cell.Value != null && cell.Valid == true && cell != playerChoice
select cell;
foreach (var item in ValidCell) // A modifier dans le cas ou il est possible de fusionner deux chemins de corde
{ if (GameRules.IsInRopePaths(playerChoice, UsedMap.RopePaths, index)) break;
if (!GameRules.IsCellAdjacent(playerChoice, item))
continue; // Le cas si il existe des chemins de corde
if (!((playerChoice.Value - item.Value) == 1 || (playerChoice.Value - item.Value) == -1))
continue; // Est-ce que la cellule adjacentes fait parti d'un chemin de corde
if (!GameRules.IsInRopePaths(item,UsedMap.RopePaths,index)) if (!GameRules.IsInRopePaths(cells,UsedMap.RopePaths,index))
{ {
UsedMap.RopePaths.Add(new List<Cell> { playerChoice, item }); UsedMap.RopePaths.Add(new List<Cell> { playerChoice, cells });
return; continue;
} }
if (!GameRules.AsValue(playerChoice, UsedMap.RopePaths, index))
if (!GameRules.AsValue(playerChoice,UsedMap.RopePaths,index))
{ {
UsedMap.RopePaths[index].Add(playerChoice); UsedMap.RopePaths[index].Add(playerChoice);
return;
} }
} }
} }
@ -462,30 +380,16 @@ namespace Models.Game
/// </summary> /// </summary>
public void InitializeGame(Map map, Player player, bool startImmediately = true) public void InitializeGame(Map map, Player player, bool startImmediately = true)
{ {
var runningGames = Games.Where(g => g.IsRunning).ToList();
foreach (var game in runningGames)
{
Games.Remove(game);
}
OnPropertyChanged(nameof(Games));
UsedMap = map; UsedMap = map;
CurrentPlayer = player; CurrentPlayer = player;
Turn = 1; Turn = 1;
Dice1 = new Dice(); Dice1 = new Dice();
Dice2 = new Dice(1); Dice2 = new Dice(1);
IsPreviousGameNotFinished = false;
OnPropertyChanged(nameof(UsedMap));
OnPropertyChanged(nameof(CurrentPlayer));
OnPropertyChanged(nameof(Turn));
if (startImmediately) if (startImmediately)
{ {
StartGame(); StartGame();
} }
SaveData();
} }
/// <summary> /// <summary>
@ -495,8 +399,6 @@ namespace Models.Game
{ {
IsRunning = true; IsRunning = true;
GameStarted?.Invoke(this, new GameStartedEventArgs(CurrentPlayer)); GameStarted?.Invoke(this, new GameStartedEventArgs(CurrentPlayer));
SaveData();
} }
/// <summary> /// <summary>
@ -531,7 +433,6 @@ namespace Models.Game
PlayerChooseOp?.Invoke(this, new PlayerChooseOperationEventArgs(PlayerOperation)); PlayerChooseOp?.Invoke(this, new PlayerChooseOperationEventArgs(PlayerOperation));
} }
PlayerOption?.Invoke(this, new PlayerOptionEventArgs(UsedMap.Boards.ToList(), ResultOperation(PlayerOperation), Turn)); PlayerOption?.Invoke(this, new PlayerOptionEventArgs(UsedMap.Boards.ToList(), ResultOperation(PlayerOperation), Turn));
OperationChosenFlag = true;
return ResultOperation(PlayerOperation); return ResultOperation(PlayerOperation);
} }
@ -544,8 +445,6 @@ namespace Models.Game
} }
MarkOperationAsChecked(PlayerOperation); MarkOperationAsChecked(PlayerOperation);
PlaceResult(PlayerCell, Resultat); PlaceResult(PlayerCell, Resultat);
DiceRolledFlag = false;
OperationChosenFlag = false;
} }
/// <summary> /// <summary>
@ -555,7 +454,6 @@ namespace Models.Game
public void HandlePlayerOperation(Operation operation) public void HandlePlayerOperation(Operation operation)
{ {
int result = ResultOperation(operation); int result = ResultOperation(operation);
OperationChosenFlag = true;
OperationChosen?.Invoke(this, new OperationChosenEventArgs(operation, result)); OperationChosen?.Invoke(this, new OperationChosenEventArgs(operation, result));
} }
@ -571,17 +469,26 @@ namespace Models.Game
if (cell.X < 0 || cell.X >= UsedMap.Boards.Count / 6 || cell.Y < 0 || cell.Y >= 6) if (cell.X < 0 || cell.X >= UsedMap.Boards.Count / 6 || cell.Y < 0 || cell.Y >= 6)
{ {
return false; return false;
//throw new InvalidCellCoordinatesException("Invalid cell coordinates. Please choose again.");
} }
if (!GameRules.IsCellValid(cell, UsedMap.Boards.ToList())) if (!GameRules.IsCellValid(cell, UsedMap.Boards.ToList()))
{ {
return false; return false;
//throw new InvalidCellException("Cell is not valid. Please choose again.");
} }
bool res = true;
if (!res)
{
return false;
//throw new InvalidPlaceResultException("Cell is not valid for place result. Please choose again.");
}
GameRules.IsZoneValidAndAddToZones(cell, UsedMap); GameRules.IsZoneValidAndAddToZones(cell, UsedMap);
AddToRopePath(cell); AddToRopePath(cell, GameRules.EveryAdjacentCells(cell, UsedMap.Boards.ToList()));
CellChosen?.Invoke(this, new CellChosenEventArgs(cell, result)); CellChosen?.Invoke(this, new CellChosenEventArgs(cell, result));
return true; return true;
//BoardUpdated?.Invoke(this, EventArgs.Empty);
} }
/// <summary> /// <summary>
@ -604,7 +511,7 @@ namespace Models.Game
foreach (var cells in Boards) foreach (var cells in Boards)
if (cells.Penalty) if (cells.Penalty)
{ {
if (!cells.Valid || cells.Value == null) if (cells.Valid == false || cells.Value == null)
continue; continue;
result += 3; result += 3;
} }
@ -615,7 +522,7 @@ namespace Models.Game
{ {
foreach (var cells in Boards) foreach (var cells in Boards)
{ {
if (cells == null || cells.Value == null || !cells.Valid) if (cells == null || cells.Value == null || cells.Valid == false)
continue; continue;
if (!UsedMap.IsCellInZones(cells) && !UsedMap.IsCellInRopePath(cells)) if (!UsedMap.IsCellInZones(cells) && !UsedMap.IsCellInRopePath(cells))
cells.SetPenalty(); cells.SetPenalty();
@ -629,7 +536,7 @@ namespace Models.Game
{ {
points += GameRules.ScoreRopePaths(UsedMap.RopePaths[i]); points += GameRules.ScoreRopePaths(UsedMap.RopePaths[i]);
} }
points -= CalculusOfPenalty(UsedMap.Boards); points += CalculusOfPenalty(UsedMap.Boards);
return points ?? 0; return points ?? 0;
} }

@ -1,6 +1,5 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using SQLite;
namespace Models.Game namespace Models.Game
{ {
@ -8,23 +7,21 @@ namespace Models.Game
/// <summary> /// <summary>
/// The Map class is the representation of the game map with the board and the operations table. /// The Map class is the representation of the game map with the board and the operations table.
/// </summary> /// </summary>
[DataContract, SQLite.Table("Maps")] [DataContract]
public class Map public class Map
{ {
/// <summary>
/// The displaying name of the map
/// </summary>
[DataMember, PrimaryKey]
public string Name { get; private set; }
/// <summary> /// <summary>
/// It is the list of cells on the map. /// It is the list of cells on the map.
/// </summary> /// </summary>
[DataMember] [DataMember]
[Ignore]
public ReadOnlyObservableCollection<Cell> Boards { get; private set; } public ReadOnlyObservableCollection<Cell> Boards { get; private set; }
ObservableCollection<Cell> board = new ObservableCollection<Cell>();
private readonly ObservableCollection<Cell> _board = new ObservableCollection<Cell>(); /// <summary>
/// The displaying name of the map
/// </summary>
[DataMember]
public string Name { get; private set; }
/// <summary> /// <summary>
/// It is the backgrond image of the map /// It is the backgrond image of the map
@ -37,8 +34,7 @@ namespace Models.Game
/// </summary> /// </summary>
[DataMember] [DataMember]
public ReadOnlyObservableCollection<OperationCell> OperationGrid { get; private set; } public ReadOnlyObservableCollection<OperationCell> OperationGrid { get; private set; }
ObservableCollection<OperationCell> operationGrid = new ObservableCollection<OperationCell>();
private readonly ObservableCollection<OperationCell> _operationGrid = new ObservableCollection<OperationCell>();
/// <summary> /// <summary>
/// It is a list of a list containing user's rope paths in the current game /// It is a list of a list containing user's rope paths in the current game
@ -55,34 +51,18 @@ namespace Models.Game
/// <summary> /// <summary>
/// Initializes a new instance of the Map class. /// Initializes a new instance of the Map class.
/// </summary> /// </summary>
/// <param name="name"></param>
/// <param name="background">The background of the map.</param> /// <param name="background">The background of the map.</param>
public Map(string name, string background) public Map(string name, string background)
{ {
Name = name; Name = name;
Background = background; Background = background;
Boards = new ReadOnlyObservableCollection<Cell>(_board); Boards = new ReadOnlyObservableCollection<Cell>(board);
InitializeBoards(_board); InitializeBoards(board);
OperationGrid = new ReadOnlyObservableCollection<OperationCell>(_operationGrid); OperationGrid = new ReadOnlyObservableCollection<OperationCell>(operationGrid);
InitializeOperationGrid(_operationGrid); InitializeOperationGrid(operationGrid);
RopePaths = new List<List<Cell>>(); RopePaths = new List<List<Cell>>();
Zones = new List<List<Cell>>(); Zones = new List<List<Cell>>();
} }
/// <summary>
/// SQLite constructor
/// </summary>
public Map() { }
/// <summary>
/// Clone the map to avoid reference problems.
/// </summary>
/// <returns></returns>
public Map Clone()
{
Map map = new Map(Name, Background);
return map;
}
/// <summary> /// <summary>
/// Initializes the boards of the map. /// Initializes the boards of the map.
@ -141,12 +121,26 @@ namespace Models.Game
public bool IsCellInZones(Cell cell) public bool IsCellInZones(Cell cell)
{ {
return Zones.Any(zone => zone.Contains(cell)); foreach (var zone in Zones)
{
if (zone.Contains(cell))
{
return true;
}
}
return false;
} }
public bool IsCellInRopePath(Cell cell) public bool IsCellInRopePath(Cell cell)
{ {
return RopePaths.Any(path => path.Contains(cell)); foreach (var path in RopePaths)
{
if (path.Contains(cell))
{
return true;
}
}
return false;
} }
} }
} }

@ -22,7 +22,7 @@ namespace Models.Game
if (isChecked == value) if (isChecked == value)
return; return;
isChecked = value; isChecked = value;
OnPropertyChanged(nameof(IsChecked)); OnPropertyChanged("IsChecked");
} }
} }

@ -1,7 +1,5 @@
using SQLite; using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Models.Interfaces; using Models.Interfaces;
@ -12,12 +10,12 @@ namespace Models.Game
/// <summary> /// <summary>
/// Represents a player in the game. /// Represents a player in the game.
/// </summary> /// </summary>
[DataContract, SQLite.Table("Players")] [DataContract]
public class Player : INotifyPropertyChanged public class Player : INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string? propertyName = null) void OnPropertyChanged([CallerMemberName] string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
@ -25,7 +23,7 @@ namespace Models.Game
/// It is he pseudo of the player. /// It is he pseudo of the player.
/// </summary> /// </summary>
private string _pseudo; private string _pseudo;
[DataMember, PrimaryKey] [DataMember]
public string Pseudo public string Pseudo
{ {
get => _pseudo; get => _pseudo;
@ -63,16 +61,14 @@ namespace Models.Game
/// <param name="profilePicture">The profile picture of the player.</param> /// <param name="profilePicture">The profile picture of the player.</param>
public Player(string pseudo, string profilePicture) public Player(string pseudo, string profilePicture)
{ {
//char[] trim = { ' ', '\n', '\t' };
//Pseudo = pseudo.Trim();
//Pseudo = Pseudo.TrimEnd(trim);
Pseudo = pseudo; Pseudo = pseudo;
ProfilePicture = profilePicture; ProfilePicture = profilePicture;
CreationDate = DateTime.Now.ToString("dd/MM/yyyy"); CreationDate = DateTime.Now.ToString("dd/MM/yyyy");
} }
/// <summary>
/// SQLite constructor
/// </summary>
public Player() { }
/// <summary> /// <summary>
/// Redefine the equal operation between player. /// Redefine the equal operation between player.
/// </summary> /// </summary>

@ -1,12 +1,12 @@
using System.Collections.ObjectModel; using Models.Game;
using System.Collections.ObjectModel;
namespace Models.Interfaces namespace Models.Interfaces
{ {
using Models.Game;
public interface IPersistence public interface IPersistence
{ {
(ObservableCollection<Player>, ObservableCollection<Game>, ObservableCollection<Map>, ObservableCollection<BestScore>) LoadData(); (ObservableCollection<Player>, ObservableCollection<Game.Game>, ObservableCollection<Map>, ObservableCollection<BestScore>) LoadData();
void SaveData(ObservableCollection<Player> players, ObservableCollection<Game> games, ObservableCollection<Map> maps, ObservableCollection<BestScore> bestScores); void SaveData(ObservableCollection<Player> players, ObservableCollection<Game.Game> games, ObservableCollection<Map> maps, ObservableCollection<BestScore> bestScores);
} }
} }

@ -14,7 +14,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls.Core" Version="8.0.3" /> <PackageReference Include="Microsoft.Maui.Controls.Core" Version="8.0.3" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -25,8 +25,6 @@ namespace Models.Rules
{ {
if (!IsCellEmpty(playerChoicePosition)) return false; if (!IsCellEmpty(playerChoicePosition)) return false;
if (!playerChoicePosition.Valid) return false;
if (EveryAdjacentCells(playerChoicePosition, cells).Count == 1) return false; if (EveryAdjacentCells(playerChoicePosition, cells).Count == 1) return false;
return true; return true;
@ -44,13 +42,15 @@ namespace Models.Rules
} }
public bool IsInRopePaths (Cell adjacente,List<List<Cell>> ropePaths, int index) public bool IsInRopePaths (Cell adjacente,List<List<Cell>> ropePaths,int index)
{ {
foreach (List<Cell> path in ropePaths) foreach (List<Cell> path in ropePaths)
{ {
if (!path.Contains(adjacente)) continue; if (path.Contains(adjacente))
index=ropePaths.IndexOf(path); {
return true; index=ropePaths.IndexOf(path);
return true;
}
} }
return false; return false;
} }
@ -70,7 +70,7 @@ namespace Models.Rules
IEnumerable<Cell> PlayedCellsQuery = IEnumerable<Cell> PlayedCellsQuery =
from cell in cells from cell in cells
where cell.Valid where cell.Valid == true
select cell; select cell;
foreach (var cell in PlayedCellsQuery) foreach (var cell in PlayedCellsQuery)
@ -90,7 +90,7 @@ namespace Models.Rules
{ {
if (chosenCell == null ||chosenCell.Value == null) return; if (chosenCell == null ||chosenCell.Value == null) return;
List<Cell> adjacentCells; List<Cell> adjacentCells = new List<Cell>();
adjacentCells = EveryAdjacentCells(chosenCell, map.Boards.ToList()); adjacentCells = EveryAdjacentCells(chosenCell, map.Boards.ToList());
@ -108,6 +108,8 @@ namespace Models.Rules
} }
} }
} }
return;
} }
public bool IsValueInZones(Cell chosenCell, List<List<Cell>> zones) public bool IsValueInZones(Cell chosenCell, List<List<Cell>> zones)
@ -152,6 +154,7 @@ namespace Models.Rules
return; return;
} }
} }
return;
} }
public void NewZoneIsCreated(Cell firstCell, Cell secondCell, Map map) public void NewZoneIsCreated(Cell firstCell, Cell secondCell, Map map)
@ -163,7 +166,7 @@ namespace Models.Rules
map.Zones.Add(newZone); map.Zones.Add(newZone);
} }
public List<Cell> EveryAdjacentCells(Cell? choosenCell, List<Cell> cells) public List<Cell> EveryAdjacentCells(Cell choosenCell, List<Cell> cells)
{ {
List<Cell> adjacentCells = new List<Cell>(); List<Cell> adjacentCells = new List<Cell>();

@ -69,67 +69,5 @@ namespace Tests
Assert.Equal(15, bestScore.Score); Assert.Equal(15, bestScore.Score);
} }
[Fact]
public void IdGetter_ReturnsCorrectId()
{
var myMap = new Map("Dunai", "Dunai.png");
var myPlayer = new Player("John", "pp.png");
var bestScore = new BestScore(myMap.Name, myPlayer, 5, 10);
bestScore.Id = 1;
Assert.Equal(1, bestScore.Id);
}
[Fact]
public void Equals_WithEqualBestScores_ReturnsTrue()
{
var myMap = new Map("Dunai", "Dunai.png");
var myPlayer = new Player("John", "pp.png");
var bestScore1 = new BestScore(myMap.Name, myPlayer, 5, 10);
var bestScore2 = new BestScore(myMap.Name, myPlayer, 5, 10);
Assert.True(bestScore1.Equals(bestScore2));
}
[Fact]
public void Equals_WithDifferentBestScores_ReturnsFalse()
{
var myMap1 = new Map("Dunai", "Dunai.png");
var myMap2 = new Map("Amazon", "Amazon.png");
var myPlayer = new Player("John", "pp.png");
var bestScore1 = new BestScore(myMap1.Name, myPlayer, 5, 10);
var bestScore2 = new BestScore(myMap2.Name, myPlayer, 5, 10);
Assert.False(bestScore1.Equals(bestScore2));
}
[Fact]
public void GetHashCode_WithEqualBestScores_ReturnsSameHashCode()
{
var myMap = new Map("Dunai", "Dunai.png");
var myPlayer = new Player("John", "pp.png");
var bestScore1 = new BestScore(myMap.Name, myPlayer, 5, 10);
var bestScore2 = new BestScore(myMap.Name, myPlayer, 5, 10);
Assert.Equal(bestScore1.GetHashCode(), bestScore2.GetHashCode());
}
[Fact]
public void GetHashCode_WithDifferentBestScores_ReturnsDifferentHashCodes()
{
var myMap1 = new Map("Dunai", "Dunai.png");
var myMap2 = new Map("Amazon", "Amazon.png");
var myPlayer = new Player("John", "pp.png");
var bestScore1 = new BestScore(myMap1.Name, myPlayer, 5, 10);
var bestScore2 = new BestScore(myMap2.Name, myPlayer, 5, 10);
Assert.NotEqual(bestScore1.GetHashCode(), bestScore2.GetHashCode());
}
} }
} }

@ -135,6 +135,25 @@ public class GameTests
Assert.Equal(player, _game.CurrentPlayer); Assert.Equal(player, _game.CurrentPlayer);
} }
[Fact]
public void InitializeGame_ShouldInitializeGameAndTriggerEventWhenStarted()
{
var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
bool eventTriggered = false;
_game.GameEnded += (sender, args) =>
{
eventTriggered = true;
};
_game.InitializeGame(map, player, true);
Assert.True(eventTriggered);
Assert.False(_game.IsRunning);
Assert.Equal(map, _game.UsedMap);
Assert.Equal(player, _game.CurrentPlayer);
}
[Theory] [Theory]
[InlineData(Operation.ADDITION, 3, 4, 7)] [InlineData(Operation.ADDITION, 3, 4, 7)]
[InlineData(Operation.SUBTRACTION, 6, 4, 2)] [InlineData(Operation.SUBTRACTION, 6, 4, 2)]
@ -172,7 +191,7 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
Assert.Equal(map, _game.UsedMap); Assert.Equal(map, _game.UsedMap);
} }
@ -183,7 +202,7 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
Assert.Equal(player, _game.CurrentPlayer); Assert.Equal(player, _game.CurrentPlayer);
} }
@ -194,7 +213,7 @@ public class GameTests
Player player = new Player("test_player", "DefaultProfilePicture"); Player player = new Player("test_player", "DefaultProfilePicture");
Map map = new Map("test_name", "test_background.png"); Map map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
Assert.NotNull(_game.Dice1); Assert.NotNull(_game.Dice1);
Assert.NotNull(_game.Dice2); Assert.NotNull(_game.Dice2);
@ -214,7 +233,7 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
// Use of reflection to call private method // Use of reflection to call private method
var methodInfo = typeof(Game).GetMethod("MarkOperationAsChecked", BindingFlags.NonPublic | BindingFlags.Instance); var methodInfo = typeof(Game).GetMethod("MarkOperationAsChecked", BindingFlags.NonPublic | BindingFlags.Instance);
@ -247,21 +266,17 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
Assert.NotNull(_game.GameRules); Assert.NotNull(_game.GameRules);
_game.UsedMap.Boards[0].Value = 1; _game.UsedMap.Boards[0].Value = 1;
_game.UsedMap.Boards[1].Value = 2; _game.UsedMap.Boards[1].Value = 2;
_game.UsedMap.Boards[0].Valid = true;
_game.UsedMap.Boards[1].Valid = true;
_game.UsedMap.Boards[2].Valid = true;
var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance); var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(methodInfo); Assert.NotNull(methodInfo);
_game.PlayerCell = new Cell(2, 0); var cell = new Cell(0, 2);
_game.PlayerCell.Value = 3; cell.Value = 3;
methodInfo.Invoke(_game, new object[] { _game.PlayerCell, 3 }); methodInfo.Invoke(_game, new object[] { cell, 3 });
//_game.UsedMap.Boards[2].Value = _game.PlayerCell.Value;
Assert.Equal(3, _game.UsedMap.Boards[2].Value); Assert.Equal(3, _game.UsedMap.Boards[2].Value);
} }
@ -272,13 +287,10 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
var cell = new Cell(1, 0); var cell = new Cell(0, 1);
cell.Valid = true;
_game.UsedMap.Boards[0].Valid = true;
_game.UsedMap.Boards[0].Value = 1; _game.UsedMap.Boards[0].Value = 1;
_game.UsedMap.Boards[1].Valid = true;
bool result = _game.HandlePlayerChoice(cell, 1); bool result = _game.HandlePlayerChoice(cell, 1);
Assert.True(result); Assert.True(result);
} }
@ -289,7 +301,7 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
var cell = new Cell(0, 7); var cell = new Cell(0, 7);
cell.Value = 1; cell.Value = 1;
@ -303,7 +315,7 @@ public class GameTests
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
var cell = new Cell(0, 0); var cell = new Cell(0, 0);
cell.Value = 1; cell.Value = 1;
@ -312,6 +324,25 @@ public class GameTests
Assert.False(result); Assert.False(result);
} }
[Fact]
public void ShouldTriggerEventWhenEnded()
{
var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
bool eventTriggered = false;
_game.GameEnded += (sender, args) =>
{
eventTriggered = true;
};
_game.InitializeGame(map, player, true);
Assert.True(eventTriggered);
Assert.False(_game.IsRunning);
Assert.Equal(map, _game.UsedMap);
Assert.Equal(player, _game.CurrentPlayer);
}
[Fact] [Fact]
public void RemovePlayerTest_ShouldRemovePlayer() public void RemovePlayerTest_ShouldRemovePlayer()
{ {
@ -335,17 +366,15 @@ public class GameTests
{ {
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
_game.UsedMap.Boards[1].Valid = true;
_game.UsedMap.Boards[2].Valid = true;
_game.UsedMap.Boards[1].Value = 5; _game.UsedMap.Boards[1].Value = 5;
var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance); var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(methodInfo); Assert.NotNull(methodInfo);
_game.PlayerCell = new Cell(2, 0); var cell = new Cell(0, 2);
_game.PlayerCell.Value = 14; cell.Value = 14;
methodInfo.Invoke(_game, new object[] { _game.PlayerCell, 14 }); methodInfo.Invoke(_game, new object[] { cell, 14 });
Assert.True(_game.UsedMap.Boards[2].Penalty); Assert.True(_game.UsedMap.Boards[2].Penalty);
} }
@ -355,20 +384,16 @@ public class GameTests
{ {
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
_game.UsedMap.Boards[1].Valid = true;
_game.UsedMap.Boards[2].Valid = true;
_game.UsedMap.Boards[1].Value = 5; _game.UsedMap.Boards[1].Value = 5;
_game.UsedMap.Boards[2].IsDangerous = true; _game.UsedMap.Boards[2].IsDangerous = true;
var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance); var methodInfo = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(methodInfo); Assert.NotNull(methodInfo);
_game.PlayerCell = new Cell(2, 0); var cell = new Cell(0, 2);
_game.PlayerCell.Value = 7; cell.Value = 7;
methodInfo.Invoke(_game, new object[] { _game.PlayerCell, 7 }); methodInfo.Invoke(_game, new object[] { cell, 7 });
Assert.True(_game.UsedMap.Boards[2].Penalty); Assert.True(_game.UsedMap.Boards[2].Penalty);
} }
@ -378,7 +403,7 @@ public class GameTests
{ {
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
_game.UsedMap.Boards[0].Valid = true; _game.UsedMap.Boards[0].Valid = true;
_game.UsedMap.Boards[3].Valid = true; _game.UsedMap.Boards[3].Valid = true;
@ -406,7 +431,7 @@ public class GameTests
{ {
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
_game.UsedMap.Boards[1].Value = 1; _game.UsedMap.Boards[1].Value = 1;
_game.UsedMap.Boards[2].Value = 2; _game.UsedMap.Boards[2].Value = 2;
@ -418,7 +443,7 @@ public class GameTests
foreach (var cells in _game.UsedMap.Boards.ToList()) foreach (var cells in _game.UsedMap.Boards.ToList())
{ {
methodInfo.Invoke(_game, new object[] { cells }); methodInfo.Invoke(_game, new object[] { cells, _game.UsedMap.Boards.ToList() });
} }
_game.PutPenaltyForLostCells(_game.UsedMap.Boards); _game.PutPenaltyForLostCells(_game.UsedMap.Boards);
@ -428,114 +453,42 @@ public class GameTests
} }
[Fact] [Fact]
public void CalculusOfPenalty_ReallyCalculusPenalty_ForZonesAndDangerousCellsAndOverTwelve() public void CalculusOfPenalty_ReallyCalculusPenalty()
{ {
var player = new Player("test_player", "DefaultProfilePicture"); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png"); var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player, false); _game.InitializeGame(map, player);
var methodInfo = typeof(Game).GetMethod("AddToRopePath", BindingFlags.NonPublic | BindingFlags.Instance);
_game.UsedMap.Boards[7].Valid = true; Assert.NotNull(methodInfo);
_game.UsedMap.Boards[8].Valid = true;
_game.UsedMap.Boards[9].Valid = true;
_game.UsedMap.Boards[10].Valid = true;
_game.UsedMap.Boards[11].Valid = true;
_game.UsedMap.Boards[12].Valid = true;
_game.UsedMap.Boards[10].Value = 2; // 1,3 // penalty
_game.UsedMap.Boards[7].Value = 5; // 1,0
_game.UsedMap.Boards[8].Value = 5; // 1,1
_game.UsedMap.Boards[9].Value = 5; // 1,2
var place = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(place);
_game.PlayerCell = new Cell(4, 1);
_game.PlayerCell.Value = 7;
_game.PlayerCell.Valid = true;
_game.PlayerCell.IsDangerous = true;
place.Invoke(_game, new object[] { _game.PlayerCell, 7 }); //One penalty
_game.PlayerCell = new Cell(5, 1);
_game.PlayerCell.Value = 14;
_game.PlayerCell.Valid = true;
place.Invoke(_game, new object[] { _game.PlayerCell, 14 });
foreach (var cells in _game.UsedMap.Boards.ToList())
{
_game.GameRules.IsZoneValidAndAddToZones(cells, _game.UsedMap);
}
_game.PutPenaltyForLostCells(_game.UsedMap.Boards);
Assert.True(_game.UsedMap.Boards[11].Penalty);
Assert.Equal(9, _game.CalculusOfPenalty(_game.UsedMap.Boards));
}
[Fact]
public void CanIModifyAPlayer()
{
Game game = new Game();
Player player = new Player("test", "DefaultProfilePicture");
game.AddPlayer(player);
game.ModifyPlayer("test", "newName");
Assert.Equal("newName", game.Players[0].Pseudo);
}
[Fact]
public void CanIModifyANonExistentPlayer()
{
Game game = new Game();
var res = game.ModifyPlayer("nope", "newName");
Assert.False(res);
}
[Fact] _game.UsedMap.Boards[0].Valid = true;
public void CanIRollDice() _game.UsedMap.Boards[1].Valid = true;
{ _game.UsedMap.Boards[2].Valid = true;
_game.InitializeGame(new Map("test", "test.png"), new Player("test", "test.png"), false); _game.UsedMap.Boards[3].Valid = true;
_game.RollAllDice();
Assert.NotNull(_game.Dice1);
Assert.NotNull(_game.Dice2);
Assert.True(_game.Dice1.Value >= 0 && _game.Dice1.Value <= 5 );
Assert.True(_game.Dice2.Value >= 1 && _game.Dice2.Value <= 6 );
}
[Fact]
public void CanIStartGame()
{
_game.InitializeGame(new Map("test", "test.png"), new Player("test", "test.png"), false);
var start = typeof(Game).GetMethod("StartGame", BindingFlags.NonPublic | BindingFlags.Instance); _game.UsedMap.Boards[0].Value = 0;
Assert.NotNull(start); methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[0], _game.GameRules.EveryAdjacentCells(_game.UsedMap.Boards[0], _game.UsedMap.Boards.ToList()) });
_game.UsedMap.Boards[1].Value = 1;
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[1], _game.GameRules.EveryAdjacentCells(_game.UsedMap.Boards[1], _game.UsedMap.Boards.ToList()) });
_game.UsedMap.Boards[2].Value = 2;
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[2], _game.GameRules.EveryAdjacentCells(_game.UsedMap.Boards[2], _game.UsedMap.Boards.ToList()) });
_game.UsedMap.Boards[3].Value = 5;
start.Invoke(_game, null); _game.PutPenaltyForLostCells(_game.UsedMap.Boards);
Assert.True(_game.IsRunning);
}
[Fact]
public void CanIEndGame()
{
_game.InitializeGame(new Map("test", "test.png"), new Player("test", "test.png"), false);
var start = typeof(Game).GetMethod("StartGame", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(start);
start.Invoke(_game, null); Assert.True(_game.UsedMap.Boards[3].Penalty);
var end = typeof(Game).GetMethod("EndGame", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(end);
end.Invoke(_game, new object[] { 14 } ); Assert.Equal(3, _game.CalculusOfPenalty(_game.UsedMap.Boards));
Assert.False(_game.IsRunning);
} }
[Fact] [Fact]
public void CalculusOfPointsWorksWellOrNot() public void CalculusOfPenalty_ReallyCalculusPenalty_ForZonesAndDangerousCellsAndOverTwelve()
{ {
_game.InitializeGame(new Map("test", "test.png"), new Player("test", "test.png"), false); var player = new Player("test_player", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
_game.InitializeGame(map, player);
_game.UsedMap.Boards[7].Valid = true; _game.UsedMap.Boards[7].Valid = true;
_game.UsedMap.Boards[8].Valid = true; _game.UsedMap.Boards[8].Valid = true;
@ -544,20 +497,24 @@ public class GameTests
_game.UsedMap.Boards[11].Valid = true; _game.UsedMap.Boards[11].Valid = true;
_game.UsedMap.Boards[12].Valid = true; _game.UsedMap.Boards[12].Valid = true;
_game.UsedMap.Boards[10].Value = 2; // penalty (- 3) _game.UsedMap.Boards[10].Value = 2; // 1,3 // penalty
_game.UsedMap.Boards[7].Value = 5; //5 + 2 = 7 _game.UsedMap.Boards[7].Value = 5; // 1,0
_game.UsedMap.Boards[8].Value = 5; _game.UsedMap.Boards[8].Value = 5; // 1,1
_game.UsedMap.Boards[9].Value = 5; _game.UsedMap.Boards[9].Value = 5; // 1,2
var place = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance); var place = typeof(Game).GetMethod("PlaceResult", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(place); Assert.NotNull(place);
_game.PlayerCell = new Cell(4, 1); var cell = new Cell(1, 4);
_game.PlayerCell.Value = 7; cell.Value = 7;
_game.PlayerCell.Valid = true; cell.Valid = true;
_game.PlayerCell.IsDangerous = true; cell.IsDangerous = true;
place.Invoke(_game, new object[] { _game.PlayerCell, 7 }); //One penalty place.Invoke(_game, new object[] { cell, 7 }); //One penalty
var othercell = new Cell(1, 5);
cell.Value = 14;
cell.Valid = true;
place.Invoke(_game, new object[] { othercell, 14 });
foreach (var cells in _game.UsedMap.Boards.ToList()) foreach (var cells in _game.UsedMap.Boards.ToList())
@ -568,127 +525,7 @@ public class GameTests
_game.PutPenaltyForLostCells(_game.UsedMap.Boards); _game.PutPenaltyForLostCells(_game.UsedMap.Boards);
Assert.True(_game.UsedMap.Boards[11].Penalty); Assert.True(_game.UsedMap.Boards[11].Penalty);
Assert.Equal(9, _game.CalculusOfPenalty(_game.UsedMap.Boards));
Assert.Equal(1, _game.FinalCalculusOfPoints());
}
[Fact]
public void CalculusOfPointsWorksWellOrNotForRopePathes()
{
_game.InitializeGame(new Map("test", "test.png"), new Player("test", "test.png"), false);
var methodInfo = typeof(Game).GetMethod("AddToRopePath", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(methodInfo);
_game.Turn = 2;
_game.UsedMap.Boards[7].Valid = true;
_game.UsedMap.Boards[8].Valid = true;
_game.UsedMap.Boards[9].Valid = true;
_game.UsedMap.Boards[10].Valid = true;
_game.UsedMap.Boards[7].Value = 5; //7 + 2 = 9
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[7] });
_game.UsedMap.Boards[8].Value = 6;
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[8] });
_game.UsedMap.Boards[9].Value = 7;
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[9] });
_game.UsedMap.Boards[10].Value = 2; // penalty (- 3)
methodInfo.Invoke(_game, new object[] { _game.UsedMap.Boards[10] });
_game.PutPenaltyForLostCells(_game.UsedMap.Boards);
Assert.True(_game.UsedMap.Boards[10].Penalty);
Assert.Equal(6, _game.FinalCalculusOfPoints());
}
[Fact]
public void AddBestScore_AddsNewBestScoreToList()
{
var game = new Game(_mockPersistence.Object);
var player = new Player("John Doe", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
game.InitializeGame(map, player, false);
game.AddBestScore(100);
Assert.Single(game.BestScores);
Assert.Equal(100, game.BestScores[0].Score);
Assert.Equal(player, game.BestScores[0].ThePlayer);
Assert.Equal(map.Name, game.BestScores[0].MapName);
}
[Fact]
public void AddBestScore_UpdatesExistingBestScoreAndIncrementsGamesPlayed()
{
var game = new Game(_mockPersistence.Object);
var player = new Player("John Doe", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
game.InitializeGame(map, player, false);
game.AddBestScore(100);
game.AddBestScore(200);
Assert.Single(game.BestScores);
Assert.Equal(300, game.BestScores[0].Score);
Assert.Equal(2, game.BestScores[0].GamesPlayed);
Assert.Equal(player, game.BestScores[0].ThePlayer);
Assert.Equal(map.Name, game.BestScores[0].MapName);
}
[Fact]
public void AddBestScore_SortsBestScoresCorrectly()
{
var game = new Game(_mockPersistence.Object);
var player1 = new Player("John Doe", "DefaultProfilePicture");
var player2 = new Player("John Does", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
game.InitializeGame(map, player1, false);
game.AddBestScore(100);
game.InitializeGame(map, player2, false);
game.AddBestScore(200);
Assert.Equal(2, game.BestScores.Count);
Assert.Equal(200, game.BestScores[0].Score);
Assert.Equal(player2, game.BestScores[0].ThePlayer);
Assert.Equal(100, game.BestScores[1].Score);
Assert.Equal(player1, game.BestScores[1].ThePlayer);
}
[Fact]
public void CheckAndRemoveBestScoresDependencies_RemovesDependenciesCorrectly()
{
var game = new Game(_mockPersistence.Object);
var player = new Player("John Doe", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
game.InitializeGame(map, player, false);
game.AddBestScore(100);
game.CheckAndRemoveBestScoresDependencies(player.Pseudo);
Assert.DoesNotContain(game.BestScores, bs => bs.ThePlayer.Pseudo == player.Pseudo);
}
[Fact]
public void CheckAndChangeBestScoresDependencies_ChangesDependenciesCorrectly()
{
var game = new Game(_mockPersistence.Object);
var player = new Player("John Doe", "DefaultProfilePicture");
var map = new Map("test_name", "test_background.png");
game.InitializeGame(map, player, false);
game.AddBestScore(100);
game.CheckAndChangeBestScoresDependencies(player.Pseudo, "John Does");
Assert.All(game.BestScores, bs => Assert.NotEqual("John Doe", bs.ThePlayer.Pseudo));
Assert.Contains(game.BestScores, bs => bs.ThePlayer.Pseudo == "John Does");
} }
} }

@ -27,7 +27,7 @@ public class MapTests
Assert.Equal(49, map.Boards.Count); Assert.Equal(49, map.Boards.Count);
for (int i = 0; i < 36; i++) for (int i = 0; i < 36; i++)
{ {
Assert.Equal(new Cell(i % 7, i / 7), map.Boards[i]); Assert.Equal(new Cell(i / 7, i % 7), map.Boards[i]);
} }
} }
@ -92,17 +92,6 @@ public class MapTests
var paths = new List<Cell> { cell }; var paths = new List<Cell> { cell };
map.RopePaths.Add(paths); map.RopePaths.Add(paths);
Assert.False(map.IsCellInRopePath(othercell)); Assert.False(map.IsCellInRopePath(othercell));
}
[Fact]
public void Clone_ReturnsNewMap()
{
var map = new Map("test_name", "test_background.png");
var clone = map.Clone();
Assert.NotEqual(map, clone);
Assert.Equal(map.Name, clone.Name);
Assert.Equal(map.Background, clone.Background);
} }
} }

@ -11,7 +11,6 @@ public class PlayerTests
var player = new Player(pseudo, profilePicture); var player = new Player(pseudo, profilePicture);
Assert.Equal(pseudo, player.Pseudo); Assert.Equal(pseudo, player.Pseudo);
Assert.Equal(profilePicture, player.ProfilePicture); Assert.Equal(profilePicture, player.ProfilePicture);
Assert.Null(player.LastPlayed);
} }
[Theory] [Theory]
@ -47,15 +46,4 @@ public class PlayerTests
Player player = new Player("test_pseudo", "DefaultProfilePicture"); Player player = new Player("test_pseudo", "DefaultProfilePicture");
Assert.False(player.Equals(new Cell(0, 0))); Assert.False(player.Equals(new Cell(0, 0)));
} }
[Fact]
public void UpdateLastPlayed_UpdatesLastPlayedDate()
{
var player = new Player("John Doe", "DefaultProfilePicture");
player.UpdateLastPlayed();
Assert.NotNull(player.LastPlayed);
Assert.Equal(DateTime.Now.ToString("dd/MM/yyyy"), player.LastPlayed);
}
} }

@ -44,7 +44,6 @@ public class RulesTests
{ {
Rules rules = new Rules(); Rules rules = new Rules();
Map map = new Map("test", "background"); Map map = new Map("test", "background");
map.Boards[0].Valid = true;
Cell selectedCell = map.Boards[0]; Cell selectedCell = map.Boards[0];
Assert.True(rules.IsCellValid(selectedCell, map.Boards.ToList())); Assert.True(rules.IsCellValid(selectedCell, map.Boards.ToList()));
} }
@ -180,7 +179,6 @@ public class RulesTests
Cell cell1 = new Cell(0, 0); Cell cell1 = new Cell(0, 0);
Cell cell2 = new Cell(0, 1); Cell cell2 = new Cell(0, 1);
cell2.Value = 12; cell2.Value = 12;
cell2.Valid = true;
List<Cell> cells = new List<Cell> { cell2 }; List<Cell> cells = new List<Cell> { cell2 };
Assert.True(rules.NearCellIsValid(cell1, cells)); Assert.True(rules.NearCellIsValid(cell1, cells));
} }

@ -5,15 +5,15 @@ VisualStudioVersion = 17.8.34408.163
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trek-12", "Trek-12\Trek-12.csproj", "{41EE7BF8-DDE6-4B00-9434-076589C0B419}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Trek-12", "Trek-12\Trek-12.csproj", "{41EE7BF8-DDE6-4B00-9434-076589C0B419}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Models", "Models\Models.csproj", "{807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Models", "Models\Models.csproj", "{807AB723-7AD3-42DD-9DA6-7AA5B0A9AAB4}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{795F2C88-3C43-4795-9764-E52F7330888D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp", "ConsoleApp\ConsoleApp.csproj", "{795F2C88-3C43-4795-9764-E52F7330888D}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{383C4215-C680-4C2E-BC7E-B62F0B164370}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{383C4215-C680-4C2E-BC7E-B62F0B164370}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataContractPersistence", "DataContractPersistence\DataContractPersistence.csproj", "{FC6A23C3-A1E3-4BF4-85B0-404D8574E190}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataContractPersistence", "DataContractPersistence\DataContractPersistence.csproj", "{FC6A23C3-A1E3-4BF4-85B0-404D8574E190}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stub", "Stub\Stub.csproj", "{49360F7D-C59D-4B4F-AF5A-73FF61D9EF9B}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stub", "Stub\Stub.csproj", "{49360F7D-C59D-4B4F-AF5A-73FF61D9EF9B}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

@ -29,7 +29,7 @@ namespace Trek_12
Directory.CreateDirectory(FilePath); Directory.CreateDirectory(FilePath);
} }
//File.Delete(Path.Combine(FilePath, FileName)); File.Delete(Path.Combine(FilePath, FileName));
string fullPath = Path.Combine(FilePath, FileName); string fullPath = Path.Combine(FilePath, FileName);
if (File.Exists(fullPath)) if (File.Exists(fullPath))
@ -40,9 +40,9 @@ namespace Trek_12
/* Add the permanent maps if they are not already in the game */ /* Add the permanent maps if they are not already in the game */
if (Manager.Maps.Count == 0) if (Manager.Maps.Count == 0)
{ {
Manager.AddMap(new Map("Dunai","montagne2.png")); Manager.AddMap(new Map("Dunai","profile.jpg"));
Manager.AddMap(new Map("Kagkot", "montagne3.png")); Manager.AddMap(new Map("Kagkot","montagne1.png"));
Manager.AddMap(new Map("Dhaulagiri", "montagne4.png")); Manager.AddMap(new Map("Dhaulagiri","tmp1.jpeg"));
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 978 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks> <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
<!--<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>--> <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET --> <!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> --> <!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
@ -38,14 +38,6 @@
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion> <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="$([MSBuild]::IsOSPlatform('windows'))">
<TargetFrameworks>$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<WindowsPackageType>MSIX</WindowsPackageType>
<PackageCertificateThumbprint>404032fa5d4dc4c8bbf036505d2409963f355ebd</PackageCertificateThumbprint>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<!-- App Icon --> <!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\app_icon.png" /> <MauiIcon Include="Resources\AppIcon\app_icon.png" />
@ -55,6 +47,7 @@
<!-- Images --> <!-- Images -->
<MauiImage Include="Resources\Images\*" /> <MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<!-- Custom Fonts --> <!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" /> <MauiFont Include="Resources\Fonts\*" />
@ -68,9 +61,6 @@
<None Remove="Resources\Images\back_arrow.png" /> <None Remove="Resources\Images\back_arrow.png" />
<None Remove="Resources\Images\checked.png" /> <None Remove="Resources\Images\checked.png" />
<None Remove="Resources\Images\maptest.png" /> <None Remove="Resources\Images\maptest.png" />
<None Remove="Resources\Images\montagne2.png" />
<None Remove="Resources\Images\montagne3.png" />
<None Remove="Resources\Images\montagne4.png" />
<None Remove="Resources\Images\user.png" /> <None Remove="Resources\Images\user.png" />
</ItemGroup> </ItemGroup>

@ -1,6 +1,5 @@
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.VisualBasic;
namespace Trek_12.Views; namespace Trek_12.Views;
@ -11,7 +10,7 @@ public partial class PageBoard : ContentPage
{ {
public Game GameManager => (App.Current as App).Manager; public Game GameManager => (App.Current as App).Manager;
public int Result { get; set; } public int Resultat { get; set; }
public Cell ChoosenCell { get; set; } public Cell ChoosenCell { get; set; }
@ -19,7 +18,6 @@ public partial class PageBoard : ContentPage
{ {
InitializeComponent(); InitializeComponent();
BindingContext = GameManager; BindingContext = GameManager;
GameManager.CurrentPlayer.UpdateLastPlayed();
GameManager.DiceRolled += TheGame_DiceRolled; GameManager.DiceRolled += TheGame_DiceRolled;
GameManager.DiceRolled += ResultAddition; GameManager.DiceRolled += ResultAddition;
@ -28,52 +26,19 @@ public partial class PageBoard : ContentPage
GameManager.DiceRolled += ResultSubstraction; GameManager.DiceRolled += ResultSubstraction;
GameManager.DiceRolled += ResultMultiplication; GameManager.DiceRolled += ResultMultiplication;
GameManager.PlayerOption += GameManager_PlayerOption; GameManager.PlayerOption += GameManager_PlayerOption;
GameManager.CellChosen += HandleCellChosen;
// We add this game to the list of games
GameManager.AddGame(GameManager); GameManager.AddGame(GameManager);
GameManager.OnPropertyChanged(nameof(GameManager.Games)); GameManager.OnPropertyChanged(nameof(GameManager.Games));
GameManager.SaveData(); GameManager.SaveData();
} }
private void HandleCellChosen(object sender, CellChosenEventArgs e)
{
YellowDice.IsVisible = false;
RedDice.IsVisible = false;
RollButton.IsEnabled = true;
}
private void ResetOperationButtonsAndDice()
{
Lower.IsVisible = false;
Higher.IsVisible = false;
Substraction.IsVisible = false;
Addition.IsVisible = false;
Multiplication.IsVisible = false;
RollButton.IsEnabled = true;
YellowDice.IsVisible = false;
RedDice.IsVisible = false;
}
private void SetOperationButtonState(Button selectedButton)
{
// Deselect all buttons
Lower.BackgroundColor = Colors.DarkSalmon;
Higher.BackgroundColor = Colors.DarkSalmon;
Substraction.BackgroundColor = Colors.DarkSalmon;
Addition.BackgroundColor = Colors.DarkSalmon;
Multiplication.BackgroundColor = Colors.DarkSalmon;
// Select the clicked button
selectedButton.BackgroundColor = Colors.LightCoral;
}
private void GameManager_PlayerOption(object? sender, PlayerOptionEventArgs e) private void GameManager_PlayerOption(object? sender, PlayerOptionEventArgs e)
{ {
/* IEnumerable<Cell> PlayedCellsQuery = /* IEnumerable<Cell> PlayedCellsQuery =
from cell in e.Board from cell in e.Board
where cell.Valid == true where cell.Valid == true
where cell.Value != null where cell.Value != null
select cell;*/ select cell;*/
// prévisualisation des zone disponible, Je ne sais pas comment ca marche... 😵 // prévisualisation des zone disponible, Je ne sais pas comment ca marche... 😵
@ -127,7 +92,8 @@ public partial class PageBoard : ContentPage
private void OnOperationCellSelected(object sender, SelectionChangedEventArgs e) private void OnOperationCellSelected(object sender, SelectionChangedEventArgs e)
{ {
if (e.CurrentSelection.Count > 0) // Si un élément est sélectionné Debug.WriteLine("OnOperationCellSelected"); // Debug
if (e.CurrentSelection.Count > 0) // Si un <20>l<EFBFBD>ment est s<>lectionn<6E>
{ {
var selectedCell = (OperationCell)e.CurrentSelection[0]; var selectedCell = (OperationCell)e.CurrentSelection[0];
if (selectedCell != null && !selectedCell.IsChecked) if (selectedCell != null && !selectedCell.IsChecked)
@ -135,48 +101,38 @@ public partial class PageBoard : ContentPage
selectedCell.Check(); selectedCell.Check();
Debug.WriteLine("OperationCell at ({0}, {1}) is checked", selectedCell.X, selectedCell.Y); // Debug Debug.WriteLine("OperationCell at ({0}, {1}) is checked", selectedCell.X, selectedCell.Y); // Debug
} }
((CollectionView)sender).SelectedItem = null; // Déselectionne l'élément pour la CollectionView ((CollectionView)sender).SelectedItem = null; // D<EFBFBD>selectionne l'<27>l<EFBFBD>ment pour la CollectionView
} }
} }
private void HigherClicked(object sender, EventArgs e) private void HigherClicked(object sender, EventArgs e)
{ {
GameManager.PlayerOperation = Operation.HIGHER; GameManager.PlayerOperation = Operation.HIGHER;
SetOperationButtonState((Button)sender); Resultat = GameManager.PlayerChooseOperation();
Result = GameManager.ResultOperation(Operation.HIGHER);
GameManager.HandlePlayerOperation(Operation.HIGHER);
} }
private void LowerClicked(object sender, EventArgs e) private void LowerClicked(object sender, EventArgs e)
{ {
GameManager.PlayerOperation = Operation.LOWER; GameManager.PlayerOperation = Operation.LOWER;
SetOperationButtonState((Button)sender); Resultat = GameManager.PlayerChooseOperation();
Result = GameManager.ResultOperation(Operation.LOWER);
GameManager.HandlePlayerOperation(Operation.LOWER);
} }
private void AdditionClicked(object sender, EventArgs e) private void AdditionClicked(object sender, EventArgs e)
{ {
GameManager.PlayerOperation = Operation.ADDITION; GameManager.PlayerOperation = Operation.ADDITION;
SetOperationButtonState((Button)sender); Resultat = GameManager.PlayerChooseOperation();
Result = GameManager.ResultOperation(Operation.ADDITION);
GameManager.HandlePlayerOperation(Operation.ADDITION);
} }
private void SubstractionClicked(object sender, EventArgs e) private void SubstractionClicked(object sender, EventArgs e)
{ {
GameManager.PlayerOperation = Operation.SUBTRACTION; GameManager.PlayerOperation = Operation.SUBTRACTION;
SetOperationButtonState((Button)sender); Resultat = GameManager.PlayerChooseOperation();
Result = GameManager.ResultOperation(Operation.SUBTRACTION);
GameManager.HandlePlayerOperation(Operation.SUBTRACTION);
} }
private void MultiplicationClicked(object sender, EventArgs e) private void MultiplicationClicked(object sender, EventArgs e)
{ {
GameManager.PlayerOperation = Operation.MULTIPLICATION; GameManager.PlayerOperation = Operation.MULTIPLICATION;
SetOperationButtonState((Button)sender); Resultat = GameManager.PlayerChooseOperation();
Result = GameManager.ResultOperation(Operation.MULTIPLICATION);
GameManager.HandlePlayerOperation(Operation.MULTIPLICATION);
} }
private void DiceButton_Clicked(object sender, EventArgs e) private void DiceButton_Clicked(object sender, EventArgs e)
@ -184,33 +140,10 @@ public partial class PageBoard : ContentPage
GameManager.RollAllDice(); GameManager.RollAllDice();
} }
private async void OnCellSelected(object sender, SelectionChangedEventArgs e) private void OnCellSelected(object sender, SelectionChangedEventArgs e)
{ {
if (!GameManager.DiceRolledFlag) ChoosenCell = (Cell)e.CurrentSelection[0];
{ GameManager.PlayerCell = ChoosenCell;
await DisplayAlert("Action Required", "You must roll the dice first.", "OK"); GameManager.PlayerSelectionCell();
return;
}
if (!GameManager.OperationChosenFlag)
{
await DisplayAlert("Action Required", "You must choose an operation first.", "OK");
return;
}
if (e.CurrentSelection.Count > 0)
{
ChoosenCell = (Cell)e.CurrentSelection[0];
GameManager.PlayerCell = ChoosenCell;
GameManager.Resultat = Result;
OnPropertyChanged(nameof(GameManager.PlayerCell));
OnPropertyChanged(nameof(GameManager.Resultat));
GameManager.PlayerSelectionCell();
((CollectionView)sender).SelectedItem = null;
ResetOperationButtonsAndDice();
}
} }
} }

@ -42,16 +42,6 @@
</DataTemplate> </DataTemplate>
</CollectionView.ItemTemplate> </CollectionView.ItemTemplate>
</CollectionView> </CollectionView>
<Button Text="Reprendre"
TextColor="White"
BackgroundColor="DarkRed"
FontAttributes="Bold"
FontSize="Large"
Grid.Row="2"
Margin="80"
HorizontalOptions="Center"
Clicked="ResumeButton_Clicked"
IsVisible="{Binding IsPreviousGameNotFinished}"/>
<Button Text="Retour" <Button Text="Retour"
FontAttributes="Bold" FontAttributes="Bold"
FontSize="Large" FontSize="Large"

@ -10,14 +10,12 @@ public partial class PageSelectMap : ContentPage
public Game SelectMapManager => (App.Current as App).Manager; public Game SelectMapManager => (App.Current as App).Manager;
private Map? _selectedMap; private Map? _selectedMap;
private bool isVisibleContinueButton = false;
protected override async void OnAppearing() protected override async void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
if (SelectMapManager.Games.Any(g => g.IsRunning)) if (SelectMapManager.Games.Any(g => g.IsRunning))
{ {
isVisibleContinueButton = true;
await DisplayAlert("Warning", "You've previously quit in the middle of a game.\nIf you start a new game, this one will be permanently lost.", "I understand"); await DisplayAlert("Warning", "You've previously quit in the middle of a game.\nIf you start a new game, this one will be permanently lost.", "I understand");
} }
@ -59,26 +57,9 @@ public partial class PageSelectMap : ContentPage
Player chosenPlayer = GetProfileByName(choosenPlayerName); Player chosenPlayer = GetProfileByName(choosenPlayerName);
var runningGames = SelectMapManager.Games.Where(g => g.IsRunning).ToList(); SelectMapManager.InitializeGame(_selectedMap, chosenPlayer);
bool delete = false;
foreach (var game in runningGames)
{
SelectMapManager.Games.Remove(game);
delete = true;
}
if (delete)
{
await DisplayAlert("Game deleted", "The previous game has been deleted because you started a new one.", "OK");
SelectMapManager.OnPropertyChanged(nameof(SelectMapManager.Games));
SelectMapManager.SaveData();
}
SelectMapManager.InitializeGame(_selectedMap.Clone(), chosenPlayer);
if (SelectMapManager.UsedMap != null && Equals(SelectMapManager.CurrentPlayer, chosenPlayer)) if (SelectMapManager.UsedMap == _selectedMap && Equals(SelectMapManager.CurrentPlayer, chosenPlayer))
{ {
await Shell.Current.GoToAsync(nameof(PageBoard)); await Shell.Current.GoToAsync(nameof(PageBoard));
} }
@ -98,17 +79,4 @@ public partial class PageSelectMap : ContentPage
return SelectMapManager.Players.FirstOrDefault(p => p.Pseudo == pseudo); return SelectMapManager.Players.FirstOrDefault(p => p.Pseudo == pseudo);
} }
private async void ResumeButton_Clicked(object sender, EventArgs e)
{
Game game = SelectMapManager.Games.FirstOrDefault(g => g.IsRunning);
if (game == null)
{
await DisplayAlert("No game found", "No game found to resume. Please start a new game.", "OK");
return;
}
SelectMapManager.InitializeGame(game.UsedMap, game.CurrentPlayer, false);
await Shell.Current.GoToAsync(nameof(PageBoard));
}
} }
Loading…
Cancel
Save