// TODO: again, NPuzzleState return type instead of int[] public override NPuzzleState <int[]> Result(NPuzzleState <int[]> s, int action) { int[] state = s.State; int[] newState = new int[state.Length]; int emptyIndex; state.CopyTo(newState, 0); emptyIndex = GetEmptyIndex(state); if (emptyIndex == -1) { NPuzzleUtils.MissingEmptyElementException ex = new NPuzzleUtils.MissingEmptyElementException(state.Length.ToString()); throw ex; } if (AcceptableAction(state, emptyIndex, action)) { if (action == 1) { NPuzzleUtils.Swap(newState, emptyIndex, emptyIndex + 1); } else if (action == -1) { NPuzzleUtils.Swap(newState, emptyIndex, emptyIndex - 1); } else if (action == -2) { NPuzzleUtils.Swap(newState, emptyIndex, emptyIndex + dimension); } else { NPuzzleUtils.Swap(newState, emptyIndex, emptyIndex - dimension); } } else { String msg = String.Format("You entered an invalid action: {0} for the state {1}", action, state.ToString()); NPuzzleUtils.ResultAcceptableActionException ex = new NPuzzleUtils.ResultAcceptableActionException(msg); throw ex; } return(new NPuzzleState <int[]>(newState)); }
/*! * Get all the actions possible in a givens state. * First, we must locate the index of the 'empty' * space in the 'board' (array), which in this case * is equal to 'size'. * * We can determine the possible actions by the direction the * 'empty' space can be moved: up, down, left or right * We'll use the following conventions: * * up : 2 * down: -2 * left: -1 * right: 1 * * */ // TODO: use State instead of int[] public override List <int> Actions(NPuzzleState <int[]> s) { int[] state = s.State; int emptyIndex = GetEmptyIndex(state); if (emptyIndex == -1) { NPuzzleUtils.MissingEmptyElementException ex = new NPuzzleUtils.MissingEmptyElementException(state.Length.ToString()); throw ex; } List <int> actions = new List <int>(); //! if emptyIndex is in the rightmost column, //! then adding one to it will be divisible by dimension if ((emptyIndex + 1) % dimension != 0) { actions.Add(1); } //! if emptyIndex is in the leftmost column, //! it can be divided by dimension //! Anything not in the leftmost column can be moved left, or - 1 if (emptyIndex % dimension != 0) { actions.Add(-1); } //! if emptyIndex is greater than or equal to dim, it //! must not be in the first row, and hence //! can be moved up, or 2 if (emptyIndex >= dimension) { actions.Add(2); } if (emptyIndex < size - dimension) { actions.Add(-2); } return(actions); }