/// <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>
        /// <param name="tileGridPosition">The tiles position within the tileGrid.</param>
        /// <returns>True, if values matching (one tileValueGrid value can be null), false if not.</returns>
        private bool CheckValueGridAtTileGridPosition(TriominoTile tile, Point tileGridPosition)
        {
            List<int?> valuesToCheck = this.GetValueGridValuesFromNameGridPositions(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;
        }
        //public bool TryAddTile(TriominoTile tile, string otherName, TileFace? otherFace)
        public bool TryAddTile(string tileName, string otherName, TileFace? tileFace, TileFace? otherFace)
        {
            // TODO: CanPlacetileOnGameBoard an diesen Funktionskopf anpassen und hier aufrufen.

            TriominoTile.EnsureName(tileName);

            TriominoTile tile = null;
            if (this.NumbTilesOnBoard == 0)
            {
                tile = new TriominoTile(tileName, TileOrientation.Straight);
                return this.AddTile(tile, new Point(23, 23));
            }

            if (tileFace == null || otherFace == null || otherName == null || otherName == string.Empty)
            {
                throw new ArgumentException("Values for Parameter 'otherName' and 'otherFace' can't be null, if it isn't the first turn.");
            }
                      
            Point otherTileGridCoordinates = this.GetTileCoordsByName(otherName);
            TileOrientation tileOrientationOnGameBoard = this.GetTileOrienationFromOtherTileOrientationAndFaces(this.tileGrid[otherTileGridCoordinates.Y, otherTileGridCoordinates.X].Orientation, otherFace.Value, tileFace.Value);

            tile = new TriominoTile(tileName, tileOrientationOnGameBoard);

            Point possibleNewGridCoordinates = this.GetTileGridPositionFromOtherTilePositionAndFace(otherTileGridCoordinates, otherFace.Value);
            

            return this.AddTile(tile, possibleNewGridCoordinates);
        }
        private bool AddTile(TriominoTile tile, Point tileGridPosition)
        {
            if (this.tileGrid[tileGridPosition.Y, tileGridPosition.X] != null)
            {
                throw new ArgumentException($"Cannot add tile {tile.Name} at position(x,y): ({tileGridPosition.X}, {tileGridPosition.Y}). Place is taken by tile: '{this.tileGrid[tileGridPosition.Y, tileGridPosition.X].Name}'");
            }

            if (!this.CheckValueGridAtTileGridPosition(tile, tileGridPosition))
            {
                return false;
            }

            this.tileGrid[tileGridPosition.Y, tileGridPosition.X] = tile;
            this.AddValuesToValueGrid(tile.GetArrayName(), tileGridPosition, tile.Orientation.ToArrayTileOrientation());

            return true;
        }
        /// <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(TriominoTile tile, string otherName, TileFace? otherFace)
        {
            // if it's the first tile it can always be placed.
            if (this.NumbTilesOnBoard == 0)
            {
                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);

            return this.CheckValueGridAtTileGridPosition(tile, possibleNewGridCoordinates);
        }