public MahjongState Play(MahjongTile tileOne, MahjongTile tileTwo)
        {
            if (!_started)
            {
                _started = true;
            }
            if (tileOne == tileTwo)
            {
                return(MahjongState.InvalidMove);
            }
            if (tileOne.Type != tileTwo.Type)
            {
                return(MahjongState.DifferentType);
            }
            if (!CanMove(tileOne) || !CanMove(tileTwo))
            {
                return(MahjongState.NotMove);
            }
            Remove(tileOne);
            Remove(tileTwo);
            if (_tiles.Count == 0)
            {
                return(MahjongState.Won);
            }
            MahjongState result = MahjongState.ValidMove;

            if (!NextMovePossible())
            {
                result |= MahjongState.NoMoves;
            }
            return(result);
        }
        public bool CanMove(MahjongTile tile)
        {
            bool up      = CanMoveUp(tile);
            bool leftUp  = up && CanMoveLeft(tile);
            bool rightUp = up && CanMoveRight(tile);

            return(leftUp || rightUp);
        }
        public async void Tapped(ItemsControl display, ContentPresenter container)
        {
            if (!_gameOver)
            {
                MahjongTile tile = (MahjongTile)display.ItemFromContainer(container);
                if (_selected == null || _selected == tile)
                {
                    Board.SetNone();
                    if (_selected == tile)
                    {
                        tile.Select = MahjongSelect.None;
                        _selected   = null;
                    }
                    else
                    {
                        tile.Select = MahjongSelect.Selected;
                        _selected   = tile;
                    }
                }
                else
                {
                    Board.State = Board.Play(_selected, tile);
                    switch (Board.State)
                    {
                    case MahjongState.DifferentType:
                        tile.Select = MahjongSelect.Incorrect;
                        break;

                    case MahjongState.NotMove:
                        tile.Select = MahjongSelect.Incorrect;
                        break;

                    case MahjongState.ValidMove:
                        tile.Select = MahjongSelect.None;
                        break;

                    case MahjongState.InvalidMove:
                        tile.Select = MahjongSelect.Incorrect;
                        break;

                    case MahjongState.NoMoves:
                        Board.Shuffle();
                        break;

                    case MahjongState.Won:
                        await ShowDialogAsync("You Won, Game Over!");

                        _gameOver = true;
                        break;
                    }
                    _selected = null;
                }
            }
            else
            {
                await ShowDialogAsync("You Won, Game Over!");
            }
        }
        public static MahjongPair GetPair(List <MahjongTile> tiles)
        {
            if (tiles.Count < 2)
            {
                throw new InvalidOperationException();
            }
            int         index   = random.Next() % tiles.Count;
            MahjongTile tileOne = tiles[index];

            tiles.RemoveAt(index);
            index = random.Next() % tiles.Count;
            MahjongTile tileTwo = tiles[index];

            tiles.RemoveAt(index);
            return(new MahjongPair(tileOne, tileTwo));
        }
 private void Structure(MahjongBoard board)
 {
     for (int index = 0; index < Indexes; index++)
     {
         for (int column = 0; column < Columns; column++)
         {
             for (int row = 0; row < Rows; row++)
             {
                 MahjongTile tile = AddTile(null, column, row, index);
                 if (tile != null)
                 {
                     board.Tiles.Add(tile);
                 }
             }
         }
     }
 }
        private bool CanMove(MahjongTile tile, int column, int row, int index)
        {
            MahjongPosition[] positions = GetPositions(tile.Position.Column, tile.Position.Row);
            int i = tile.Position.Index + index;

            for (int p = 0; p < positions.Length; p++)
            {
                int         c     = positions[p].Column + column;
                int         r     = positions[p].Row + row;
                MahjongTile found = GetTile(c, r, i);
                if (found != null && tile != found)
                {
                    return(false);
                }
            }
            return(true);
        }
        private List <MahjongTile> ExtractRemovableTiles(MahjongBoard board)
        {
            List <MahjongTile> removable = new List <MahjongTile>();

            MahjongTile[] tiles = new MahjongTile[board.Tiles.Count];
            board.Tiles.CopyTo(tiles, 0);
            foreach (MahjongTile tile in tiles)
            {
                if (board.CanMove(tile))
                {
                    removable.Add(tile);
                }
            }
            foreach (MahjongTile tile in removable)
            {
                board.Remove(tile);
            }
            return(removable);
        }
 private void Remove(MahjongTile tile) => _tiles.Remove(tile);
 private void Add(MahjongTile tile) => _tiles.Add(tile);
 private bool CanMoveLeft(MahjongTile tile) => CanMove(tile, -1, 0, 0);
 private bool CanMoveRight(MahjongTile tile) => CanMove(tile, 1, 0, 0);
 private bool CanMoveUp(MahjongTile tile) => CanMove(tile, 0, 0, 1);
 public MahjongPair(MahjongTile tileOne, MahjongTile tileTwo)
 {
     _tileOne = tileOne;
     _tileTwo = tileTwo;
 }