Skip to content

Commit cc96ce2

Browse files
committed
server side bugfixes, add pass button
1 parent 255cb6f commit cc96ce2

File tree

11 files changed

+205
-34
lines changed

11 files changed

+205
-34
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ pack:
1010
lint:
1111
cd src/main/client && npm run lint
1212

13+
test:
14+
./gradlew test
15+
1316
run:
1417
./gradlew bootRun
1518

src/main/client/src/Play.jsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const Play = () => {
3737
let black = useGameStore(state => state.black)
3838
let white = useGameStore(state => state.white)
3939
let board = useGameStore(state => state.gameState.board)
40-
let currentUser = useGameStore(state => state.gameState.currentUser)
40+
let currentPlayer = useGameStore(state => state.gameState.currentPlayer)
4141
let initialized = useRef()
4242
let opponent = auth.name === black.name ? white : black
4343
useEffect(() => {
@@ -59,6 +59,15 @@ export const Play = () => {
5959
sub1.unsubscribe
6060
}
6161
}, [setGameState, initialized, stompClient, auth, gameId])
62+
let onPass = useCallback(() => {
63+
stompClient.publish({
64+
destination: "/app/game/move",
65+
body: JSON.stringify({
66+
id: gameId,
67+
pass: true,
68+
}),
69+
})
70+
}, [stompClient, gameId])
6271
let onClick = useCallback((x, y) => {
6372
stompClient.publish({
6473
destination: "/app/game/move",
@@ -89,7 +98,7 @@ export const Play = () => {
8998
board.map((row, y) => (
9099
row.map((check, x) => (
91100
<Tile
92-
disabled={currentUser !== auth.name}
101+
disabled={currentPlayer !== auth.name}
93102
key={y + "_" + x}
94103
onClick={() => onClick(x, y)}
95104
check={check} />
@@ -99,12 +108,22 @@ export const Play = () => {
99108
</div>
100109
</div>
101110
<div className="fixed right-12 ml-4">
111+
<div>
112+
<button
113+
onClick={onPass}
114+
type="button"
115+
className="bg-slate-700 hover:bg-slate-600 text-white px-2 py-1 rounded-lg">
116+
Pass
117+
</button>
118+
</div>
119+
<div className="mt-2">
102120
{
103-
currentUser === auth.name ?
121+
currentPlayer === auth.name ?
104122
"Jetzt bin ich dran" :
105123
(opponent.name + " ist dran...")
106124
}
107125
</div>
126+
</div>
108127
</div>
109128
)
110129
}

src/main/client/src/store.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const useGameStore = create((set, get) => ({
3838
name: "",
3939
},
4040
gameState: {
41-
currentUser: undefined,
41+
currentPlayer: undefined,
4242
},
4343
setGameState: (game, auth) => {
4444
set(produce(state => {
@@ -50,7 +50,7 @@ export const useGameStore = create((set, get) => ({
5050
state.white = game.white
5151
}
5252
state.gameState.board = game.board
53-
state.gameState.currentUser = game.currentUser
53+
state.gameState.currentPlayer = game.currentPlayer
5454
let symbol = game.black.name === auth.name? BLACK : WHITE
5555
if (oldState.symbol !== symbol) {
5656
state.symbol = symbol

src/main/java/com/bernd/LobbyController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public void matchAction(MatchRequest message, Principal principal) {
4949
operations.convertAndSend("/topic/lobby/users",
5050
new UserList(lobbyUsers.users()));
5151
String gameId = RandomString.get();
52-
Game game = games.put(new Game(gameId, user, lookingForMatch, user.name(), new int[][]{
52+
Game game = games.put(new Game(gameId, user, lookingForMatch, false, user.name(), false, new int[][]{
5353
new int[9],
5454
new int[9],
5555
new int[9],

src/main/java/com/bernd/game/Board.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@ private static StoneGroup getStoneGroup(
1919
BoardUpdate update = BoardUpdate.builder(dim);
2020
int liberties = 0;
2121
PointSet pointsChecked = PointSet.create(dim);
22+
pointsChecked.add(xx, yy);
2223
PointQueue pointsToCheck = PointQueue.create(dim);
2324
pointsToCheck.offer(xx, yy);
2425
while (!pointsToCheck.isEmpty()) {
2526
int ptId = pointsToCheck.poll();
2627
int y = ptId / dim;
2728
int x = ptId % dim;
28-
pointsChecked.add(x, y);
2929
update.add(x, y, 0);
3030
if (y > 0) {
3131
int bpt = board[y - 1][x];
3232
if (bpt == 0) {
3333
liberties++;
3434
} else if (bpt == color && !pointsChecked.has(x, y - 1)) {
35+
pointsChecked.add(x, y - 1);
3536
pointsToCheck.offer(x, y - 1);
3637
}
3738
}
@@ -40,6 +41,7 @@ private static StoneGroup getStoneGroup(
4041
if (bpt == 0) {
4142
liberties++;
4243
} else if (bpt == color && !pointsChecked.has(x, y + 1)) {
44+
pointsChecked.add(x, y + 1);
4345
pointsToCheck.offer(x, y + 1);
4446
}
4547
}
@@ -48,6 +50,7 @@ private static StoneGroup getStoneGroup(
4850
if (bpt == 0) {
4951
liberties++;
5052
} else if (bpt == color && !pointsChecked.has(x - 1, y)) {
53+
pointsChecked.add(x - 1, y);
5154
pointsToCheck.offer(x - 1, y);
5255
}
5356
}
@@ -56,6 +59,7 @@ private static StoneGroup getStoneGroup(
5659
if (bpt == 0) {
5760
liberties++;
5861
} else if (bpt == color && !pointsChecked.has(x + 1, y)) {
62+
pointsChecked.add(x + 1, y);
5963
pointsToCheck.offer(x + 1, y);
6064
}
6165
}

src/main/java/com/bernd/game/Count.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,37 @@ private static int getImpliedColor(
1818
}
1919
int dim = board.length;
2020
PointSet pointsChecked = PointSet.create(dim);
21+
pointsChecked.add(xx, yy);
2122
PointQueue pointsToCheck = PointQueue.create(dim);
2223
pointsToCheck.offer(xx, yy);
2324
while (!pointsToCheck.isEmpty()) {
2425
int ptId = pointsToCheck.poll();
2526
int y = ptId / dim;
2627
int x = ptId % dim;
27-
pointsChecked.add(x, y);
2828
if (board[y][x] != 0) {
2929
return board[y][x] + TERRITORY;
3030
}
3131
if (y > 0 && !pointsChecked.has(x, y - 1)) {
32+
pointsChecked.add(x, y - 1);
3233
pointsToCheck.offer(x, y - 1);
3334
}
3435
if (y < dim - 1 && !pointsChecked.has(x, y + 1)) {
36+
pointsChecked.add(x, y + 1);
3537
pointsToCheck.offer(x, y + 1);
3638
}
3739
if (x > 0 && !pointsChecked.has(x - 1, y)) {
40+
pointsChecked.add(x - 1, y);
3841
pointsToCheck.offer(x - 1, y);
3942
}
4043
if (x < dim - 1 && !pointsChecked.has(x + 1, y)) {
44+
pointsChecked.add(x + 1, y);
4145
pointsToCheck.offer(x + 1, y);
4246
}
4347
}
4448
throw new RuntimeException("empty board");
4549
}
4650

47-
private static void markStonesAround(
51+
static void markStonesAround(
4852
int[][] acc,
4953
int[][] board,
5054
int xx,
@@ -58,21 +62,23 @@ private static void markStonesAround(
5862
int baseColor = color - TERRITORY;
5963
int oppositeColor = baseColor == W ? B : W;
6064
int dim = board.length;
61-
BoardUpdate updater = BoardUpdate.builder(dim, 64);
65+
BoardUpdate tracker = BoardUpdate.builder(dim, 64);
6266
PointQueue pointsToCheck = PointQueue.create(dim);
67+
acc[yy][xx] = color;
68+
tracker.add(xx, yy);
6369
pointsToCheck.offer(xx, yy);
6470
while (!pointsToCheck.isEmpty()) {
6571
int ptId = pointsToCheck.poll();
6672
int y = ptId / dim;
6773
int x = ptId % dim;
68-
acc[y][x] = color;
69-
updater.add(x, y);
74+
tracker.add(x, y);
7075
if (y > 0) {
7176
int c = board[y - 1][x];
7277
if (c == oppositeColor) {
7378
oppositeStonesFound = true;
7479
}
75-
if (c == 0 && acc[y - 1][x] != color) {
80+
if (c == 0 && acc[y - 1][x] == -1) {
81+
acc[y - 1][x] = color;
7682
pointsToCheck.offer(x, y - 1);
7783
}
7884
}
@@ -81,7 +87,8 @@ private static void markStonesAround(
8187
if (c == oppositeColor) {
8288
oppositeStonesFound = true;
8389
}
84-
if (c == 0 && acc[y + 1][x] != color) {
90+
if (c == 0 && acc[y + 1][x] == -1) {
91+
acc[y + 1][x] = color;
8592
pointsToCheck.offer(x, y + 1);
8693
}
8794
}
@@ -90,7 +97,8 @@ private static void markStonesAround(
9097
if (c == oppositeColor) {
9198
oppositeStonesFound = true;
9299
}
93-
if (c == 0 && acc[y][x - 1] != color) {
100+
if (c == 0 && acc[y][x - 1] == -1) {
101+
acc[y][x - 1] = color;
94102
pointsToCheck.offer(x - 1, y);
95103
}
96104
}
@@ -99,14 +107,15 @@ private static void markStonesAround(
99107
if (c == oppositeColor) {
100108
oppositeStonesFound = true;
101109
}
102-
if (c == 0 && acc[y][x + 1] != color) {
110+
if (c == 0 && acc[y][x + 1] == -1) {
111+
acc[y][x + 1] = color;
103112
pointsToCheck.offer(x + 1, y);
104113
}
105114
}
106115
}
107116
if (oppositeStonesFound) {
108-
for (int i = 0; i < updater.size(); i++) {
109-
acc[updater.y(i)][updater.x(i)] = 0;
117+
for (int i = 0; i < tracker.size(); i++) {
118+
acc[tracker.y(i)][tracker.x(i)] = 0;
110119
}
111120
}
112121
}
@@ -125,7 +134,7 @@ public static int[][] count(
125134
return acc;
126135
}
127136

128-
private static int[][] createAcc(int[][] board) {
137+
static int[][] createAcc(int[][] board) {
129138
int[][] result = new int[board.length][];
130139
for (int i = 0; i < board.length; i++) {
131140
result[i] = new int[result.length];

src/main/java/com/bernd/game/Remove.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,39 @@ private static List<Point> findGroup(
1717
int dim = board.length;
1818
PointQueue pointsToCheck = PointQueue.create(dim);
1919
PointSet pointsChecked = PointSet.create(dim);
20+
pointsChecked.add(xx, yy);
2021
pointsToCheck.offer(xx, yy);
2122
List<Point> result = new ArrayList<>();
2223
while (!pointsToCheck.isEmpty()) {
2324
int ptId = pointsToCheck.poll();
2425
int y = ptId / dim;
2526
int x = ptId % dim;
26-
pointsChecked.add(x, y);
2727
result.add(new Point(x, y));
2828
if (y > 0) {
2929
int c = board[y - 1][x];
3030
if (c == color && !pointsChecked.has(x, y - 1)) {
31+
pointsChecked.add(x, y - 1);
3132
pointsToCheck.offer(x, y - 1);
3233
}
3334
}
3435
if (y < dim - 1) {
3536
int c = board[y + 1][x];
3637
if (c == color && !pointsChecked.has(x, y + 1)) {
38+
pointsChecked.add(x, y + 1);
3739
pointsToCheck.offer(x, y + 1);
3840
}
3941
}
4042
if (x > 0) {
4143
int c = board[y][x - 1];
4244
if (c == color && !pointsChecked.has(x - 1, y)) {
45+
pointsChecked.add(x - 1, y);
4346
pointsToCheck.offer(x - 1, y);
4447
}
4548
}
4649
if (x < dim - 1) {
4750
int c = board[y][x + 1];
4851
if (c == color && !pointsChecked.has(x + 1, y)) {
52+
pointsChecked.add(x + 1, y);
4953
pointsToCheck.offer(x + 1, y);
5054
}
5155
}
Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,84 @@
11
package com.bernd.model;
22

33
import com.bernd.game.Board;
4+
import com.bernd.game.Count;
45
import com.bernd.util.BoardUpdate;
5-
import java.util.function.Function;
6+
import java.util.Arrays;
7+
import org.apache.logging.log4j.LogManager;
8+
import org.apache.logging.log4j.Logger;
69

710
public record Game(
811
String id,
912
User black,
1013
User white,
11-
String currentUser,
14+
boolean counting,
15+
String currentPlayer,
16+
boolean opponentPassed,
1217
int[][] board
1318
) {
1419

20+
private static final Logger logger = LogManager.getLogger(Game.class);
21+
1522
public Game update(Move move) {
23+
try {
24+
return updateInternal(move);
25+
} catch (RuntimeException e) {
26+
StringBuilder sb = new StringBuilder("int[][] position = new int[][]{\n");
27+
for (int[] row : board) {
28+
String string = Arrays.toString(row).replace('[', '{').replace(']', '}');
29+
sb.append(" new int[]" + string + ",\n");
30+
}
31+
sb.append("};\n");
32+
logger.error(sb.toString(), e);
33+
return this;
34+
}
35+
}
36+
37+
private Game updateInternal(Move move) {
38+
if (move.pass()) {
39+
if (!opponentPassed) {
40+
return game(board, counting, true);
41+
}
42+
int[][] counted = Count.count(board);
43+
return game(counted, true);
44+
}
1645
int x = move.x();
1746
int y = move.y();
18-
int color = currentUser.equals(black().name()) ? Board.B : Board.W;
19-
Function<int[][], int[][]> update = BoardUpdate.create(board.length, x, y, color);
20-
int[][] rows = update.apply(board);
21-
int[][] newRows = Board.removeDeadStonesAround(rows, x, y);
47+
int color = currentColor();
48+
int[][] updated = BoardUpdate.create(board.length, x, y, color).apply(board);
49+
return game(Board.removeDeadStonesAround(updated, x, y));
50+
}
51+
52+
private Game game(
53+
int[][] board,
54+
boolean counting,
55+
boolean opponentPassed) {
2256
return new Game(
23-
this.id,
24-
this.black,
25-
this.white,
26-
currentUser.equals(black.name()) ? white().name() : black().name(),
27-
newRows);
57+
id,
58+
black,
59+
white,
60+
counting,
61+
nextPlayer(),
62+
opponentPassed,
63+
board);
64+
}
65+
66+
private Game game(
67+
int[][] board) {
68+
return game(board, counting, opponentPassed);
69+
}
70+
71+
private Game game(
72+
int[][] board,
73+
boolean counting) {
74+
return game(board, counting, opponentPassed);
75+
}
76+
77+
private String nextPlayer() {
78+
return currentPlayer.equals(black.name()) ? white().name() : black().name();
79+
}
80+
81+
private int currentColor() {
82+
return currentPlayer.equals(black().name()) ? Board.B : Board.W;
2883
}
2984
}

0 commit comments

Comments
 (0)