diff --git a/src/main/client/src/Game.jsx b/src/main/client/src/Game.jsx
index 50ea2e3..b06950a 100644
--- a/src/main/client/src/Game.jsx
+++ b/src/main/client/src/Game.jsx
@@ -46,7 +46,8 @@ export const Game = () => {
let setGameState = useGameStore(state => state.setGameState)
let queueStatus = useGameStore(state => state.queueStatus)
let addMove = useGameStore(state => state.addMove)
- let { board, currentColor, currentPlayer, counting, forbidden } = useGameStore(state => state.gameState)
+ let currentPlayer = useGameStore(state => state.currentPlayer)
+ let { board, currentColor, counting, forbidden } = useGameStore(state => state.gameState)
let [forbidden_x, forbidden_y] = forbidden
let initialized = useRef()
let canvasRef = useRef()
@@ -117,7 +118,7 @@ export const Game = () => {
if (!board.length) {
return
}
- if (!counting && currentPlayer !== auth.name) {
+ if (!counting && currentPlayer() !== auth.name) {
return
}
let cursor_x = Math.round((e.nativeEvent.offsetX - context.margin) / context.step)
@@ -146,7 +147,7 @@ export const Game = () => {
if (cursor_x == forbidden_x && cursor_y == forbidden_y) {
return
}
- if (currentPlayer !== auth.name) {
+ if (currentPlayer() !== auth.name) {
return
}
}
@@ -173,7 +174,7 @@ export const Game = () => {
} else {
paintStones(context, board)
}
- if (currentPlayer !== auth.name) {
+ if (currentPlayer() !== auth.name) {
return
}
if (!context.isCursorInBounds(cursor_x, cursor_y)) {
diff --git a/src/main/client/src/feature/GamePanel.jsx b/src/main/client/src/feature/GamePanel.jsx
index 267d220..b5d8eff 100644
--- a/src/main/client/src/feature/GamePanel.jsx
+++ b/src/main/client/src/feature/GamePanel.jsx
@@ -48,7 +48,8 @@ function Panel({zoom, setZoom}) {
let auth = useAuthStore(state => state.auth)
let black = useGameStore(state => state.black)
let white = useGameStore(state => state.white)
- let { board, currentPlayer, counting } = useGameStore(state => state.gameState)
+ let currentPlayer = useGameStore(state => state.currentPlayer)
+ let { board, counting } = useGameStore(state => state.gameState)
let navigate = useNavigate()
let onExit = useCallback(() => {
navigate(base + "/lobby")
@@ -121,7 +122,7 @@ function Panel({zoom, setZoom}) {
@@ -148,7 +149,7 @@ function Panel({zoom, setZoom}) {
)}
{!counting && (
- {currentPlayer + " ist dran..."}
+ {currentPlayer() + " ist dran..."}
)}
>
diff --git a/src/main/client/src/model/PointList.js b/src/main/client/src/model/PointList.js
index e335327..37c977b 100644
--- a/src/main/client/src/model/PointList.js
+++ b/src/main/client/src/model/PointList.js
@@ -7,11 +7,14 @@ export class PointList {
static LO = 0xffff
static HI = 0xffff0000
+ static EMPTY = {
+ size: () => 0,
+ forEach: () => undefined,
+ isEmpty: () => true,
+ }
+
static empty() {
- return {
- size: 0,
- forEach: () => {},
- }
+ return PointList.EMPTY
}
constructor(dim) {
diff --git a/src/main/client/src/model/board.js b/src/main/client/src/model/board.js
index d74c7a6..3e49c03 100644
--- a/src/main/client/src/model/board.js
+++ b/src/main/client/src/model/board.js
@@ -18,7 +18,6 @@ export function getGroupInfo(board, xx, yy) {
return {
x: xx,
y: yy,
- ptId: yy * dim + xx,
color: color,
hasStone: false,
liberties: 0,
@@ -80,7 +79,6 @@ export function getGroupInfo(board, xx, yy) {
return {
x: xx,
y: yy,
- ptId: yy * dim + xx,
color: color,
hasStone: true,
liberties: liberties,
@@ -98,7 +96,7 @@ export function rehydrate(board) {
for (let y = 0; y < board.length; y++) {
for (let x = 0; x < board[y].length; x++) {
if (result[y][x]) {
- result[y][x] = {...result[y][x], x: x, y: y, ptId: y * dim + x }
+ result[y][x] = {...result[y][x], x: x, y: y}
continue
}
let groupInfo = getGroupInfo(board, x, y)
diff --git a/src/main/client/src/model/ko.js b/src/main/client/src/model/ko.js
new file mode 100644
index 0000000..5383043
--- /dev/null
+++ b/src/main/client/src/model/ko.js
@@ -0,0 +1,30 @@
+import {
+ updateBoard,
+} from "./base.js"
+import {
+ BLACK,
+ WHITE,
+} from "../util.js"
+
+const NOT_FORBIDDEN = [-1, -1]
+
+export function getForbidden(board, updated, move) {
+ if (!board || !board.length) {
+ return NOT_FORBIDDEN
+ }
+ let {x, y, color, dead} = move
+ if (dead.size() !== 1) {
+ return NOT_FORBIDDEN
+ }
+ let oppositeColor = color ^ (WHITE | BLACK)
+ let dx = dead.x(0)
+ let dy = dead.y(0)
+ let [kill] = updateBoard(updated, {x: dx, y: dy, color: oppositeColor})
+ if (kill.size() !== 1) {
+ return NOT_FORBIDDEN
+ }
+ if (kill.x(0) !== x || kill.y(0) !== y) {
+ return NOT_FORBIDDEN
+ }
+ return [dx, dy]
+}
diff --git a/src/main/client/src/store.js b/src/main/client/src/store.js
index 986cd23..4bf6500 100644
--- a/src/main/client/src/store.js
+++ b/src/main/client/src/store.js
@@ -17,6 +17,9 @@ import {
import {
updateBoard,
} from "./model/base.js"
+import {
+ getForbidden,
+} from "./model/ko.js"
export const useAuthStore = create((set) => ({
auth: {
@@ -55,9 +58,13 @@ export const useGameStore = create((set, get) => ({
state.isInCountingGroup = has
}))
},
+ currentPlayer: () => {
+ return get().gameState.currentColor === WHITE ?
+ get().white.name :
+ get().black.name
+ },
gameState: {
board: [],
- currentPlayer: undefined,
currentColor: BLACK,
counting: false,
forbidden: [-1, -1],
@@ -80,12 +87,12 @@ export const useGameStore = create((set, get) => ({
return
}
let [dead, updated] = updateBoard(get().baseBoard, move)
- state.moves.push({...move, dead})
+ let storedMove = {...move, dead}
+ state.moves.push(storedMove)
state.baseBoard = updated
state.gameState.board = rehydrate(updated)
state.gameState.currentColor = get().gameState.currentColor ^ (BLACK | WHITE)
- state.gameState.currentPlayer = get().gameState.currentPlayer === get().black.name ? get().white.name : get().black.name
- state.gameState.forbidden = move.forbidden
+ state.gameState.forbidden = getForbidden(get().baseBoard, updated, storedMove)
}))
},
setGameState: (game) => {
@@ -96,7 +103,6 @@ export const useGameStore = create((set, get) => ({
state.baseBoard = game.board
state.moves = game.moves
state.gameState.board = rehydrate(game.board)
- state.gameState.currentPlayer = game.currentPlayer
state.gameState.currentColor = game.currentColor
state.gameState.counting = game.counting
state.gameState.forbidden = game.forbidden
diff --git a/src/main/java/com/bernd/GameController.java b/src/main/java/com/bernd/GameController.java
index bb861c9..c02af1b 100644
--- a/src/main/java/com/bernd/GameController.java
+++ b/src/main/java/com/bernd/GameController.java
@@ -66,7 +66,7 @@ public void action(Move move, Principal principal) {
if (updated.counting()) {
operations.convertAndSend("/topic/move/" + game.id(), CountingMove.create(color, moveNumber, updated.board()));
} else {
- operations.convertAndSend("/topic/move/" + game.id(), move.toView(color, moveNumber, updated.forbidden()));
+ operations.convertAndSend("/topic/move/" + game.id(), move.toView(color, moveNumber));
}
}
diff --git a/src/main/java/com/bernd/game/Direction.java b/src/main/java/com/bernd/game/Direction.java
index 6e57da6..42045e3 100644
--- a/src/main/java/com/bernd/game/Direction.java
+++ b/src/main/java/com/bernd/game/Direction.java
@@ -35,11 +35,11 @@ public static Direction from(int source_x, int source_y, int target_x, int targe
return NONE;
}
- public int moveX(int xx) {
- return xx + inc_x;
+ public int moveX(int x) {
+ return x + inc_x;
}
- public int moveY(int yy) {
- return yy + inc_y;
+ public int moveY(int y) {
+ return y + inc_y;
}
}
diff --git a/src/main/java/com/bernd/game/MoveList.java b/src/main/java/com/bernd/game/MoveList.java
index 0053408..e886f2b 100644
--- a/src/main/java/com/bernd/game/MoveList.java
+++ b/src/main/java/com/bernd/game/MoveList.java
@@ -77,16 +77,16 @@ public GameMove get(int i) {
int ptId = i % 2 == 0 ? code & LO : (code >> 16);
int color = (ptId & WHITE) != 0 ? Board.W : Board.B;
if ((ptId & GAME_END) != 0) {
- return new GameMove(i, 0, true, -1, -1, true, true, new int[]{-1, -1});
+ return new GameMove(i, 0, true, -1, -1, true, true);
}
boolean counting = (ptId & COUNTING) != 0;
if ((ptId & PASS) != 0) {
- return new GameMove(i, color, true, -1, -1, counting, false, new int[]{-1, -1});
+ return new GameMove(i, color, true, -1, -1, counting, false);
} else {
int data = ptId & DATA;
int x = data % dim;
int y = data / dim;
- return new GameMove(i, color, false, x, y, counting, false, new int[]{-1, -1});
+ return new GameMove(i, color, false, x, y, counting, false);
}
}
diff --git a/src/main/java/com/bernd/model/GameMove.java b/src/main/java/com/bernd/model/GameMove.java
index 1350222..273cb7e 100644
--- a/src/main/java/com/bernd/model/GameMove.java
+++ b/src/main/java/com/bernd/model/GameMove.java
@@ -7,6 +7,5 @@ public record GameMove(
int x,
int y,
boolean counting,
- boolean end,
- int[] forbidden) {
+ boolean end) {
}
diff --git a/src/main/java/com/bernd/model/Move.java b/src/main/java/com/bernd/model/Move.java
index d7fcae7..b608e7a 100644
--- a/src/main/java/com/bernd/model/Move.java
+++ b/src/main/java/com/bernd/model/Move.java
@@ -7,7 +7,7 @@ public record Move(
int x,
int y) {
- public GameMove toView(int color, int moveNumber, int[] forbidden) {
- return new GameMove(moveNumber, color, pass, x, y, false, false, forbidden);
+ public GameMove toView(int color, int moveNumber) {
+ return new GameMove(moveNumber, color, pass, x, y, false, false);
}
}