|
|
|
@ -21,9 +21,9 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
public ReadOnlyDictionary<Player, int> ScoreBoard => scoreBoard.AsReadOnly();
|
|
|
|
|
private readonly Dictionary<Player, int> scoreBoard = new();
|
|
|
|
|
|
|
|
|
|
private TileBag bag;
|
|
|
|
|
private TileBag? bag = null;
|
|
|
|
|
public bool GameRunning { get; private set; }
|
|
|
|
|
private Board board;
|
|
|
|
|
private Board? board = null;
|
|
|
|
|
|
|
|
|
|
public ReadOnlyCollection<Player> PlayerList => players.AsReadOnly();
|
|
|
|
|
private readonly List<Player> players = new();
|
|
|
|
@ -50,15 +50,6 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
|
|
|
|
|
protected virtual void OnEndOfGame(EndOfGameNotifiedEventArgs args)
|
|
|
|
|
=> EndOfGameNotified?.Invoke(this, args);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a game with a board and a tile bag
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Game()
|
|
|
|
|
{
|
|
|
|
|
bag = CreateTileBag(3);
|
|
|
|
|
board = CreateBoard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds a player in the game if the game is not running, if the name is correct, if the game is not full and if the name is not already taken.
|
|
|
|
@ -119,7 +110,13 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
/// Returns the board of the game
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>Board</returns>
|
|
|
|
|
public Board GetBoard() { return board; }
|
|
|
|
|
public Board? GetBoard() { return board; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the tile bag of the game
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public TileBag? GetTileBag() { return bag; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a board with a number of columns and rows
|
|
|
|
@ -127,7 +124,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
/// <returns>Board</returns>
|
|
|
|
|
public Board CreateBoard()
|
|
|
|
|
{
|
|
|
|
|
board = new Board(15, 12);
|
|
|
|
|
board = new Board(7, 7);
|
|
|
|
|
return board;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -148,6 +145,8 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
public void StartGame()
|
|
|
|
|
{
|
|
|
|
|
if (players.Count < 2 || players.Count >= 5) return;
|
|
|
|
|
board = CreateBoard();
|
|
|
|
|
bag = CreateTileBag(3);
|
|
|
|
|
GameRunning = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -177,7 +176,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
{
|
|
|
|
|
if (GetPlayingPlayerPosition() == -1)
|
|
|
|
|
{
|
|
|
|
|
throw new ArgumentException("No player play.");
|
|
|
|
|
throw new ArgumentException("No player currently playing !");
|
|
|
|
|
}
|
|
|
|
|
return players[GetPlayingPlayerPosition()];
|
|
|
|
|
}
|
|
|
|
@ -217,10 +216,13 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < 6; j++)
|
|
|
|
|
{
|
|
|
|
|
int val = RandomNumberGenerator.GetInt32(0, bag.TilesBag.Count);
|
|
|
|
|
if (bag != null)
|
|
|
|
|
{
|
|
|
|
|
int val = RandomNumberGenerator.GetInt32(0, bag.TilesBag.Count);
|
|
|
|
|
|
|
|
|
|
p.AddTileToPlayer(bag.TilesBag[val]);
|
|
|
|
|
bag.RemoveTileInBag(bag.TilesBag[val]);
|
|
|
|
|
p.AddTileToPlayer(bag.TilesBag[val]);
|
|
|
|
|
bag.RemoveTileInBag(bag.TilesBag[val]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -238,7 +240,8 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
OnNextPlayer(new NextPlayerNotifiedEventArgs(players[0]));
|
|
|
|
|
return players[0].NameTag;
|
|
|
|
|
}
|
|
|
|
|
throw new ArgumentException("Game is not running");
|
|
|
|
|
|
|
|
|
|
throw new ArgumentException("Game is not running");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -271,8 +274,8 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
/// <returns>bool</returns>
|
|
|
|
|
public bool PlaceTile(Player player, Tile tile, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
|
OnPlaceTile(new PlaceTileNotifiedEventArgs(tile, "was correctly placed !"));
|
|
|
|
|
AddCellUsed(board.GetCell(x, y));
|
|
|
|
@ -293,7 +296,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
{
|
|
|
|
|
while (player.Tiles.Count < 6)
|
|
|
|
|
{
|
|
|
|
|
if (bag.TilesBag.Count == 0)
|
|
|
|
|
if (bag!.TilesBag.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -335,7 +338,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
|
|
|
|
|
foreach (var t in tilesToSwap)
|
|
|
|
|
{
|
|
|
|
|
bag.AddTileInBag(t);
|
|
|
|
|
bag!.AddTileInBag(t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
@ -486,7 +489,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!surroundingCells.Any(cell => cell?.GetTile != null))
|
|
|
|
|
if (surroundingCells.All(cell => cell?.GetTile == null))
|
|
|
|
|
{
|
|
|
|
|
OnPlaceTile(new PlaceTileNotifiedEventArgs(t, " : You can't place a tile that isn't adjacent to another one !"));
|
|
|
|
|
return false;
|
|
|
|
@ -520,18 +523,25 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
int cellsX = cellsPlayed[0].GetX;
|
|
|
|
|
int cellsY = cellsPlayed[0].GetY;
|
|
|
|
|
|
|
|
|
|
foreach (var cell in cellsPlayed)
|
|
|
|
|
if (cellsPlayed.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
if (cellsX != cell.GetX && cellsX != -1)
|
|
|
|
|
{
|
|
|
|
|
cellsX = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (cellsY != cell.GetY && cellsY != -1)
|
|
|
|
|
foreach (var cell in cellsPlayed)
|
|
|
|
|
{
|
|
|
|
|
cellsY = -1;
|
|
|
|
|
if (cellsX != cell.GetX && cellsX != -1)
|
|
|
|
|
{
|
|
|
|
|
cellsX = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (cellsY != cell.GetY && cellsY != -1)
|
|
|
|
|
{
|
|
|
|
|
cellsY = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
cellsX = cellsY = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
score += cellsPlayed.Sum(cell => CalculateAdjacentScore(cell, b, cellsPlayed, cellsX, cellsY));
|
|
|
|
|
|
|
|
|
@ -605,7 +615,12 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dx != 0 && cellsY != -1 && nbCellsPlayed + i == 6 || dy != 0 && cellsX != -1 && nbCellsPlayed + i == 6)
|
|
|
|
|
if (dx == 0 && cellsY != -1 && i + 1 == 6 || dy == 0 && cellsX != -1 && i + 1 == 6)
|
|
|
|
|
{
|
|
|
|
|
score += 6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dx != 0 && cellsY != -1 && i + nbCellsPlayed == 6 || dy != 0 && cellsX != -1 && i + nbCellsPlayed == 6)
|
|
|
|
|
{
|
|
|
|
|
score += 6;
|
|
|
|
|
}
|
|
|
|
@ -630,7 +645,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
{
|
|
|
|
|
List<int> playerTilesBagPos = [];
|
|
|
|
|
|
|
|
|
|
if (bag.TilesBag.Count == 0)
|
|
|
|
|
if (bag!.TilesBag.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < players.Count; i++)
|
|
|
|
|
{
|
|
|
|
@ -650,13 +665,13 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="playerTilesBagPos"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public bool CheckBoardTile(List<int> playerTilesBagPos)
|
|
|
|
|
public bool CheckPlacementPossibilities(List<int> playerTilesBagPos)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < playerTilesBagPos.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < players[playerTilesBagPos[i]].Tiles.Count; j++)
|
|
|
|
|
{
|
|
|
|
|
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 y = board.ReadCells[b].GetY;
|
|
|
|
@ -682,7 +697,7 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
{
|
|
|
|
|
List<int> playerTilesBagPos = CheckTilesBag();
|
|
|
|
|
|
|
|
|
|
if (playerTilesBagPos.Count != 0 && !CheckBoardTile(playerTilesBagPos))
|
|
|
|
|
if (playerTilesBagPos.Count != 0 && !CheckPlacementPossibilities(playerTilesBagPos))
|
|
|
|
|
{
|
|
|
|
|
OnEndOfGame(new EndOfGameNotifiedEventArgs(player));
|
|
|
|
|
GameRunning = false;
|
|
|
|
@ -692,5 +707,15 @@ namespace QwirkleClassLibrary.Games
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearGame()
|
|
|
|
|
{
|
|
|
|
|
players.Clear();
|
|
|
|
|
scoreBoard.Clear();
|
|
|
|
|
cellUsed.Clear();
|
|
|
|
|
bag = null;
|
|
|
|
|
board = CreateBoard();
|
|
|
|
|
GameRunning = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|