It's method extraction time!
But before that, I have to comment on your Player enum:
stris a bad name,namewould be better.- Speaking of name, all enums have a
name()method by default. You don't need your strstrvariable,return name();instead. - Speaking of
return name();, that's exactly what the default implementation of toStringtoString()already does for enums. Absolutely no need to override it.
And therefore, we've reduced your PlayerPlayer enum to:
public enum Player {
X, O;
}
Ain't it lovely with enums? :)
Now, back to your getWinner() method:
You have a whole bunch of duplicated code there indeed. It would be handy if you could get a Collection of some kind (or an array), add some elements to it and check: Is there a winner given by these Player values?
This is just one version of doing it, it's not the optimal one but it should get you started. The idea here is that weThis code will add a bunch of PlayerPlayer objects to a list and then we check if those Player objects match to find if there's a winner or not.
List<Player> players = new ArrayList<>();
for (int x = 0; x < fields.length; x++) {
for (int y = 0; y < fields[x].length; y++) {
players.add(fields[x][y]);
}
Player winner = findWinner(players);
if (winner != null)
return winner;
}
Player findWinner(List<Player> players) {
Player win = players.get(0);
for (Player pl : players) {
// it's fine that we loop through index 0 again,
// even though we've already processed it.
// It's a fast operation and it won't change the result
if (pl != win)
return null;
}
return pl;
}
Please note that there are even more improvements possible for this getWinnerthe getWinner method, I don't want to reveal all my secrets for now though ;) ThisAnd also, this is just one way of cleaningdoing it up, which will reduce your code duplication a bit at least. There are other possible approaches here as well.