Merge branch 'master' of https://codefirst.iut.uca.fr/git/jeremy.mouyon/sae201_qwirkle
continuous-integration/drone/push Build is passing Details

test_old_branch
Jérémy Mouyon 11 months ago
commit c446099974

@ -0,0 +1 @@
<Leaderboard xmlns="http://schemas.datacontract.org/2004/07/QwirkleClassLibrary.Players" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><leaderboard><Score><Date>2024-05-31T00:00:00+02:00</Date><PlayerName>Jérémy</PlayerName><Points>0</Points><Victories>1</Victories></Score><Score><Date>2024-05-31T00:00:00+02:00</Date><PlayerName>Jules</PlayerName><Points>0</Points><Victories>0</Victories></Score></leaderboard></Leaderboard>

File diff suppressed because one or more lines are too long

@ -122,7 +122,7 @@ namespace QwirkleClassLibrary.Boards
return null; return null;
} }
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }

@ -85,7 +85,7 @@ public class Cell : INotifyPropertyChanged
} }
} }
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }

@ -1,7 +1,12 @@
namespace QwirkleClassLibrary.Events namespace QwirkleClassLibrary.Events
{ {
public class SwapTilesNotifiedEventArgs(string reason) public class SwapTilesNotifiedEventArgs
{ {
public string Reason { get; private set; } = reason; public string Reason { get; private set; }
public SwapTilesNotifiedEventArgs(string reason)
{
Reason = reason;
}
} }
} }

