Skip to content

Commit

Permalink
add server side timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
h908714124 committed Sep 27, 2024
1 parent 025e85b commit 5dcf9aa
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 38 deletions.
10 changes: 8 additions & 2 deletions src/main/client/src/feature/game/Game.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
isKibitz,
createGameState,
isReviewing,
isCounting,
teleport,
setWinnerByTime,
} from "./state.js"
Expand Down Expand Up @@ -104,7 +105,7 @@ function Board({gameState, setGameState}) {
let lastMove = gameState.lastMove
let queueStatus = gameState.queueStatus
let myColor = gameState.myColor
let counting = gameState.counting
let counting = isCounting(gameState)
let board = gameState.board
let [forbidden_x, forbidden_y] = gameState.forbidden
let canvasRef = useRef()
Expand Down Expand Up @@ -326,7 +327,12 @@ function Board({gameState, setGameState}) {
y: cursor_y,
}
if (!isSelfPlay(gameState)) { // can't add early in self play; myColor is 0
setGameState(addMove(gameState, {...move, color: myColor})) // early add move
// early add move
setGameState(addMove(gameState, {
...move,
color: myColor,
n: gameState.moves.length,
}))
}
resetCountdown()
playClickSound()
Expand Down
7 changes: 5 additions & 2 deletions src/main/client/src/feature/game/GamePanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
currentPlayer,
currentColor,
isKibitz,
isCounting,
moveBack,
moveForward,
countingAgreed,
Expand All @@ -60,7 +61,8 @@ export const GamePanel = ({gameState, setGameState}) => {
function Panel({gameState, setGameState}) {
let {gameId} = useParams()
let auth = useAuthStore(state => state.auth)
let {counting, board} = gameState
let {board} = gameState
let counting = isCounting(gameState)

if (!board.length) {
return <span>Loading...</span>
Expand All @@ -84,7 +86,8 @@ function Panel({gameState, setGameState}) {
}

function WhoIsWho({gameState}) {
let {black, white, counting} = gameState
let {black, white} = gameState
let counting = isCounting(gameState)
let end = gameHasEnded(gameState)
let timeout = useTimeoutStore(state => state.timeout)
let timesetting = gameState.timesetting
Expand Down
25 changes: 18 additions & 7 deletions src/main/client/src/feature/game/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import {
PointList,
} from "src/model/PointList.js"

const STATE_COUNTING = 1
const STATE_TIMEOUT = 2

export function initialState() {
return {
id: "",
Expand All @@ -41,16 +44,16 @@ export function initialState() {
black: "",
white: "",
myColor: 0,
counting: false,
state: 0,
queueLength: 0,
lastMove: undefined,
board: [],
forbidden: [-1, -1],
}
}

export function countingComplete({dim, counting, baseBoard}) {
if (!counting) {
export function countingComplete({dim, state, baseBoard}) {
if (state !== STATE_COUNTING) {
return false
}
for (let y = 0; y < dim; y++) {
Expand Down Expand Up @@ -99,7 +102,10 @@ export function countingAgreed({moves, myColor}) {
return move.color === myColor && move.action === "agreeCounting"
}

export function gameHasEnded({winnerByTime, moves}) {
export function gameHasEnded({state, winnerByTime, moves}) {
if (state === STATE_TIMEOUT) {
return true
}
if (winnerByTime) {
return true
}
Expand Down Expand Up @@ -182,7 +188,8 @@ function goToEnd(baseState) {

export function addMove(baseState, move) {
let {action, n} = move
let {moves, baseBoard, historyBoard, counting, queueLength} = baseState
let {moves, baseBoard, historyBoard, state, queueLength} = baseState
let counting = state === STATE_COUNTING
let previousMove = getMove(moves, n - 1)
if (n < moves.length) {
return baseState
Expand Down Expand Up @@ -212,7 +219,7 @@ export function addMove(baseState, move) {
draft.board = rehydrate(updated, updatedFinalBoard)
draft.forbidden = forbidden
if (action === "pass" && previousMove?.action === "pass") {
draft.counting = true
draft.state = STATE_COUNTING
}
})
}
Expand Down Expand Up @@ -275,7 +282,7 @@ export function createGameState(game, auth) {
dim: game.dim,
timesetting: game.timesetting,
handicap: game.handicap,
counting: counting,
state: game.state,
baseBoard: baseBoard,
historyBoard: historyBoard,
moves: moves,
Expand Down Expand Up @@ -394,3 +401,7 @@ function updateHistoryBoard(historyBoard, move) {
updated[y][x] = {n, color: (color || oldColor)}
return updated
}

export function isCounting({state}) {
return state === STATE_COUNTING
}
33 changes: 21 additions & 12 deletions src/main/java/com/bernd/GameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,35 +72,44 @@ public void action(Move move, Principal p) {
if (p == null || game == null) {
return;
}
if (game.isForbidden(move)) {
if (game.gameHasEnded()) {
return;
}
int principalColor = getColorFromPrincipal(game, getPrincipal(p));
if (principalColor == 0) {
return;
}
int color = getColorFromGameState(game);
if (color == 0
|| principalColor == 0
|| color != principalColor && !game.counting() && !game.isSelfPlay()) {
Chat chat = chats.get(game.id());
if (System.currentTimeMillis() > game.updated() + game.timesetting() * 1000L) {
games.put(game.withTimeoutState());
String text = color == Board.W ? "B+Time" : "W+Time";
ChatMessage message = new ChatMessage(chat.counter().getAndIncrement(), text, null, "status", null);
chat.messages().add(message);
operations.convertAndSend("/topic/chat/" + chat.id(), message);
operations.convertAndSend("/topic/move/" + game.id(), game.getLastMove());
return;
}
Move updatedMove = move
if (!game.isCounting() && !game.isSelfPlay() && color != principalColor) {
return;
}
if (game.isForbidden(move)) {
return;
}
Game updated = game.update(move
.withCount(game.moves().size())
.withColor(game.isSelfPlay() ? color : principalColor);
Game updated = game.update(updatedMove);
.withColor(game.isSelfPlay() ? color : principalColor));
games.put(updated);
Move lastMove = game.getLastMove();
if (lastMove.end()) {
Chat chat = chats.get(game.id());
ChatMessage message = new ChatMessage(chat.counter().getAndIncrement(), game.getScore(), null, "status", null);
chat.messages().add(message);
operations.convertAndSend("/topic/chat/" + chat.id(), message);
}
operations.convertAndSend("/topic/move/" + game.id(), lastMove.removeColor());
operations.convertAndSend("/topic/move/" + game.id(), lastMove);
}

private int getColorFromGameState(Game game) {
if (game.gameHasEnded()) {
return 0;
}
if (game.remainingHandicap() > 0) {
return Board.B;
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/bernd/LobbyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ public ViewGame startEdit(@RequestBody MatchRequest request) {
RandomString.get(),
principal,
principal,
false,
Game.STATE_NORMAL,
createEmptyBoard(request.dim()),
request.dim(),
request.timesetting(),
System.currentTimeMillis(),
request.handicap(),
new int[]{-1, -1},
MoveList.create(request.dim())));
Expand Down
35 changes: 31 additions & 4 deletions src/main/java/com/bernd/model/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,29 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Objects;

import static com.bernd.game.Board.removeDeadStonesAround;
import static com.bernd.util.Util.COLORS;

public record Game(
String id,
String black,
String white,
boolean counting,
int state,
int[][] board,
int dim,
int timesetting,
long updated,
int handicap,
int[] forbidden,
MoveList moves
) {

public static final int STATE_NORMAL = 0;
public static final int STATE_COUNTING = 1;
public static final int STATE_TIMEOUT = 2;

private static final Logger logger = LogManager.getLogger(Game.class);
public static final int[] NOT_FORBIDDEN = {-1, -1};

Expand All @@ -47,7 +54,7 @@ private Game updateInternal(Move move) {
if (move.agreeCounting()) {
return toBuilder().build();
}
if (counting) {
if (isCounting()) {
int[][] updated = move.resetCounting() ?
Toggle.resetCounting(board) :
Toggle.toggleStonesAt(board, move.x(), move.y());
Expand All @@ -59,7 +66,7 @@ private Game updateInternal(Move move) {
if (move.pass()) {
if (opponentPassed()) {
return toBuilder()
.withCounting(true)
.withState(STATE_COUNTING)
.withBoard(Count.count(board))
.withForbidden(NOT_FORBIDDEN)
.build();
Expand Down Expand Up @@ -143,6 +150,9 @@ public ViewGame toView() {
}

public boolean gameHasEnded() {
if (isTimeout()) {
return true;
}
if (moves.isEmpty()) {
return false;
}
Expand Down Expand Up @@ -189,7 +199,11 @@ public int remainingHandicap() {
}

public boolean isForbidden(Move move) {
return move.x() == forbidden[0] && move.y() == forbidden[1];
if (!Objects.toString(move.action(), "").isEmpty()) {
return false;
}
return move.x() == -1 || move.y() == -1 ||
move.x() == forbidden[0] && move.y() == forbidden[1];
}

public String getScore() {
Expand All @@ -208,4 +222,17 @@ public String getScore() {
}
return w > b ? "W+" + w : "B+" + b;
}

public Game withTimeoutState() {
moves.addGameEndMarker();
return toBuilder().withState(STATE_TIMEOUT).build();
}

public boolean isTimeout() {
return state == STATE_TIMEOUT;
}

public boolean isCounting() {
return state == STATE_COUNTING;
}
}
11 changes: 6 additions & 5 deletions src/main/java/com/bernd/model/GameBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
public final class GameBuilder {
private final Game game;

private boolean counting;
private int state;
private int[][] board;
private int[] forbidden;

private GameBuilder(Game game) {
this.game = game;
}

public GameBuilder withCounting(boolean counting) {
this.counting = counting;
public GameBuilder withState(int state) {
this.state = state;
return this;
}

Expand All @@ -32,7 +32,7 @@ public GameBuilder withForbidden(int x, int y) {

static GameBuilder builder(Game game) {
GameBuilder builder = new GameBuilder(game);
builder.counting = game.counting();
builder.state = game.state();
builder.board = game.board();
builder.forbidden = game.forbidden();
return builder;
Expand All @@ -43,10 +43,11 @@ public Game build() {
game.id(),
game.black(),
game.white(),
counting,
state,
board,
game.dim(),
game.timesetting(),
System.currentTimeMillis(),
game.handicap(),
forbidden,
game.moves()
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/com/bernd/model/Move.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ public Move withCount(int n) {
return new Move(color, n, action, x, y);
}

public Move removeColor() {
return this;
}

public boolean agreeCounting() {
return "agreeCounting".equals(action);
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/bernd/model/OpenGame.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ public Game accept(String opponent, AcceptRequest acceptRequest) {
id,
userBlack,
userWhite,
false,
Game.STATE_NORMAL,
createEmptyBoard(dim),
dim,
timesetting,
System.currentTimeMillis(),
acceptRequest.handicap(),
new int[]{-1, -1},
MoveList.create(dim));
Expand Down

0 comments on commit 5dcf9aa

Please sign in to comment.