Ejemplo n.º 1
0
        private GridState MoveToNewState(
            GridState state,
            int xDelta,
            int yDelta,
            int keysBitmask)
        {
            int newX = state.Location.X + xDelta;
            int newY = state.Location.Y + yDelta;

            var p = new Point(newX, newY);

            if (!grid.ContainsKey(p))
            {
                return(null);
            }

            char c = grid[p];

            if (c == '#')
            {
                // hit a wall
                return(null);
            }
            if (c >= 'A' && c <= 'Z')
            {
                // this is a door
                // key for this door is the associated lowercase letter
                char key    = (char)(c + 32);
                int  keybit = CharToBit(key);

                // if the key for this door is not in all the keys
                if ((keysBitmask & keybit) == 0)
                {
                    // this key is not in the keys we are looking for
                    // at all, so for part 2 it's in a different
                    // quadrant of the grid
                    return(new GridState
                    {
                        Location = new Point(newX, newY),
                        OriginalLocation = state,
                        BitMask = state.BitMask,
                        Steps = state.Steps + 1
                    });
                }

                // if the key is in the state's found keys - found the key
                // for this door already so we can move there
                if ((state.BitMask & keybit) != 0)
                {
                    return(new GridState
                    {
                        Location = new Point(newX, newY),
                        BitMask = state.BitMask,
                        OriginalLocation = state,
                        Steps = state.Steps + 1
                    });
                }

                // can't go here
                return(null);
            }

            if (c >= 'a' && c <= 'z')
            {
                // we are at another key, pick it up
                // and move to this location
                return(new GridState
                {
                    Location = new Point(newX, newY),
                    Steps = state.Steps + 1,
                    OriginalLocation = state,
                    BitMask = state.BitMask | CharToBit(c)
                });
            }

            // otherwise this is an empty location,
            // move there but don't update keys or anything
            return(new GridState
            {
                Location = new Point(newX, newY),
                BitMask = state.BitMask,
                OriginalLocation = state,
                Steps = state.Steps + 1
            });
        }