@ -20,21 +20,25 @@ namespace QwirkleClassLibrary.Games
[DataContract] [DataContract]
public class Game : IPlayer, IRules public class Game : IPlayer, IRules
{ {
public ReadOnlyDictionary<Player, int> ScoreBoard => scoreBoard.AsReadOnly();
private readonly Dictionary<Player, int> scoreBoard = new();
private TileBag? bag = null; private TileBag? bag = null;
[DataMember] [DataMember]
public bool GameRunning { get; private set; } public bool GameRunning { get; set; }
[DataMember] [DataMember]
private Board board = new Board(15, 12); private Board board = new Board(15, 12);
public Board Board => board; public Board Board => board;
public ReadOnlyCollection<Player> PlayerList => players.AsReadOnly(); public ReadOnlyCollection<Player> PlayerList => players.AsReadOnly();
[DataMember]
private readonly List<Player> players = new(); private readonly List<Player> players = new();
[DataMember]
private readonly Dictionary<Player, int> scoreBoard = new();
public ReadOnlyDictionary<Player, int> ScoreBoard => scoreBoard.AsReadOnly();
public ReadOnlyCollection<Cell> CellsUsed => cellUsed.AsReadOnly(); public ReadOnlyCollection<Cell> CellsUsed => cellUsed.AsReadOnly();
private readonly List<Cell> cellUsed = new(); private readonly List<Cell> cellUsed = new();
@ -259,7 +263,7 @@ namespace QwirkleClassLibrary.Games
{ {
for (int j = 0; j < 6; j++) for (int j = 0; j < 6; j++)
{ {
if (bag != null) if (bag != null && p.Tiles.Count < 6)
{ {
int val = RandomNumberGenerator.GetInt32(0, bag.TilesBag.Count); int val = RandomNumberGenerator.GetInt32(0, bag.TilesBag.Count);
@ -333,16 +337,14 @@ namespace QwirkleClassLibrary.Games
return false; return false;
} }
public bool TileInbag(Player player, Tile tile) private bool TileInbag(Player player, Tile tile)
{ {
for (int i = 0; i < player.Tiles.Count; i++) foreach (var t in player.Tiles)
{ {
Tile? t = player.Tiles[i]; if (ReferenceEquals(t, tile)) return true;
if (Object.ReferenceEquals(t, tile)) return true;
} }
return false;
return false;
} }

@ -0,0 +1,27 @@
using System.Runtime.Serialization;
using QwirkleClassLibrary.Games;
namespace QwirkleClassLibrary.Persistences;
public class GamePersistenceJson : IGamePersistence
{
public void SaveGame(Game game)
{
var serializer = new DataContractSerializer(typeof(Game));
using (Stream writer = File.Create("Game.json"))
{
serializer.WriteObject(writer, game);
}
}
public Game LoadGame()
{
var serializer = new DataContractSerializer(typeof(Game));
using (Stream reader = File.OpenRead("Game.json"))
{
return serializer.ReadObject(reader) as Game ?? throw new InvalidOperationException();
}
}
}

@ -0,0 +1,10 @@
using QwirkleClassLibrary.Games;
namespace QwirkleClassLibrary.Persistences;
public interface IGamePersistence
{
void SaveGame(Game game);
Game LoadGame();
}

@ -0,0 +1,10 @@
using QwirkleClassLibrary.Players;
namespace QwirkleClassLibrary.Persistences;
public interface ILeaderboardPersistence
{
void SaveLeaderboard(Leaderboard leaderboard);
Leaderboard LoadLeaderboard();
}

@ -0,0 +1,27 @@
using System.Runtime.Serialization;
using QwirkleClassLibrary.Players;
namespace QwirkleClassLibrary.Persistences;
public class LeaderboardPersistenceJson : ILeaderboardPersistence
{
public void SaveLeaderboard(Leaderboard leaderboard)
{
var serializer = new DataContractSerializer(typeof(Leaderboard));
using (Stream writer = File.Create("Leaderboard.json"))
{
serializer.WriteObject(writer, leaderboard);
}
}
public Leaderboard LoadLeaderboard()
{
var serializer = new DataContractSerializer(typeof(Leaderboard));
using (Stream reader = File.OpenRead("Leaderboard.json"))
{
return serializer.ReadObject(reader) as Leaderboard ?? throw new InvalidOperationException();
}
}
}

@ -3,14 +3,18 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace QwirkleClassLibrary.Players namespace QwirkleClassLibrary.Players
{ {
[DataContract]
public class Leaderboard public class Leaderboard
{ {
public ReadOnlyCollection<Score> Lb => leaderboard.AsReadOnly(); public ReadOnlyCollection<Score> Lb => leaderboard.AsReadOnly();
[DataMember]
private readonly List<Score> leaderboard = new(); private readonly List<Score> leaderboard = new();

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -11,20 +12,15 @@ using QwirkleClassLibrary.Tiles;
namespace QwirkleClassLibrary.Players namespace QwirkleClassLibrary.Players
{ {
[DataContract]
public class Player : INotifyPropertyChanged public class Player : INotifyPropertyChanged
{ {
private ObservableCollection<Tile> playerTiles = new ObservableCollection<Tile>(); [DataMember]
public ObservableCollection<Tile> Tiles public ObservableCollection<Tile> Tiles { get; private set; }
{
get { return playerTiles; }
set
{
playerTiles = value;
OnPropertyChanged(nameof(Tiles));
}
}
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));
@ -41,10 +37,13 @@ namespace QwirkleClassLibrary.Players
} }
NameTag = name; NameTag = name;
Tiles = new ObservableCollection<Tile>();
} }
public string NameTag { get; } [DataMember]
public string NameTag { get; set; }
[DataMember]
public bool IsPlaying { get; set; } = false; public bool IsPlaying { get; set; } = false;
/// <summary> /// <summary>
@ -53,7 +52,7 @@ namespace QwirkleClassLibrary.Players
/// <param name="tile"></param> /// <param name="tile"></param>
public void AddTileToPlayer(Tile tile) public void AddTileToPlayer(Tile tile)
{ {
playerTiles.Add(tile); Tiles.Add(tile);
OnPropertyChanged(nameof(Tiles)); OnPropertyChanged(nameof(Tiles));
} }
@ -64,7 +63,7 @@ namespace QwirkleClassLibrary.Players
/// <returns>bool</returns> /// <returns>bool</returns>
public bool RemoveTileToPlayer(Tile tile) public bool RemoveTileToPlayer(Tile tile)
{ {
if (playerTiles.Remove(tile)) if (Tiles.Remove(tile))
{ {
OnPropertyChanged(nameof(Tiles)); OnPropertyChanged(nameof(Tiles));
return true; return true;

@ -3,16 +3,25 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace QwirkleClassLibrary.Players namespace QwirkleClassLibrary.Players
{ {
[DataContract]
public class Score public class Score
{ {
[DataMember]
public string PlayerName { get; private set; } public string PlayerName { get; private set; }
[DataMember]
public DateTime Date { get; set; } public DateTime Date { get; set; }
[DataMember]
public int Points { get; set; } public int Points { get; set; }
[DataMember]
public int Victories { get; set; } public int Victories { get; set; }
/// <summary> /// <summary>

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.Serialization;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;

@ -36,7 +36,6 @@ namespace QwirkleClassLibrary.Tiles
} }
} }
TilesBag = tiles.AsReadOnly(); TilesBag = tiles.AsReadOnly();
} }

@ -12,6 +12,7 @@ using System.Runtime.Serialization;
using System.Runtime.Serialization.Json; using System.Runtime.Serialization.Json;
using System.Text; using System.Text;
using System.Transactions; using System.Transactions;
using QwirkleClassLibrary.Persistences;
using static System.Console; using static System.Console;
@ -173,7 +174,7 @@ static void MenuSwitch(Game game)
{ {
int enter = 0; int enter = 0;
while (enter != 3) while (enter != 3 && game.GameRunning)
{ {
ShowBoard(game); ShowBoard(game);
@ -186,6 +187,7 @@ static void MenuSwitch(Game game)
WriteLine("[1] Place your tiles"); WriteLine("[1] Place your tiles");
WriteLine("[2] Swap your tiles"); WriteLine("[2] Swap your tiles");
WriteLine("[3] End your turn / Skip your turn"); WriteLine("[3] End your turn / Skip your turn");
WriteLine("[4] Save the game");
Write("Enter your choice : "); Write("Enter your choice : ");
try try
@ -215,7 +217,17 @@ static void MenuSwitch(Game game)
game.EmptyCellUsed(); game.EmptyCellUsed();
game.DrawTiles(game.GetPlayingPlayer()); game.DrawTiles(game.GetPlayingPlayer());
game.CheckGameOver(game.GetPlayingPlayer()); game.CheckGameOver(game.GetPlayingPlayer());
IGamePersistence gameSave = new GamePersistenceJson();
gameSave.SaveGame(game);
return; return;
case 4:
IGamePersistence endGameSave = new GamePersistenceJson();
endGameSave.SaveGame(game);
game.GameRunning = false;
break;
} }
} }
} }
@ -231,20 +243,20 @@ static void ShowBoard(Game game)
Cell? cell = board.GetCell(y, i); Cell? cell = board.GetCell(y, i);
if (cell != null && !cell.IsFree) if (cell != null && !cell.IsFree)
{ {
Tile? tile = cell.GetTile; Tile? tile = cell.Tile;
if (tile != null) if (tile != null)
{ {
Console.Write("| " + tile.GetShape.ToString()[0] + tile.GetShape.ToString()[1] + Write("| " + tile.GetShape.ToString()[0] + tile.GetShape.ToString()[1] +
tile.GetColor.ToString()[0] + " |"); tile.GetColor.ToString()[0] + " |");
} }
} }
else else
{ {
Console.Write("| |"); Write("| |");
} }
} }
Console.WriteLine(); WriteLine();
} }
} }
@ -281,9 +293,9 @@ static void MainMenu(Game game)
{ {
game.GiveTilesToPlayers(); game.GiveTilesToPlayers();
Console.ForegroundColor = ConsoleColor.Green; ForegroundColor = ConsoleColor.Green;
WriteLine("Game is starting !"); WriteLine("Game is starting !");
Console.ResetColor(); ResetColor();
NotificationClass nc = new NotificationClass(); NotificationClass nc = new NotificationClass();
@ -309,12 +321,40 @@ static void MainMenu(Game game)
ShowScoreBoard(game); ShowScoreBoard(game);
} }
static void MainMenuContinue(Game game)
{
ForegroundColor = ConsoleColor.Green;
WriteLine("Game loaded ! You can continue the game !");
ResetColor();
NotificationClass nc = new NotificationClass();
do
{
game.NextPlayerNotified += nc.NotificationNextPlayer;
game.EndOfGameNotified += nc.NotificationEndOfGame;
game.SetNextPlayer();
WriteLine(" --------------------- GAME ! ------------------------");
MenuSwitch(game);
game.NextPlayerNotified -= nc.NotificationNextPlayer;
game.EndOfGameNotified -= nc.NotificationEndOfGame;
} while (game.GameRunning);
}
static void MainGame() static void MainGame()
{ {
Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), "..\\..\\..\\..\\Files"));
Leaderboard leaderboard = new Leaderboard(); Leaderboard leaderboard = new Leaderboard();
Console.ForegroundColor = ConsoleColor.DarkGray;
ForegroundColor = ConsoleColor.DarkGray;
WriteLine(" ===================== WELCOME TO QWIRKLE ! ====================="); WriteLine(" ===================== WELCOME TO QWIRKLE ! =====================");
Console.ResetColor(); ResetColor();
int enter = 0; int enter = 0;
@ -322,8 +362,9 @@ static void MainGame()
{ {
ForegroundColor = ConsoleColor.DarkCyan; ForegroundColor = ConsoleColor.DarkCyan;
WriteLine("[1] Create game"); WriteLine("[1] Create game");
WriteLine("[2] Show leaderboard"); WriteLine("[2] Load game");
WriteLine("[3] Exit"); WriteLine("[3] Show leaderboard");
WriteLine("[4] Exit");
WriteLine(); WriteLine();
ResetColor(); ResetColor();
WriteLine("Enter your choice : "); WriteLine("Enter your choice : ");
@ -347,47 +388,43 @@ static void MainGame()
ForegroundColor = ConsoleColor.DarkYellow; ForegroundColor = ConsoleColor.DarkYellow;
WriteLine("Enter minimun 2 player and max 4 player !\n"); WriteLine("Enter minimun 2 player and max 4 player !\n");
ResetColor(); ResetColor();
Game game = new Game(); Game game = new Game();
AddPlayers(game); AddPlayers(game);
game.StartGame(); game.StartGame();
MainMenu(game); MainMenu(game);
leaderboard.AddScoreInLead(game.ScoreBoard); leaderboard.AddScoreInLead(game.ScoreBoard);
break;
case 2: ILeaderboardPersistence leaderboardSave = new LeaderboardPersistenceJson();
ShowLeaderboard(leaderboard); leaderboardSave.SaveLeaderboard(leaderboard);
break;
case 3: break;
return;
}
} case 2:
} Game loadedGame;
// MainGame(); IGamePersistence gameLoad = new GamePersistenceJson();
loadedGame = gameLoad.LoadGame();
var game = new Game(); ILeaderboardPersistence leaderboardLoad = new LeaderboardPersistenceJson();
game.AddPlayerInGame(["Player1", "Player2", "Player3", "Player4"]); leaderboard = leaderboardLoad.LoadLeaderboard();
game.StartGame(); MainMenuContinue(loadedGame);
game.SetNextPlayer(); leaderboard.AddScoreInLead(loadedGame.ScoreBoard);
game.PlaceTile(game.GetPlayingPlayer(), new Tile(Shape.Round, Color.Blue), 0, 0); break;
game.PlaceTile(game.GetPlayingPlayer(), new Tile(Shape.Square, Color.Blue), 0, 1);
Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), "..\\..\\..\\..\\Files")); case 3:
ShowLeaderboard(leaderboard);
break;
var serializer = new DataContractJsonSerializer(typeof(Game)); case 4:
using (Stream s = File.Create("game.json")) return;
{
serializer.WriteObject(s, game);
} }
Game game2; }
using (Stream s = File.OpenRead("game.json"))
{
game2 = (serializer.ReadObject(s) as Game)!;
} }
WriteLine(game2.GetBoard()!.GetCell(0, 0)!.GetTile); MainGame();

