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); } }