George Santayana remembers the past and is trying desperately to repeat it. He assigns a scores to each past round to signify how similar that round (and the rounds before it) was to the last round. If the round had the same majority as the last round, it gets a score of the amount of total players plus the amount of players that gave the same answer in both rounds, George then looks at the rounds before these rounds and adds the score for those two to the total score. He does this until he encounters two rounds where the majority was not the same. After having found the round with the highest score, he picks the majority of the round after that.
Since I'm very new to Java and relatively new to programming in general, I took Angelo Neuschitzer's Backpacker class as a template. I didn't bother to change the way he responded to the first round (though I default to good in stead of evil) and the way he stores the history in an array of strings. I also reused his didGoodWin function, though I rewrote that to not require the amount of players as an argument. Other than that, the code and logic is all mine. Thanks Angelo, hope you don't mind.
package Humans;
public class GeorgeSantayana extends Human {
private String[] roundVotes;
@Override
public final String takeSides(String history) {
if (history == null || history.equals("")) //these last 4 lines copied from BackPacker(http://codegolf.stackexchange.com/questions/33137/good-versus-evil/34294#34294) by Angelo NeuSchitzer.
return "good";
roundVotes = history.split(","); //this line copied from BackPacker(http://codegolf.stackexchange.com/questions/33137/good-versus-evil/34294#34294) by Angelo NeuSchitzer.
int bestScore = -1;
boolean pickGood = true;
for (int round = 0; round < roundVotes.length - 1; round++) {
int currentScore = calculateSimilarity(round, roundVotes.length - 1);
if (currentScore > bestScore) {
bestScore = currentScore;
pickGood = didGoodWin(roundVotes[round + 1]);
}
}
if (pickGood)
return "good";
else
return "evil";
}
private int getSameVotes(int round1, int round2){
int votes = 0;
for(int i = 0; i < roundVotes[round1].length() && i < roundVotes[round1].length(); i++){
if (roundVotes[round1].charAt(i) == roundVotes[round2].charAt(i)) {
votes++;
}
}
return votes;
}
private int calculateSimilarity(int round1, int round2){
int players = roundVotes[0].length();
int score = 0;
if (didGoodWin(roundVotes[round1]) == didGoodWin(roundVotes[round2])) {
score += players + getSameVotes(round1, round2);
score += calculateSimilarity(round1 - 1, round2 - 1);
}
return score;
}
private boolean didGoodWin(String round) { //this function in part copied from BackPacker(http://codegolf.stackexchange.com/questions/33137/good-versus-evil/34294#34294) by Angelo NeuSchitzer.
int good = 0;
for (char next : round.toCharArray())
good += next == '1' ? 1 : 0;
return (good * 2) > round.length();
}
}