Ejemplo n.º 1
0
 private Func <int, int, int> CreateValueGetter(_2048MoveDirection move)
 {
     return(this.getters[(int)move]);
 }
Ejemplo n.º 2
0
 private Action <int, int, int> CreateValueSetter(_2048MoveDirection move)
 {
     return(this.setters[(int)move]);
 }
Ejemplo n.º 3
0
        public bool TryMove(_2048MoveDirection move, bool autoAddTile = true)
        {
            if (this.emptyTilesCount.HasValue)
            {
                throw new InvalidOperationException("Tile wasn't added after previous move!");
            }
            bool moved = false;
            var  get   = this.CreateValueGetter(move);
            var  set   = this.CreateValueSetter(move);

            for (int row = 0; row < size; ++row)
            {
                int  destination = -1;
                int  destinationValue;
                int  source      = 0;
                int  sourceValue = -1;
                bool sourceMoved = source < size;
                do
                {
                    destinationValue = get(row, ++destination);
                    // move source to non-empty tile.
                    while ((sourceMoved = ++source < size) &&
                           (sourceValue = get(row, source)) == 0
                           )
                    {
                        ;
                    }
                    if (sourceMoved)
                    {
                        bool repeat;
                        do
                        {
                            repeat = false;
                            // move tile into empty space
                            if (destinationValue == 0)
                            {
                                destinationValue = sourceValue;
                                set(row, destination, destinationValue);
                                sourceValue = 0;
                                set(row, source, sourceValue);
                                moved = true;

                                /*
                                 *      even moved tile can be subsequently
                                 *      merged so we need to move the source
                                 *      enumerator to the next tile and
                                 *      repeat with the same destination
                                 *      to try to merge them.
                                 */
                                while ((sourceMoved = ++source < size) &&
                                       (sourceValue = get(row, source)) == 0
                                       )
                                {
                                    ;
                                }
                                repeat = true;
                            }
                            // merge tiles with the same value
                            else if (destinationValue == sourceValue)
                            {
                                this._score += destinationValue *= 2;
                                set(row, destination, destinationValue);
                                sourceValue = 0;
                                set(row, source, sourceValue);
                                moved = true;
                            }

                            /*
                             * if there is a gap between source and
                             * destination we can try to move destination
                             * closer to source and repeat.
                             */
                            else if (destination < source - 1)
                            {
                                destinationValue = get(row, ++destination);
                                repeat           = true;
                            }
                        } while (repeat && sourceMoved);
                    }
                } while (sourceMoved);
            }
            if (moved)
            {
                this.__matrix = null;
                this.SetEmptyTiles();
                return(!autoAddTile || this.TryAutoAddTile());
            }
            else
            {
                return(false);
            }
        }