package com.github.donkirkby.vograbulary.ultraghost;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
public class Match implements Serializable {
private static final long serialVersionUID = 3147466969252314807L;
private boolean isHyperghost;
private transient UltraghostRandom random = new UltraghostRandom();
private int matchScore;
private Student[] students;
private int studentIndex = Integer.MIN_VALUE;
private Puzzle puzzle;
private int minimumWordLength = 4;
public Match(int matchScore, Student... students) {
this.matchScore = matchScore;
this.students = students;
}
/** Get the score required to win the match. */
public int getMatchScore() {
return matchScore;
}
private void checkStudentOrder() {
if (studentIndex < 0) {
for (int i = 0; i < students.length - 1; i++) {
int source = random.chooseStartingStudent(students.length - i);
Student student = students[i + source];
students[i + source] = students[i];
students[i] = student;
}
studentIndex = students.length - 1;
}
}
/**
* Replace the default implementation of the random generator. Useful for
* testing.
*/
public void setRandom(UltraghostRandom random) {
this.random = random;
}
public Puzzle createPuzzle(WordList wordList) {
checkStudentOrder();
studentIndex = (studentIndex + 1) % students.length;
String letters;
String previousWord;
if (puzzle == null ||
! isHyperghost ||
puzzle.getResult() == WordResult.SKIP_NOT_IMPROVED ||
puzzle.getResult() == WordResult.IMPROVED_SKIP_NOT_A_WORD ||
puzzle.getResult() == WordResult.IMPROVED_SKIP_TOO_SOON ||
puzzle.getResult() == WordResult.IMPROVED_SKIP_TOO_SHORT) {
letters = random.generatePuzzle();
previousWord = null;
}
else {
letters = puzzle.getLetters();
WordResult result = puzzle.getResult();
switch (result) {
case LONGER:
case LATER:
case WORD_FOUND:
previousWord = puzzle.getResponse();
break;
default:
previousWord = puzzle.getSolution();
break;
}
}
boolean isPaused = puzzle != null && puzzle.isPaused();
puzzle = new Puzzle(
letters,
students[studentIndex],
wordList);
puzzle.setPreviousWord(previousWord);
puzzle.setMinimumWordLength(minimumWordLength);
puzzle.setPaused(isPaused);
return puzzle;
}
public String getSummary() {
checkStudentOrder();
StringBuilder writer = new StringBuilder();
for (Student student : students) {
writer.append(student).append('\n');
}
return writer.toString();
}
public Puzzle getPuzzle() {
return puzzle;
}
public void setPuzzle(Puzzle puzzle) {
this.puzzle = puzzle;
}
public Student getWinner() {
Student bestStudent = null;
int bestScore = Integer.MIN_VALUE;
int scoreCount = Integer.MIN_VALUE;
boolean isTie = false;
for (Student student : students) {
if (bestStudent == null) {
scoreCount = student.getScoreCount();
}
else if (student.getScoreCount() != scoreCount) {
return null;
}
if (student.getScore() > bestScore) {
bestStudent = student;
bestScore = student.getScore();
}
else {
isTie = student.getScore() == bestScore;
}
}
return !isTie && bestScore >= matchScore ? bestStudent : null;
}
/**
* Set the minimum length for solutions in this match. Default is 4.
* @param minimumWordLength
*/
public void setMinimumWordLength(int minimumWordLength) {
this.minimumWordLength = minimumWordLength;
}
/**
* Set to true if new puzzles should use the same letters as previous
* puzzles until no player can think of any worse solutions.
*/
public void setHyperghost(boolean isHyperghost) {
this.isHyperghost = isHyperghost;
}
public boolean isHyperghost() {
return isHyperghost;
}
public List<Student> getStudents() {
return Arrays.asList(students);
}
}