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

master
Jérémy Mouyon 1 year ago
commit 019307e893

File diff suppressed because one or more lines are too long

@ -53,7 +53,7 @@ namespace QwirkleClassLibrary.Boards
{ {
for (int b = 0; b < Columns; b++) for (int b = 0; b < Columns; b++)
{ {
Cell localcell = new(a, b); Cell localcell = new(b, a);
cells.Add(localcell); cells.Add(localcell);
} }
} }

@ -61,7 +61,7 @@ public class Cell : INotifyPropertyChanged
/// <returns>True if the cell is empty, false if the cell contains a tile.</returns> /// <returns>True if the cell is empty, false if the cell contains a tile.</returns>
public bool IsFree public bool IsFree
{ {
get { return Tile == null; } get { return Tile! == null!; }
} }
@ -72,7 +72,7 @@ public class Cell : INotifyPropertyChanged
/// <returns>True if added succefully (if the cell didn't already contain a tile), false if there already was a tile in this cell.</returns> /// <returns>True if added succefully (if the cell didn't already contain a tile), false if there already was a tile in this cell.</returns>
public bool SetTile(Tile addedTile) public bool SetTile(Tile addedTile)
{ {
if (Tile == null) if (Tile! == null!)
{ {
Tile = addedTile; Tile = addedTile;

@ -7,43 +7,34 @@ using QwirkleClassLibrary.Events;
using QwirkleClassLibrary.Players; using QwirkleClassLibrary.Players;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using static System.Formats.Asn1.AsnWriter;
namespace QwirkleClassLibrary.Games namespace QwirkleClassLibrary.Games
{ {
[DataContract] [DataContract]
public class Game : IPlayer, IRules, INotifyPropertyChanged public class Game : IPlayer, IRules, INotifyPropertyChanged
{ {
[DataMember] [DataMember] private TileBag? bag = null;
private TileBag? bag = null;
[DataMember] [DataMember] public bool GameRunning { get; set; }
public bool GameRunning { get; set; }
[DataMember] [DataMember] private Board board = new(17, 14);
private Board board = new(17, 14);
public bool PlayerSwapping { get; set; } public bool PlayerSwapping { get; set; }
public Board Board => board; public Board Board => board;
public ReadOnlyCollection<Player> PlayerList => players.AsReadOnly(); public ReadOnlyCollection<Player> PlayerList => players.AsReadOnly();
[DataMember] [DataMember] private readonly List<Player> players = [];
private readonly List<Player> players = [];
[DataMember] [DataMember] private readonly Dictionary<string, int> scoreBoard = new Dictionary<string, int>();
private readonly Dictionary<string, int> scoreBoard = new Dictionary<string, int>();
public ReadOnlyDictionary<string, int> ScoreBoard => scoreBoard.AsReadOnly(); public ReadOnlyDictionary<string, int> ScoreBoard => scoreBoard.AsReadOnly();
[DataMember] [DataMember] private readonly ObservableCollection<KeyValuePair<string, int>> observableScoreBoard = [];
private readonly ObservableCollection<KeyValuePair<string, int>> observableScoreBoard = [];
public ReadOnlyObservableCollection<KeyValuePair<string, int>> ObservableScoreBoard => public ReadOnlyObservableCollection<KeyValuePair<string, int>> ObservableScoreBoard =>
new(observableScoreBoard); new(observableScoreBoard);
[DataMember] [DataMember] private readonly List<Cell> cellUsed = [];
private readonly List<Cell> cellUsed = [];
public ReadOnlyCollection<Cell> CellsUsed => cellUsed.AsReadOnly(); public ReadOnlyCollection<Cell> CellsUsed => cellUsed.AsReadOnly();
@ -104,9 +95,11 @@ namespace QwirkleClassLibrary.Games
if (playersTag.Count <= 1 || playersTag.Count > 4) if (playersTag.Count <= 1 || playersTag.Count > 4)
{ {
playersTag.Clear(); playersTag.Clear();
OnPlayerNotified(new AddPlayerNotifiedEventArgs("ERROR : It takes a minimum of 2 players and a maximum of 4 players to start a game.")); OnPlayerNotified(new AddPlayerNotifiedEventArgs(
"ERROR : It takes a minimum of 2 players and a maximum of 4 players to start a game."));
return false; return false;
} }
for (int i = playersTag.Count - 1; i >= 0; i--) for (int i = playersTag.Count - 1; i >= 0; i--)
{ {
if (!CheckPlayerTag(playersTag, i)) if (!CheckPlayerTag(playersTag, i))
@ -131,7 +124,8 @@ namespace QwirkleClassLibrary.Games
{ {
if (string.IsNullOrWhiteSpace(playersTag[pos])) if (string.IsNullOrWhiteSpace(playersTag[pos]))
{ {
OnPlayerNotified(new AddPlayerNotifiedEventArgs("ERROR with " + (pos + 1) + " entry : The name is null or white space.")); OnPlayerNotified(new AddPlayerNotifiedEventArgs("ERROR with " + (pos + 1) +
" entry : The name is null or white space."));
return false; return false;
} }
@ -148,7 +142,6 @@ namespace QwirkleClassLibrary.Games
new AddPlayerNotifiedEventArgs("ERROR with " + (pos + 1) + " entry : Name alreay taken")); new AddPlayerNotifiedEventArgs("ERROR with " + (pos + 1) + " entry : Name alreay taken"));
return false; return false;
} }
} }
return true; return true;
@ -170,13 +163,19 @@ namespace QwirkleClassLibrary.Games
/// Returns the Board of the game /// Returns the Board of the game
/// </summary> /// </summary>
/// <returns>Board</returns> /// <returns>Board</returns>
public Board? GetBoard() { return board; } public Board GetBoard()
{
return board;
}
/// <summary> /// <summary>
/// Returns the tile bag of the game /// Returns the tile bag of the game
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public TileBag? GetTileBag() { return bag; } public TileBag? GetTileBag()
{
return bag;
}
/// <summary> /// <summary>
/// Creates a Board with a number of columns and rows /// Creates a Board with a number of columns and rows
@ -238,6 +237,7 @@ namespace QwirkleClassLibrary.Games
{ {
throw new ArgumentException("No player currently playing !"); throw new ArgumentException("No player currently playing !");
} }
return players[GetPlayingPlayerPosition()]; return players[GetPlayingPlayerPosition()];
} }
@ -254,6 +254,7 @@ namespace QwirkleClassLibrary.Games
return i; return i;
} }
} }
return -1; return -1;
} }
@ -312,11 +313,10 @@ namespace QwirkleClassLibrary.Games
startingPlayer = player; startingPlayer = player;
} }
} }
startingPlayer!.IsPlaying = true; startingPlayer!.IsPlaying = true;
OnNextPlayer(new NextPlayerNotifiedEventArgs(players[0])); OnNextPlayer(new NextPlayerNotifiedEventArgs(players[0]));
return startingPlayer.NameTag; return startingPlayer.NameTag;
} }
/// <summary> /// <summary>
@ -354,13 +354,15 @@ namespace QwirkleClassLibrary.Games
OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, "you are swapping, you can't place tile !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, "you are swapping, you can't place tile !"));
return false; return false;
} }
if (!TileInbag(player, tile)) if (!TileInbag(player, tile))
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, "you can't play")); OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, "you can't play"));
return false; return false;
} }
if (!IsMoveCorrect(tile, x, y, board!)) return false;
if (board!.AddTileInCell(x, y, tile)) if (!IsMoveCorrect(tile, x, y, board)) return false;
if (board.AddTileInCell(x, y, tile))
{ {
AddCellUsed(board.GetCell(x, y)); AddCellUsed(board.GetCell(x, y));
return player.RemoveTileToPlayer(tile); return player.RemoveTileToPlayer(tile);
@ -446,12 +448,12 @@ namespace QwirkleClassLibrary.Games
{ {
players[GetPlayingPlayerPosition()].AddTileToPlayer(t); players[GetPlayingPlayerPosition()].AddTileToPlayer(t);
} }
}
}
/// <summary> /// <summary>
/// Extension of IsMoveCorrect to check beyond the surrounding cells of the cell where the tile is placed /// Extension of IsMoveCorrect to check beyond the surrounding cells of the cell where the tile is placed
/// </summary> /// </summary>
/// <param name="previousTilesFound"></param>
/// <param name="tile"></param> /// <param name="tile"></param>
/// <param name="x"></param> /// <param name="x"></param>
/// <param name="y"></param> /// <param name="y"></param>
@ -459,26 +461,39 @@ namespace QwirkleClassLibrary.Games
/// <param name="dy">used to get the direction on the y axis</param> /// <param name="dy">used to get the direction on the y axis</param>
/// <param name="b"></param> /// <param name="b"></param>
/// <returns>bool</returns> /// <returns>bool</returns>
public bool CheckExtendedSurroundingCells(Tile tile, int x, int y, int dx, int dy, Board b) public bool CheckExtendedSurroundingCells(ref bool previousTilesFound, Tile tile, int x, int y, int dx, int dy,
Board b)
{ {
for (int i = 1; i < 7; i++) for (int i = 1; i < 7; i++)
{ {
var extendedCell = b.GetCell(x + i * dx, y + i * dy); var extendedCell = b.GetCell(x + i * dx, y + i * dy);
if (extendedCell?.Tile == null) if (cellUsed.Count == 0)
{
previousTilesFound = true;
}
if (cellUsed.Contains(extendedCell!))
{
previousTilesFound = true;
}
if (extendedCell?.Tile! == null!)
{ {
break; break;
} }
if (extendedCell.Tile.GetColor != tile.GetColor && extendedCell.Tile.GetShape != tile.GetShape) if (extendedCell.Tile.GetColor != tile.GetColor && extendedCell.Tile.GetShape != tile.GetShape)
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, " : Color / Shape does not match with the surrounding tiles !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(tile,
" : Color / Shape does not match with the surrounding tiles !"));
return false; return false;
} }
if (extendedCell.Tile.GetColor == tile.GetColor && extendedCell.Tile.GetShape == tile.GetShape) if (extendedCell.Tile.GetColor == tile.GetColor && extendedCell.Tile.GetShape == tile.GetShape)
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, " : Tile already placed on the same line / column !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(tile,
" : Tile already placed on the same line / column !"));
return false; return false;
} }
@ -527,6 +542,7 @@ namespace QwirkleClassLibrary.Games
{ {
return x == x1; return x == x1;
} }
if (y1 == y2) if (y1 == y2)
{ {
return y == y1; return y == y1;
@ -536,13 +552,62 @@ namespace QwirkleClassLibrary.Games
} }
/// <summary> /// <summary>
/// Main method to check if the move the player is trying to make is correct /// Check that there isn't any same tile on a said line when a tile is forming a line
/// </summary> /// </summary>
/// <param name="t"></param> /// <param name="t1"></param>
/// <param name="nbTiles"></param>
/// <param name="checkdoubles"></param>
/// <returns></returns>
public static bool CheckTileInCompletedLines(Tile? t1, ref int nbTiles, ref List<Tile> checkdoubles)
{
if (t1! != null!)
{
nbTiles++;
if (checkdoubles.Any(t => t.CompareTo(t1) == 0))
{
return false;
}
checkdoubles.Add(t1);
}
return true;
}
/// <summary>
/// Check if the line is completed with the tile placed
/// </summary>
/// <param name="tile"></param>
/// <param name="x"></param> /// <param name="x"></param>
/// <param name="y"></param> /// <param name="y"></param>
/// <param name="dx"></param>
/// <param name="dy"></param>
/// <param name="b"></param> /// <param name="b"></param>
/// <returns>bool</returns> /// <param name="checkdoubles"></param>
/// <returns></returns>
public static bool CheckWrongCompletedLines(int x, int y, int dx, int dy, Board b, ref List<Tile> checkdoubles)
{
int nbTiles = 1;
for (int i = 1; i < 7; i++)
{
var extendedCell = b.GetCell(x + i * dx, y + i * dy);
var extendedCell2 = b.GetCell(x - i * dx, y - i * dy);
if (extendedCell?.Tile! == null! && extendedCell2?.Tile! == null!)
{
break;
}
if(!CheckTileInCompletedLines(extendedCell?.Tile, ref nbTiles, ref checkdoubles)) return false;
if(!CheckTileInCompletedLines(extendedCell2?.Tile, ref nbTiles, ref checkdoubles)) return false;
}
return nbTiles <= 6;
}
public bool IsMoveCorrect(Tile t, int x, int y, Board b) public bool IsMoveCorrect(Tile t, int x, int y, Board b)
{ {
if (!b.HasOccupiedCase()) if (!b.HasOccupiedCase())
@ -550,9 +615,10 @@ namespace QwirkleClassLibrary.Games
return true; return true;
} }
if (b.GetCell(x, y)!.Tile != null) if (b.GetCell(x, y)!.Tile! != null!)
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " : Cell already used !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " : Cell already used !"));
return false;
} }
var surroundingCells = new List<Cell?> var surroundingCells = new List<Cell?>
@ -562,50 +628,68 @@ namespace QwirkleClassLibrary.Games
b.GetCell(x, y + 1), b.GetCell(x, y + 1),
b.GetCell(x, y - 1) b.GetCell(x, y - 1)
}; };
if (surroundingCells.All(cell => cell?.Tile! == null!))
{
OnPlaceTile(new PlaceTileNotifiedEventArgs(t,
" : You can't place a tile that isn't adjacent to another one !"));
return false;
}
return IsTilePlacementCorrect(t, x, y, b, surroundingCells);
}
public bool IsTilePlacementCorrect(Tile t, int x, int y, Board b, List<Cell?> surroundingCells)
{
bool previousTilesFound = false;
var checkDoubles = new List<Tile>();
foreach (var cell in surroundingCells) foreach (var cell in surroundingCells)
{ {
if (cell?.Tile == null) if (cell?.Tile! == null!)
{ {
continue; continue;
} }
if (cell.Tile.GetColor != t.GetColor && cell.Tile.GetShape != t.GetShape) if (cell.Tile.GetColor != t.GetColor && cell.Tile.GetShape != t.GetShape)
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " : Colors / Shapes do not match with the surrounding tiles !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(t,
" : Colors / Shapes do not match with the surrounding tiles !"));
return false; return false;
} }
if (cell.Tile.GetColor == t.GetColor && cell.Tile.GetShape == t.GetShape) if (cell.Tile.GetColor == t.GetColor && cell.Tile.GetShape == t.GetShape)
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " is already placed on the same line / column !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " is already placed on the same line / column !"));
return false; return false;
} }
var dx = cell.GetX - x; var dx = cell.GetX - x;
var dy = cell.GetY - y; var dy = cell.GetY - y;
if (!CheckExtendedSurroundingCells(t, x, y, dx, dy, b)) if (!CheckExtendedSurroundingCells(ref previousTilesFound, t, x, y, dx, dy, b))
{ {
return false; return false;
} }
}
if (CheckWrongCompletedLines(x, y, dx, dy, b, ref checkDoubles)) continue;
if (!CheckTilesInLine(cellUsed, b, x, y)) OnPlaceTile(new PlaceTileNotifiedEventArgs(t,
{ " : You can't complete this line ! (More than 6 tiles / same tiles on the line)"));
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, "isn't on the same line as the ones previously placed !"));
return false; return false;
} }
if (surroundingCells.All(cell => cell?.Tile == null)) if (!CheckTilesInLine(cellUsed, b, x, y))
{ {
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " : You can't place a tile that isn't adjacent to another one !")); OnPlaceTile(new PlaceTileNotifiedEventArgs(t,
"isn't on the same line as the ones previously placed !"));
return false; return false;
} }
return true; if (previousTilesFound) return true;
OnPlaceTile(new PlaceTileNotifiedEventArgs(t,
" : You must place your tile next / on the same line as the ones previously placed !"));
return false;
} }
@ -654,7 +738,8 @@ namespace QwirkleClassLibrary.Games
cellsX = cellsY = -1; cellsX = cellsY = -1;
} }
score += cellsPlayed.Sum(cell => CalculateAdjacentScore(cell, b, cellsPlayed, cellsX, cellsY, ref nbCellsInLine)); score += cellsPlayed.Sum(cell =>
CalculateAdjacentScore(cell, b, cellsPlayed, cellsX, cellsY, ref nbCellsInLine));
if (nbCellsInLine == 6) if (nbCellsInLine == 6)
{ {
@ -663,7 +748,6 @@ namespace QwirkleClassLibrary.Games
if (!scoreBoard.TryAdd(player.NameTag, score)) if (!scoreBoard.TryAdd(player.NameTag, score))
{ {
scoreBoard.TryGetValue(player.NameTag, out int scoreold); scoreBoard.TryGetValue(player.NameTag, out int scoreold);
SetScoreBoard(player.NameTag, score + scoreold); SetScoreBoard(player.NameTag, score + scoreold);
} }
@ -681,7 +765,8 @@ namespace QwirkleClassLibrary.Games
/// <param name="cellsY"></param> /// <param name="cellsY"></param>
/// <param name="nbCellsInLine"></param> /// <param name="nbCellsInLine"></param>
/// <returns>int</returns> /// <returns>int</returns>
public int CalculateAdjacentScore(Cell cell, Board b, ReadOnlyCollection<Cell> cellsPlayed, int cellsX, int cellsY, ref int nbCellsInLine) public int CalculateAdjacentScore(Cell cell, Board b, ReadOnlyCollection<Cell> cellsPlayed, int cellsX,
int cellsY, ref int nbCellsInLine)
{ {
int score = 0; int score = 0;
@ -697,7 +782,8 @@ namespace QwirkleClassLibrary.Games
foreach (var adjacentCell in surroundingCells) foreach (var adjacentCell in surroundingCells)
{ {
if (adjacentCell?.Tile == null || cellsPlayed.Contains(adjacentCell) || checkedSurroundingCells.Contains(adjacentCell)) if (adjacentCell?.Tile! == null! || cellsPlayed.Contains(adjacentCell) ||
checkedSurroundingCells.Contains(adjacentCell))
{ {
continue; continue;
} }
@ -705,7 +791,8 @@ namespace QwirkleClassLibrary.Games
int dx = adjacentCell.GetX - cell.GetX; int dx = adjacentCell.GetX - cell.GetX;
int dy = adjacentCell.GetY - cell.GetY; int dy = adjacentCell.GetY - cell.GetY;
score += CalculateLineScore(cellsPlayed, cell, new Tuple<int, int>(dx, dy), b, new Tuple<int, int>(cellsX, cellsY), ref nbCellsInLine); score += CalculateLineScore(cellsPlayed, cell, new Tuple<int, int>(dx, dy), b,
new Tuple<int, int>(cellsX, cellsY), ref nbCellsInLine);
checkedSurroundingCells.Add(adjacentCell); checkedSurroundingCells.Add(adjacentCell);
} }
@ -723,7 +810,8 @@ namespace QwirkleClassLibrary.Games
/// <param name="orientation"></param> /// <param name="orientation"></param>
/// <param name="nbCellsInLine"></param> /// <param name="nbCellsInLine"></param>
/// <returns>int</returns> /// <returns>int</returns>
public int CalculateLineScore(ReadOnlyCollection<Cell> cellsPlayed, Cell cell, Tuple<int, int> direction, Board b, Tuple<int, int> orientation, ref int nbCellsInLine) public int CalculateLineScore(ReadOnlyCollection<Cell> cellsPlayed, Cell cell, Tuple<int, int> direction,
Board b, Tuple<int, int> orientation, ref int nbCellsInLine)
{ {
int score = 0; int score = 0;
@ -731,7 +819,7 @@ namespace QwirkleClassLibrary.Games
{ {
var extendedCell = b.GetCell(cell.GetX + i * direction.Item1, cell.GetY + i * direction.Item2); var extendedCell = b.GetCell(cell.GetX + i * direction.Item1, cell.GetY + i * direction.Item2);
if (extendedCell?.Tile == null || cellsPlayed.Contains(extendedCell)) if (extendedCell?.Tile! == null! || cellsPlayed.Contains(extendedCell))
{ {
break; break;
} }
@ -744,7 +832,8 @@ namespace QwirkleClassLibrary.Games
score++; score++;
} }
if (direction.Item1 == 0 && orientation.Item1 == -1 && orientation.Item2 != -1 || direction.Item2 == 0 && orientation.Item2 == -1 && orientation.Item1 != -1) if (direction.Item1 == 0 && orientation.Item1 == -1 && orientation.Item2 != -1 ||
direction.Item2 == 0 && orientation.Item2 == -1 && orientation.Item1 != -1)
{ {
score += 1; score += 1;
} }
@ -770,7 +859,6 @@ namespace QwirkleClassLibrary.Games
playerTilesBagPos.Add(i); playerTilesBagPos.Add(i);
} }
} }
} }
return playerTilesBagPos; return playerTilesBagPos;
@ -787,7 +875,7 @@ namespace QwirkleClassLibrary.Games
{ {
foreach (var t in players[t1].Tiles) foreach (var t in players[t1].Tiles)
{ {
for (int b = 0; b < board!.ReadCells.Count; b++) for (int b = 0; b < board.ReadCells.Count; b++)
{ {
int x = board.ReadCells[b].GetX; int x = board.ReadCells[b].GetX;
int y = board.ReadCells[b].GetY; int y = board.ReadCells[b].GetY;
@ -813,7 +901,8 @@ namespace QwirkleClassLibrary.Games
{ {
List<int> playerTilesBagPos = CheckTilesBag(); List<int> playerTilesBagPos = CheckTilesBag();
if (playerTilesBagPos.Count != 0 && !CheckPlacementPossibilities(playerTilesBagPos) || bag!.TilesBag!.Count == 0 && players[GetPlayingPlayerPosition()].Tiles.Count == 0) if (playerTilesBagPos.Count != 0 && !CheckPlacementPossibilities(playerTilesBagPos) ||
bag!.TilesBag!.Count == 0 && players[GetPlayingPlayerPosition()].Tiles.Count == 0)
{ {
OnEndOfGame(new EndOfGameNotifiedEventArgs(player)); OnEndOfGame(new EndOfGameNotifiedEventArgs(player));
GameRunning = false; GameRunning = false;
@ -838,7 +927,6 @@ namespace QwirkleClassLibrary.Games
public void SetScoreBoard(string name, int score) public void SetScoreBoard(string name, int score)
{ {
if (!scoreBoard.TryAdd(name, score)) if (!scoreBoard.TryAdd(name, score))
{ {
scoreBoard[name] = score; scoreBoard[name] = score;
@ -849,6 +937,7 @@ namespace QwirkleClassLibrary.Games
{ {
observableScoreBoard.Add(item); observableScoreBoard.Add(item);
} }
OnPropertyChanged(nameof(ObservableScoreBoard)); OnPropertyChanged(nameof(ObservableScoreBoard));
} }
} }

@ -17,7 +17,7 @@ namespace QwirkleClassLibrary.Games
bool IsMoveCorrect(Tile t, int x, int y, Board b); bool IsMoveCorrect(Tile t, int x, int y, Board b);
bool CheckExtendedSurroundingCells(Tile tile, int x, int y, int dx, int dy, Board b); bool CheckExtendedSurroundingCells(ref bool previousTilesFound, Tile tile, int x, int y, int dx, int dy, Board b);
bool CheckTilesInLine(List<Cell> cells, Board b, int x, int y); bool CheckTilesInLine(List<Cell> cells, Board b, int x, int y);

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace QwirkleClassLibrary.Tiles namespace QwirkleClassLibrary.Tiles
{ {
[DataContract] [DataContract]
public class Tile public class Tile : IComparable
{ {
[DataMember] [DataMember]
private readonly Shape shape; private readonly Shape shape;
@ -41,19 +41,13 @@ namespace QwirkleClassLibrary.Tiles
/// A getter for the shape of the Tile. /// A getter for the shape of the Tile.
/// </summary> /// </summary>
/// <returns>The shape attribute of the Tile.</returns> /// <returns>The shape attribute of the Tile.</returns>
public Shape GetShape public Shape GetShape => shape;
{
get { return shape; }
}
/// <summary> /// <summary>
/// A getter for the color of the Tile. /// A getter for the color of the Tile.
/// </summary> /// </summary>
/// <returns>The color attribute of the Tile.</returns> /// <returns>The color attribute of the Tile.</returns>
public Color GetColor public Color GetColor => color;
{
get { return color; }
}
/// <summary> /// <summary>
/// This method is used to override the ToString() method. It is simply a tool to facilitate the development. /// This method is used to override the ToString() method. It is simply a tool to facilitate the development.
@ -63,5 +57,69 @@ namespace QwirkleClassLibrary.Tiles
{ {
return color.ToString() + " " + shape.ToString(); return color.ToString() + " " + shape.ToString();
} }
public int CompareTo(object? obj)
{
if (obj == null)
{
return 1;
}
var otherTile = obj as Tile;
if (color == otherTile!.color)
{
return shape.CompareTo(otherTile.shape);
}
return color.CompareTo(otherTile.color);
}
public override bool Equals(object? obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
var otherTile = obj as Tile;
return color == otherTile!.color && shape == otherTile.shape;
}
public override int GetHashCode()
{
return HashCode.Combine(color, shape);
}
public static bool operator ==(Tile tile1, Tile tile2)
{
return EqualityComparer<Tile>.Default.Equals(tile1, tile2);
}
public static bool operator !=(Tile tile1, Tile tile2)
{
return !(tile1 == tile2);
}
public static bool operator <(Tile tile1, Tile tile2)
{
return tile1.CompareTo(tile2) < 0;
}
public static bool operator >(Tile tile1, Tile tile2)
{
return tile1.CompareTo(tile2) > 0;
}
public static bool operator <=(Tile tile1, Tile tile2)
{
return tile1.CompareTo(tile2) <= 0;
}
public static bool operator >=(Tile tile1, Tile tile2)
{
return tile1.CompareTo(tile2) >= 0;
}
} }
} }

@ -287,25 +287,6 @@ public class TestGame
Assert.False(game.PlaceTile(game.GetPlayingPlayer(), game.PlayerList[game.GetPlayingPlayerPosition()].Tiles[0], -5, 1)); Assert.False(game.PlaceTile(game.GetPlayingPlayer(), game.PlayerList[game.GetPlayingPlayerPosition()].Tiles[0], -5, 1));
} }
// [Fact]
// public void Test_DrawTile()
// {
// Game game = new Game();
// game.AddPlayerInGame("Test1");
// game.AddPlayerInGame(playerstest);
//
// game.StartGame();
// game.SetNextPlayer();
//
// Assert.True(game.DrawTiles(game.GetPlayingPlayer()));
//
// /*test*/
// TileBag bag = new TileBag(0);
// Assert.False(game.DrawTiles(game.GetPlayingPlayer()));
// return;
//
// }
[Theory] [Theory]
[InlineData(true)] [InlineData(true)]
[InlineData(false)] [InlineData(false)]
@ -342,6 +323,48 @@ public class TestGame
Assert.Equal(p, events.Player); Assert.Equal(p, events.Player);
} }
[Fact]
public void Test_IsTilePlacementCorrect()
{
var game = new Game();
var board = new Board(17, 14);
var tile = new Tile(Shape.Club, Color.Red);
board.AddTileInCell(0, 1, new Tile(Shape.Club, Color.Blue));
var x = 1;
var y = 1;
var surroundingCells = new List<Cell?>
{
board.GetCell(x + 1, y),
board.GetCell(x - 1, y),
board.GetCell(x, y + 1),
board.GetCell(x, y - 1)
};
bool result = game.IsTilePlacementCorrect(tile, x, y, board, surroundingCells);
Assert.True(result);
}
[Fact]
public void Test_IsMoveCorrect()
{
var game = new Game();
var board = new Board(17, 14);
var tile = new Tile(Shape.Club, Color.Red);
board.AddTileInCell(0, 1, new Tile(Shape.Club, Color.Blue));
var x = 2;
var y = 1;
bool result = game.IsMoveCorrect(tile, x, y, board);
Assert.False(result);
}
[Fact] [Fact]
public void Test_IsMoveCorrectSixLine() public void Test_IsMoveCorrectSixLine()
{ {
@ -381,6 +404,41 @@ public class TestGame
} }
[Fact]
public void Test_CheckTileInCompletedLines()
{
int nbTiles = 0;
var checkdoubles = new List<Tile>()
{
new(Shape.Club, Color.Blue),
new(Shape.Club, Color.Red),
new(Shape.Club, Color.Green),
};
var t1 = new Tile(Shape.Club, Color.Green);
Assert.False(Game.CheckTileInCompletedLines(t1, ref nbTiles, ref checkdoubles));
}
[Fact]
public void Test_CheckWrongCompletedLines()
{
var board = new Board(17, 14);
var checkDoubles = new List<Tile>();
int x = 4, y = 1, dx = 1, dy = 0;
board.AddTileInCell(1, 1, new Tile(Shape.Club, Color.Red));
board.AddTileInCell(2, 1, new Tile(Shape.Square, Color.Red));
board.AddTileInCell(3, 1, new Tile(Shape.Star, Color.Red));
board.AddTileInCell(5, 1, new Tile(Shape.Round, Color.Red));
board.AddTileInCell(6, 1, new Tile(Shape.Shuriken, Color.Red));
board.AddTileInCell(7, 1, new Tile(Shape.Rhombus, Color.Red));
bool result = Game.CheckWrongCompletedLines(x, y, dx, dy, board, ref checkDoubles);
Assert.False(result);
}
[Theory] [Theory]
[InlineData(3, 1, 4, 1, 5, 1, 5)] [InlineData(3, 1, 4, 1, 5, 1, 5)]
[InlineData(2, 2, 3, 2, 4, 2, 5)] [InlineData(2, 2, 3, 2, 4, 2, 5)]

Loading…
Cancel
Save