Othello.java (5525B) download
1package nl.isygameclient.models.games;
2
3import nl.isygameclient.models.Game;
4import nl.isygameclient.models.Player;
5import nl.isygameclient.models.PlayerManager;
6import nl.isygameclient.models.board.HistoryBoard;
7import nl.isygameclient.util.Vector2D;
8
9import java.util.*;
10import java.util.stream.Collectors;
11
12public class Othello extends Game {
13
14 public Othello(PlayerManager playerManager) {
15 super(playerManager, new HistoryBoard<>(8, 8) {
16 });
17 initializeBoard();
18 }
19
20 @Override
21 public void restart() {
22 playerManager.restart();
23 board = new HistoryBoard<>(8, 8) {
24 };
25 initializeBoard();
26 }
27
28 private void initializeBoard() {
29 var players = playerManager.getPlayers();
30 board.set(players.get(0), new Vector2D<>(3, 3));
31 board.set(players.get(0), new Vector2D<>(4, 4));
32 board.set(players.get(1), new Vector2D<>(3, 4));
33 board.set(players.get(1), new Vector2D<>(4, 3));
34
35 }
36
37 @Override
38 public boolean isDraw() {
39 var scores = getScores();
40 return scores.values().stream().distinct().count() == 1;
41 }
42
43 @Override
44 public boolean isGameOver() {
45 for (Player player : playerManager.getPlayers()) {
46 if (getValidMoves(player).size() > 0){
47 return false;
48 }
49 }
50 return true;
51 }
52
53 @Override
54 public boolean isWinner(Player player) {
55 Player winner = null;
56 int score = 0;
57 for (Map.Entry<Player, Integer> entry : getScores().entrySet()) {
58 if (entry.getValue() > score) {
59 winner = entry.getKey();
60 score = entry.getValue();
61 }
62 }
63 return Objects.equals(player, winner);
64 }
65
66
67 @Override
68 public boolean move(Player player, Vector2D<Integer, Integer> pos) {
69 if (!isMoveValid(player, pos)) {
70 return false;
71 }
72
73 var flippable = checkNeighbours(player, pos);
74
75 Map<Vector2D<Integer, Integer>, Player> changes = flippable.stream().collect(Collectors.toMap(e -> e, e -> player));
76 board.add(player, changes);
77 playerManager.nextPlayer();
78 return true;
79 }
80
81
82 @Override
83 public boolean isMoveValid(Player player, Vector2D<Integer, Integer> pos) {
84 if (board.get(pos) != null)
85 return false;
86
87 var flippable = checkNeighbours(player, pos);
88 return !flippable.isEmpty();
89 }
90
91
92 private List<Vector2D<Integer, Integer>> rangeContains(Player player, Vector2D<Integer, Integer> pos, Vector2D<Integer, Integer> dir) {
93 List<Vector2D<Integer, Integer>> flippable = new ArrayList<>();
94 int x = pos.getX();
95 int y = pos.getY();
96 while (x >= 0 && x < board.getWidth() && y >= 0 && y < board.getHeight()) {
97 var newPos = new Vector2D<>(x, y);
98 flippable.add(newPos);
99 if (Objects.equals(board.get(newPos), player)) {
100 return flippable;
101 }
102 x += dir.getX();
103 y += dir.getY();
104 }
105 return null;
106 }
107
108
109 private Set<Vector2D<Integer, Integer>> checkNeighbours(Player player, Vector2D<Integer, Integer> pos) {
110 Set<Vector2D<Integer, Integer>> flippable = new HashSet<>();
111 for (int dx = -1; dx <= 1; dx++) {
112 if ((pos.getX() + dx) < 0 || (pos.getX() + dx) >= board.getWidth())
113 continue;
114
115 for (int dy = -1; dy <= 1; dy++) {
116 if ((pos.getY() + dy) < 0 || (pos.getY() + dy) >= board.getHeight())
117 continue;
118
119 if (dx == 0 && dy == 0)
120 continue;
121
122 var checkPos = board.get(new Vector2D<>(pos.getX() + dx, pos.getY() + dy));
123 if (checkPos != null && checkPos != player) {
124 List<Vector2D<Integer, Integer>> flip = rangeContains(player, pos, new Vector2D<>(dx, dy));
125 if (flip != null)
126 flippable.addAll(flip);
127 }
128 }
129 }
130 return flippable;
131 }
132
133 @Override
134 public List<Vector2D<Integer, Integer>> getValidMoves(Player player) {
135 List<Vector2D<Integer, Integer>> valid = new ArrayList<>();
136 for (int y = 0; y < board.getHeight(); y++) {
137 for (int x = 0; x < board.getWidth(); x++) {
138 if (isMoveValid(player, new Vector2D<>(x, y))) {
139 valid.add(new Vector2D<>(x, y));
140 }
141 }
142 }
143 return valid;
144 }
145
146 @Override
147 public List<Player> getWinners() {
148 ArrayList<Player> winners = new ArrayList<>();
149 for (Player player : playerManager.getPlayers()) {
150 if (isWinner(player)) {
151 winners.add(player);
152 }
153 }
154 return winners;
155 }
156
157 @Override
158 public int getPlayerScore(Player player) {
159 int score = 0;
160 for (int y = 0; y < board.getHeight(); y++) {
161 for (int x = 0; x < board.getWidth(); x++) {
162 if (Objects.equals(player, board.get(new Vector2D<>(x, y)))) {
163 score += 1;
164 }
165 }
166 }
167 return score;
168 }
169
170 private HashMap<Player, Integer> getScores() {
171 HashMap<Player, Integer> scores = new HashMap<>();
172 for (Player player : playerManager.getPlayers()) {
173 int score = getPlayerScore(player);
174 scores.put(player, score);
175 }
176 return scores;
177 }
178}