/* * Copyright 2015 Daniel Dittmar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package dan.dit.whatsthat.solution; import android.support.annotation.NonNull; import android.text.TextUtils; import java.util.LinkedList; import java.util.List; import dan.dit.whatsthat.preferences.Tongue; import dan.dit.whatsthat.util.compaction.Compactable; import dan.dit.whatsthat.util.compaction.CompactedDataCorruptException; import dan.dit.whatsthat.util.compaction.Compacter; /** * Created by daniel on 24.03.15. */ public class Solution implements Compactable { public static final int SOLVED_NOTHING = 0; public static final int SOLVED_COMPLETELY = 100; private Tongue mTongue; private List<String> mSolutionWords = new LinkedList<>(); public Solution(Compacter compacter) throws CompactedDataCorruptException { unloadData(compacter); } /** * Constructs a solution of a language with an empty word. This will not * be an expected solution for an image, don't use it there! * @param tongue The tongue of the solution. */ Solution(Tongue tongue) { if (tongue == null) { throw new IllegalArgumentException("Null tongue given."); } mTongue = tongue; addWord(""); } public Solution(Tongue tongue, String word) { if (tongue == null || TextUtils.isEmpty(word)) { throw new IllegalArgumentException("Null tongue or word given."); } mTongue = tongue; addWord(word); } public Solution(Tongue tongue, String word1, String word2) { if (tongue == null || (TextUtils.isEmpty(word1) && TextUtils.isEmpty(word2))) { throw new IllegalArgumentException("Null tongue or word given."); } mTongue = tongue; if (!TextUtils.isEmpty(word1)) { addWord(word1); } if (!TextUtils.isEmpty(word2)) { addWord(word2); } } public Solution(Tongue tongue, List<String> words) { mTongue = tongue; for (String word : words) { if (!TextUtils.isEmpty(word)) { addWord(word); } } if (tongue == null || mSolutionWords.isEmpty()) { throw new IllegalArgumentException("Null tongue or no valid words given."); } } private Solution(Tongue tongue, String[] words) { mTongue = tongue; for (String word : words) { if (!TextUtils.isEmpty(word)) { addWord(word); } } if (tongue == null || mSolutionWords.isEmpty()) { throw new IllegalArgumentException("Null tongue or no valid words given."); } } public static Solution makeSolution(Tongue tongue, String[] words) { if (tongue == null || words == null || words.length == 0) { return null; } boolean foundNotEmptyWord = false; for (String word : words) { if (!TextUtils.isEmpty(word)) { foundNotEmptyWord = true; } } if (foundNotEmptyWord) { return new Solution(tongue, words); } return null; } private void addWord(@NonNull String word) { mSolutionWords.add(word.toUpperCase()); } @Override public String toString() { return mTongue.getShortcut() + ": " + mSolutionWords; } @Override public String compact() { Compacter cmp = new Compacter(); cmp.appendData(mTongue.getShortcut()); for (String solution : mSolutionWords) { cmp.appendData(solution); } return cmp.compact(); } @Override public void unloadData(Compacter compactedData) throws CompactedDataCorruptException { if (compactedData.getSize() <= 1) { throw new CompactedDataCorruptException("Too little data to unload solution."); } mTongue = Tongue.getByShortcut(compactedData.getData(0)); for (int i=1;i<compactedData.getSize();i++) { mSolutionWords.add(compactedData.getData(i)); } } public Tongue getTongue() { return mTongue; } public int estimateSolvedValue(String userWord) { // the empty word will never count as solved if (TextUtils.isEmpty(userWord)) { return SOLVED_NOTHING; } int maxSolved = SOLVED_NOTHING; for (String word : mSolutionWords) { int length = Math.min(word.length(), userWord.length()); int solvedLettersCount = 0; for (int i = 0; i < length; i++) { if (word.charAt(i) == userWord.charAt(i)) { solvedLettersCount++; } } int currSolved = length == 0 ? SOLVED_NOTHING : (int) (SOLVED_COMPLETELY * (solvedLettersCount / ((double) word.length()))); if (currSolved > maxSolved) { maxSolved = currSolved; } } return Math.min(Math.max(SOLVED_NOTHING, maxSolved), SOLVED_COMPLETELY); } /** * Returns the list of solution words. Do not change the list as it is backed by this solution. * @return The list of words, length >= 1. */ public List<String> getWords() { return mSolutionWords; } }