@ -320,15 +320,19 @@ public class TestGame
Tile t2 = new Tile(Shape.Club, Color.Purple); Tile t2 = new Tile(Shape.Club, Color.Purple);
Tile t3 = new Tile(Shape.Round, Color.Red); Tile t3 = new Tile(Shape.Round, Color.Red);
game.PlaceTile(game.GetPlayingPlayer(), t1, 0, 0); game.GetPlayingPlayer().Tiles.Add(t1);
game.GetPlayingPlayer().Tiles.Add(t2);
game.GetPlayingPlayer().Tiles.Add(t3);
game.PlaceTile(game.GetPlayingPlayer(), game.GetPlayingPlayer().Tiles[0], 0, 0);
if (except) if (except)
{ {
Assert.True(game.IsMoveCorrect(t3, 0, 1, game.GetBoard()!)); Assert.True(game.IsMoveCorrect(game.GetPlayingPlayer().Tiles[1], 0, 1, game.GetBoard()!));
} }
else else
{ {
Assert.False(game.IsMoveCorrect(t2, 0, 1, game.GetBoard()!)); Assert.False(game.IsMoveCorrect(game.GetPlayingPlayer().Tiles[0], 0, 1, game.GetBoard()!));
} }
} }
@ -350,6 +354,12 @@ public class TestGame
Tile t6 = new Tile(Shape.Rhombus, Color.Red); Tile t6 = new Tile(Shape.Rhombus, Color.Red);
Tile t7 = new Tile(Shape.Round, Color.Red); Tile t7 = new Tile(Shape.Round, Color.Red);
game.GetPlayingPlayer().Tiles.Add(t1);
game.GetPlayingPlayer().Tiles.Add(t2);
game.GetPlayingPlayer().Tiles.Add(t3);
game.GetPlayingPlayer().Tiles.Add(t4);
game.GetPlayingPlayer().Tiles.Add(t5);
game.GetPlayingPlayer().Tiles.Add(t6);
game.PlaceTile(game.GetPlayingPlayer(), t1, 0, 0); game.PlaceTile(game.GetPlayingPlayer(), t1, 0, 0);
game.PlaceTile(game.GetPlayingPlayer(), t2, 1, 0); game.PlaceTile(game.GetPlayingPlayer(), t2, 1, 0);
@ -358,6 +368,7 @@ public class TestGame
game.PlaceTile(game.GetPlayingPlayer(), t5, 4, 0); game.PlaceTile(game.GetPlayingPlayer(), t5, 4, 0);
game.PlaceTile(game.GetPlayingPlayer(), t6, 5, 0); game.PlaceTile(game.GetPlayingPlayer(), t6, 5, 0);
game.GetPlayingPlayer().Tiles.Add(t7);
Assert.False(game.IsMoveCorrect(t7, 6, 0, game.GetBoard()!)); Assert.False(game.IsMoveCorrect(t7, 6, 0, game.GetBoard()!));

Loading…
Cancel
Save