package com.github.donkirkby.vograbulary.ultraghost;
import java.util.Iterator;
import com.github.donkirkby.vograbulary.VograbularyPreferences;
public class ComputerStudent extends Student {
private static final long serialVersionUID = 2114858077675128651L;
private int searchBatchSize = 1;
private int maxSearchBatchCount = Integer.MAX_VALUE;
private int vocabularySize;
private transient int searchBatchCount;
private transient int searchedWordsCount;
private transient Puzzle currentPuzzle;
private transient Puzzle searchPuzzle; // used to search for the best solution.
private transient Iterator<String> itr;
public ComputerStudent(VograbularyPreferences preferences) {
super("Computer");
vocabularySize = preferences.getComputerStudentVocabularySize();
}
public void setSearchBatchSize(int searchBatchSize) {
this.searchBatchSize = searchBatchSize;
}
public int getSearchBatchSize() {
return searchBatchSize;
}
public void setMaxSearchBatchCount(int maxSearchBatchCount) {
this.maxSearchBatchCount = maxSearchBatchCount;
searchBatchSize = vocabularySize / maxSearchBatchCount;
}
@Override
public void startSolving(Puzzle puzzle) {
currentPuzzle = puzzle;
searchPuzzle = new Puzzle(puzzle.getLetters(), this);
searchPuzzle.setMinimumWordLength(puzzle.getMinimumWordLength());
searchPuzzle.setPreviousWord(puzzle.getPreviousWord());
searchPuzzle.setSolution(Puzzle.NO_SOLUTION);
searchBatchCount = 0;
searchedWordsCount = 0;
if (currentPuzzle.getOwner() == this) {
getListener().showThinking();
}
itr = getWordList().iterator();
}
@Override
public boolean runSearchBatch() {
checkCurrentPuzzle();
searchBatchCount++;
int wordCount = Math.min(
searchBatchSize,
vocabularySize
- searchedWordsCount);
for (int i = 0; i < wordCount && itr.hasNext(); i++) {
searchPuzzle.setResponse(itr.next());
if (searchPuzzle.getResult().isImproved()) {
searchPuzzle.setSolution(searchPuzzle.getResponse());
}
}
searchedWordsCount += wordCount;
if (searchBatchCount >= maxSearchBatchCount
|| ! itr.hasNext()
|| searchedWordsCount >= vocabularySize) {
if (currentPuzzle.getOwner() == this) {
currentPuzzle.setSolution(searchPuzzle.getSolution());
getListener().askForResponse();
return true;
}
}
return ! itr.hasNext();
}
private void checkCurrentPuzzle() {
Match match = getMatch();
if (match != null && match.getPuzzle() != currentPuzzle) {
startSolving(match.getPuzzle());
}
}
@Override
public void prepareResponse() {
checkCurrentPuzzle();
if (currentPuzzle == null) {
throw new IllegalStateException(
"Called prepareResponse() before startSolving().");
}
String challenge = searchPuzzle.getSolution();
currentPuzzle.setResponse(challenge);
if ( ! currentPuzzle.getResult().isImproved()) {
currentPuzzle.setResponse(Puzzle.NO_SOLUTION);
}
}
public Puzzle getCurrentPuzzle() {
return currentPuzzle;
}
}