Skip to content

Commit

Permalink
wip incremental updates
Browse files Browse the repository at this point in the history
  • Loading branch information
h908714124 committed Aug 3, 2024
1 parent 9225bd6 commit f69f4a5
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 16 deletions.
10 changes: 3 additions & 7 deletions src/main/client/src/Game.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const Game = () => {
let stompClient = useContext(StompContext)
let auth = useAuthStore(state => state.auth)
let setGameState = useGameStore(state => state.setGameState)
let addMove = useGameStore(state => state.addMove)
let { board, currentColor, currentPlayer, counting, forbidden } = useGameStore(state => state.gameState)
let [forbidden_x, forbidden_y] = forbidden
let initialized = useRef()
Expand Down Expand Up @@ -192,13 +193,9 @@ export const Game = () => {
return
}
initialized.current = true
let sub1 = stompClient.subscribe("/topic/game/" + gameId, (message) => {
let game = JSON.parse(message.body)
setGameState(game)
})
let sub2 = stompClient.subscribe("/topic/move/" + gameId, (message) => {
let move = JSON.parse(message.body)
console.log(move) // TODO
addMove(move)
})
doTry(async () => {
let game = await tfetch("/api/game/" + gameId, {
Expand All @@ -209,10 +206,9 @@ export const Game = () => {
setGameState(game)
})
return () => {
sub1.unsubscribe()
sub2.unsubscribe()
}
}, [setGameState, initialized, stompClient, gameId, auth])
}, [setGameState, addMove, initialized, stompClient, gameId, auth])
if (!board.length) {
return <div>Loading...</div>
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/client/src/feature/GamePanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ function Panel({zoom, setZoom}) {
let { gameId } = useParams()
let stompClient = useContext(StompContext)
let auth = useAuthStore(state => state.auth)
let { black, white} = useGameStore(state => state)
let black = useGameStore(state => state.black)
let white = useGameStore(state => state.white)
let { board, currentPlayer, counting } = useGameStore(state => state.gameState)
let navigate = useNavigate()
let onExit = useCallback(() => {
Expand Down
113 changes: 109 additions & 4 deletions src/main/client/src/model/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
} from "./PointSet.js"
import {
hasStone,
BLACK,
WHITE,
} from "../util.js"

export function getGroup(board, xx, yy) {
Expand Down Expand Up @@ -117,7 +119,7 @@ export function isForbidden(board, groupInfo, currentColor) {
return true
}
if (y > 0) {
let { color, liberties, hasStone } = board[y - 1][x]
let {color, liberties, hasStone} = board[y - 1][x]
if (!hasStone) {
return false
}
Expand All @@ -129,7 +131,7 @@ export function isForbidden(board, groupInfo, currentColor) {
}
}
if (y < dim - 1) {
let { color, liberties, hasStone } = board[y + 1][x]
let {color, liberties, hasStone} = board[y + 1][x]
if (!hasStone) {
return false
}
Expand All @@ -141,7 +143,7 @@ export function isForbidden(board, groupInfo, currentColor) {
}
}
if (x > 0) {
let { color, liberties, hasStone } = board[y][x - 1]
let {color, liberties, hasStone} = board[y][x - 1]
if (!hasStone) {
return false
}
Expand All @@ -153,7 +155,7 @@ export function isForbidden(board, groupInfo, currentColor) {
}
}
if (x < dim - 1) {
let { color, liberties, hasStone } = board[y][x + 1]
let {color, liberties, hasStone} = board[y][x + 1]
if (!hasStone) {
return false
}
Expand All @@ -166,3 +168,106 @@ export function isForbidden(board, groupInfo, currentColor) {
}
return true
}

export function updateBoard(boardBeforeMove, move) {
let {pass, x, y, color} = move
if (pass) {
return boardBeforeMove
}
let board = applyMove(boardBeforeMove, move)
let oppositeColor = color ^ (WHITE | BLACK)
let size = board.length
let result = board
if (y > 0 && board[y - 1][x] === oppositeColor) {
result = removeDeadGroup(board, x, y - 1)
}
if (y < size - 1 && board[y + 1][x] === oppositeColor) {
result = removeDeadGroup(board, x, y + 1)
}
if (x > 0 && board[y][x - 1] === oppositeColor) {
result = removeDeadGroup(board, x - 1, y)
}
if (x < size - 1 && board[y][x + 1] === oppositeColor) {
result = removeDeadGroup(board, x + 1, y)
}
return result
}

function removeDeadGroup(board, xx, yy) {
let dim = board.length
if (yy > 0 && board[yy - 1][xx] == 0) {
return board
}
if (yy < dim - 1 && board[yy + 1][xx] == 0) {
return board
}
if (xx > 0 && board[yy][xx - 1] == 0) {
return board
}
if (xx < dim - 1 && board[yy][xx + 1] == 0) {
return board
}
let color = board[yy][xx]
let acc = new PointList(dim)
let pointsChecked = new PointSet(dim)
pointsChecked.add(xx, yy)
let pointsToCheck = new PointQueue(dim)
pointsToCheck.offer(xx, yy)
while (!pointsToCheck.isEmpty()) {
let ptId = pointsToCheck.poll()
let y = Math.trunc(ptId / dim)
let x = ptId % dim
acc.add(x, y)
if (y > 0) {
let bpt = board[y - 1][x]
if (bpt === 0) {
return board
} else if (bpt === color && !pointsChecked.has(x, y - 1)) {
pointsChecked.add(x, y - 1)
pointsToCheck.offer(x, y - 1)
}
}
if (y < dim - 1) {
let bpt = board[y + 1][x]
if (bpt === 0) {
return board
} else if (bpt === color && !pointsChecked.has(x, y + 1)) {
pointsChecked.add(x, y + 1)
pointsToCheck.offer(x, y + 1)
}
}
if (x > 0) {
let bpt = board[y][x - 1]
if (bpt === 0) {
return board
} else if (bpt === color && !pointsChecked.has(x - 1, y)) {
pointsChecked.add(x - 1, y)
pointsToCheck.offer(x - 1, y)
}
}
if (x < dim - 1) {
let bpt = board[y][x + 1]
if (bpt === 0) {
return board
} else if (bpt === color && !pointsChecked.has(x + 1, y)) {
pointsChecked.add(x + 1, y)
pointsToCheck.offer(x + 1, y)
}
}
}
let result = board.slice()
acc.forEach((x, y) => {
if (result[y] === board[y]) {
result[y] = board[y].slice()
}
result[y][x] = 0
})
return result
}

function applyMove(board, {color, x, y}) {
let result = board.slice()
result[y] = board[y].slice()
result[y][x] = color
return result
}
24 changes: 23 additions & 1 deletion src/main/client/src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
} from "immer"
import {
BLACK,
WHITE,
} from "./util.js"
import {
rehydrate,
updateBoard,
} from "./model/board.js"

export const useAuthStore = create((set) => ({
Expand All @@ -31,7 +33,10 @@ export const useAuthStore = create((set) => ({
},
}))

export const useGameStore = create((set) => ({
export const useGameStore = create((set, get) => ({
moves: [],
baseBoard: [],
queueStatus: "up_to_date",
editMode: false,
black: {
name: "",
Expand All @@ -52,11 +57,28 @@ export const useGameStore = create((set) => ({
counting: false,
forbidden: [-1, -1],
},
addMove: (move) => {
set(produce(state => {
if (get().moves.length < move.n) {
state.queueStatus = "behind"
return
}
state.queueStatus = "up_to_date"
state.moves.push(move)
let updated = updateBoard(get().baseBoard, move)
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
}))
},
setGameState: (game) => {
set(produce(state => {
state.black = game.black
state.white = game.white
state.editMode = game.editMode
state.baseBoard = game.board
state.moves = game.moves
state.gameState.board = rehydrate(game.board)
state.gameState.currentPlayer = game.currentPlayer
state.gameState.currentColor = game.currentColor
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/bernd/game/MoveList.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public final class MoveList {
private MoveList(
int dim,
int[] buffer) {
this.capacity = dim * dim;
this.capacity = 2 * buffer.length;
this.dim = dim;
this.buffer = buffer;
}
Expand All @@ -39,7 +39,8 @@ public static MoveList create(int dim) {

public void add(int color, Move move) {
if (pos >= capacity) {
int newCapacity = 2 * capacity;
int boardSize = dim * dim;
int newCapacity = capacity < boardSize ? boardSize : capacity + boardSize;
buffer = Arrays.copyOf(buffer, divUp(newCapacity, 2));
capacity = newCapacity;
}
Expand Down
13 changes: 12 additions & 1 deletion src/test/java/com/bernd/game/MoveListTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class MoveListTest {

@Test
void get() {
void testGet() {
MoveList list = MoveList.create(9);
list.add(Board.B, move(0, 1));
list.add(Board.W, move(2, 3));
Expand All @@ -21,6 +21,17 @@ void get() {
assertEquals(Board.W, list.get(1).color());
}

@Test
void testGrow() {
MoveList list = MoveList.create(9);
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
list.add(Board.B, move(x, y));
}
}
assertEquals(81, list.size());
}

private Move move(int x, int y) {
return new Move("", false, false, x, y);
}
Expand Down

0 comments on commit f69f4a5

Please sign in to comment.