private IEnumerable <TriominoTile> GetTileNeighbors(TriominoTile tile) { // No Checks for Arraybounds, cause this should create an Exception (so, the bounds can be enlargened then). List <TriominoTile> neighbors = new List <TriominoTile>(); Point tileGridPosition = this.GetTileCoordsByName(tile.Name); // Add neighbors from both tile sides (left and right, according to orientation) neighbors.Add(this.tileGrid[tileGridPosition.Y, tileGridPosition.X - 1]); neighbors.Add(this.tileGrid[tileGridPosition.Y, tileGridPosition.X + 1]); if (tile.Orientation.ToArrayTileOrientation() == ArrayTileOrientation.BottomUp) { // Bottom neighbors.Add(this.tileGrid[tileGridPosition.Y + 1, tileGridPosition.X]); } if (tile.Orientation.ToArrayTileOrientation() == ArrayTileOrientation.TopDown) { // Top neighbors.Add(this.tileGrid[tileGridPosition.Y - 1, tileGridPosition.X]); } neighbors = neighbors.Where(n => n != null).ToList(); return(neighbors); }
/// <summary> /// Checks the values for a tile at a specific tileGridPosition. /// If one value doesn't match the value within the tiles name false is returned, /// while one null-value of the tileValueGrid values is allowed. /// </summary> /// <param name="tile">The tile whose values should be checked.</param> /// <returns>True, if values matching (one tileValueGrid value can be null), false if not.</returns> private bool CheckValueGridAtTileGridPosition(TriominoTile tile) { List <int?> valuesToCheck = this.GetValueGridValuesFromNameGridPositions(tile.TileGridPosition, tile.Orientation.ToArrayTileOrientation()); // if more than two values are null, this triomino tile // isn't added adjacent to another tile (except for the first tile). if (this.NumbTilesOnBoard > 0 && valuesToCheck.Where(v => !v.HasValue).Count() > 1) { return(false); } string[] nameParts = tile.GetArrayName().Split('-'); for (int i = 0; i < valuesToCheck.Count; i++) { int intValue = int.Parse(nameParts[i]); if (valuesToCheck[i].HasValue && valuesToCheck[i] != intValue) { return(false); } } return(true); }
/// <summary> /// Returns a tile from the tileGrid starting from a given face of a specific tile (and it's position on the tileGrid). /// </summary> /// <param name="tile">Tile to start from.</param> /// <returns></returns> internal TriominoTile GetAdjacentTileAtSpecificFace(TriominoTile tile, TileFace tileFace) { ArrayTileOrientation orientation = tile.Orientation.ToArrayTileOrientation(); if (orientation == ArrayTileOrientation.BottomUp && tileFace == TileFace.Bottom) { return(this.tileGrid[tile.TileGridPosition.Y + 1, tile.TileGridPosition.X]); } if (orientation == ArrayTileOrientation.TopDown && tileFace == TileFace.Bottom) { return(this.tileGrid[tile.TileGridPosition.Y - 1, tile.TileGridPosition.X]); } if (orientation == ArrayTileOrientation.BottomUp && tileFace == TileFace.Right || orientation == ArrayTileOrientation.TopDown && tileFace == TileFace.Left) { return(this.tileGrid[tile.TileGridPosition.Y, tile.TileGridPosition.X + 1]); } if (orientation == ArrayTileOrientation.BottomUp && tileFace == TileFace.Left || orientation == ArrayTileOrientation.TopDown && tileFace == TileFace.Right) { return(this.tileGrid[tile.TileGridPosition.Y, tile.TileGridPosition.X - 1]); } return(null); }
/// <summary> /// Sets a tile on the grid with coordinates from tile object. /// </summary> /// <param name="tile">The tile to be set on the grid including the coordinates.</param> private void SetTileOnGrid(TriominoTile tile) { if (tile.TileGridPosition.Y < 0 || tile.TileGridPosition.X < 0) { throw new IndexOutOfRangeException("Only positive coordinates are allowed"); } this.tileGrid[tile.TileGridPosition.Y, tile.TileGridPosition.X] = tile; }
/// <summary> /// Places a Tile on the TileGrid and TileValuesGrid /// </summary> /// <param name="tile"></param> /// <returns></returns> private bool AddTile(TriominoTile tile) { if (this.GetTileFromGrid(tile.TileGridPosition) != null) { throw new ArgumentException($"Cannot add tile {tile.Name} at position(x,y): ({tile.TileGridPosition.X}, {tile.TileGridPosition.Y}). Place is taken by tile: '{this.GetTileFromGrid(tile.TileGridPosition).Name}'"); } this.SetTileOnGrid(tile); this.AddValuesToValueGrid(tile.GetArrayName(), tile.TileGridPosition, tile.Orientation.ToArrayTileOrientation()); this.NumbTilesOnBoard++; return(true); }
private bool CheckMatchingAdjacentTiles(TriominoTile newTile) { bool newTileMatchesAdjacentTiles = true; TileFace[] facesToCheck = new TileFace[] { TileFace.Bottom, TileFace.Right, TileFace.Left }; foreach (TileFace faceToCheck in facesToCheck) { TriominoTile adjacenTileAtFace = this.GetAdjacentTileAtSpecificFace(newTile, faceToCheck); if (adjacenTileAtFace != null) { newTileMatchesAdjacentTiles = newTileMatchesAdjacentTiles && this.CheckMatchingAdjacentTileFaces(newTile, adjacenTileAtFace); } else { newTileMatchesAdjacentTiles = newTileMatchesAdjacentTiles && this.CheckBridgeEdgesAtTileFace(newTile, faceToCheck); } } return(newTileMatchesAdjacentTiles); }
/// <summary> /// Checks if a tile can placed on the GameBoard, based on the tiles orientation, /// and another tile next to which the new tile should be placed /// </summary> /// <param name="tile">The tile which should be placed</param> /// <param name="otherName">The name of the other tile.</param> /// <param name="otherFace">The face of the other tile at which the new tile should be placed.</param> /// <returns>True, if the new tile can be placed, false if not.</returns> public bool CanPlaceTileOnGameBoard(string tileName, string otherName, TileFace?tileFace, TileFace?otherFace, out TriominoTile placableTile) { placableTile = null; // if it's the first tile it can always be placed. if (this.NumbTilesOnBoard == 0) { placableTile = new TriominoTile(tileName, TileOrientation.Straight, new Point(this.maxGameBoardSize / 2, this.maxGameBoardSize / 2)); return(true); } // otherFace and otherName can only be null if it's the first tile if (otherFace == null || otherName == null || otherName == string.Empty) { return(false); } Point otherTileGridCoordinates = this.GetTileCoordsByName(otherName); Point possibleNewGridCoordinates = this.GetTileGridPositionFromOtherTilePositionAndFace(otherTileGridCoordinates, otherFace.Value); if (possibleNewGridCoordinates.Y == -1 || possibleNewGridCoordinates.X == -1) { return(false); } TileOrientation tileOrientation = GameBoard.GetTileOrienationFromOtherTileOrientationAndFaces(this.GetTileFromGrid(otherTileGridCoordinates).Orientation, otherFace.Value, tileFace.Value); TriominoTile tile = new TriominoTile(tileName, tileOrientation, possibleNewGridCoordinates); // If Tile values can be placed it will be returned if (this.CheckValueGridAtTileGridPosition(tile)) { placableTile = tile; return(true); } return(false); }
private bool CheckBridgeEdgesAtTileFace(TriominoTile newTile, TileFace tileFace) { throw new NotImplementedException(); }
private bool CheckMatchingAdjacentTileFaces(TriominoTile thisTile, TriominoTile otherTile) { // adjacentTiles must have different Orientations. if (thisTile.Orientation.ToArrayTileOrientation() == otherTile.Orientation.ToArrayTileOrientation()) { return(false); } // other tile is right of this tile if (thisTile.TileGridPosition.Y == otherTile.TileGridPosition.Y && thisTile.TileGridPosition.X + 1 == otherTile.TileGridPosition.X) { switch (thisTile.Orientation.ToArrayTileOrientation()) { case ArrayTileOrientation.BottomUp: return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Right, TileFace.Right)); case ArrayTileOrientation.TopDown: return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Left, TileFace.Left)); default: throw new ArgumentException("Unknown TileOrientation."); } } // other tile is left of this tile if (thisTile.TileGridPosition.Y == otherTile.TileGridPosition.Y && thisTile.TileGridPosition.X - 1 == otherTile.TileGridPosition.X) { switch (thisTile.Orientation.ToArrayTileOrientation()) { case ArrayTileOrientation.BottomUp: return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Left, TileFace.Left)); case ArrayTileOrientation.TopDown: return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Right, TileFace.Right)); default: throw new ArgumentException("Unknown TileOrientation."); } } // other tile is top of this tile if (thisTile.TileGridPosition.Y - 1 == otherTile.TileGridPosition.Y && thisTile.TileGridPosition.X == otherTile.TileGridPosition.X) { if (thisTile.Orientation.ToArrayTileOrientation() == ArrayTileOrientation.TopDown) { return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Bottom, TileFace.Bottom)); } else { throw new ArgumentException("Tiles got now adjacent faces."); } } // other tile is bottom of this tile if (thisTile.TileGridPosition.Y + 1 == otherTile.TileGridPosition.Y && thisTile.TileGridPosition.X == otherTile.TileGridPosition.X) { if (thisTile.Orientation.ToArrayTileOrientation() == ArrayTileOrientation.BottomUp) { return(thisTile.Name.CheckIfFacesMatches(otherTile.Name, TileFace.Bottom, TileFace.Bottom)); } else { throw new ArgumentException("Tiles got now adjacent faces."); } } return(false); }