// Return a new state with the given move on the given state with new reference private static StringState GetStateWithMove(StringState state, MoveString move) { // Deep clone previous state StringState resultState = TypeConverter.DeepCloneState(state); // Remove the token from the previous field (if already placed) resultState = RemoveTokenFromGameState(resultState, move.Token); // If the field already has a token if (resultState.ContainsKey(move.Field)) { Stack <string> tokenStack = new Stack <string>(resultState[move.Field]); tokenStack.Push(move.Token); // Place the allowed Token above the old Token resultState.Remove(move.Field); resultState.Add(move.Field, tokenStack); } else { // Otherwise add the Field with a new Stack with the allowed Token Stack <string> tokenStack = new Stack <string>(); tokenStack.Push(move.Token); resultState.Add(move.Field, tokenStack); } return(resultState); }
// Returns a new Gamestate without the given Token with new reference // Removes the Token from the given GameState if it is on the Gamestate // otherwise the given GameState will be returned with new reference // (only has to check the peeks because the covered Tokens are ignored by GetAvailableTokensForGameState) private static StringState RemoveTokenFromGameState(StringState state, string token) { // Deep clone the given state without reference StringState resultState = TypeConverter.DeepCloneState(state); // Iterate through all available fields of the state foreach (var field in state) { // Check if the token is on the peek of the field if (field.Value.Peek() == token) { // When the field has more than one token if (field.Value.Count > 1) { // Remove the highest token from the field resultState[field.Key].Pop(); } // When the token is the only token on the field else { // Remove the field from the state resultState.Remove(field.Key); } } } return(resultState); }