From 06902692992452662f5da44e8ce11f02a2e52ed1 Mon Sep 17 00:00:00 2001 From: Christopher Strauss Date: Thu, 29 Aug 2024 13:41:55 +0200 Subject: [PATCH] create sgf --- .../client/src/feature/game/BoardSettings.jsx | 25 ++++++++- src/main/client/src/feature/game/Game.jsx | 2 +- src/main/java/com/bernd/GameController.java | 17 +++++- src/main/java/com/bernd/game/Board.java | 1 + src/main/java/com/bernd/util/SgfCreator.java | 55 +++++++++++++++++++ .../java/com/bernd/util/SgfCreatorTest.java | 26 +++++++++ 6 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/bernd/util/SgfCreator.java create mode 100644 src/test/java/com/bernd/util/SgfCreatorTest.java diff --git a/src/main/client/src/feature/game/BoardSettings.jsx b/src/main/client/src/feature/game/BoardSettings.jsx index 245ad01..20aef59 100644 --- a/src/main/client/src/feature/game/BoardSettings.jsx +++ b/src/main/client/src/feature/game/BoardSettings.jsx @@ -6,6 +6,7 @@ import { FaVolumeUp, FaSearchPlus, FaSearchMinus, + FaDownload, } from "react-icons/fa" import { useMuteStore, @@ -13,12 +14,18 @@ import { import { useViewStateStore, } from "src/layout.js" +import { + base, +} from "src/util.js" + +export function BoardSettings({gameId, black, white}) { + -export function BoardSettings() { return (
+
) } @@ -66,3 +73,19 @@ function Zoom() { ) } + +function SaveGameFile({gameId, black, white}) { + return ( + + + + + + ) +} diff --git a/src/main/client/src/feature/game/Game.jsx b/src/main/client/src/feature/game/Game.jsx index b9f3267..61c93ea 100644 --- a/src/main/client/src/feature/game/Game.jsx +++ b/src/main/client/src/feature/game/Game.jsx @@ -69,7 +69,7 @@ export function Game() {
- +
diff --git a/src/main/java/com/bernd/GameController.java b/src/main/java/com/bernd/GameController.java index 184f9b8..26d9d22 100644 --- a/src/main/java/com/bernd/GameController.java +++ b/src/main/java/com/bernd/GameController.java @@ -11,7 +11,11 @@ import com.bernd.model.OpenGame; import com.bernd.model.ViewGame; import com.bernd.util.RandomString; +import com.bernd.util.SgfCreator; +import java.security.Principal; +import java.time.LocalDate; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.messaging.core.MessageSendingOperations; import org.springframework.messaging.handler.annotation.MessageMapping; @@ -23,8 +27,6 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.server.ResponseStatusException; -import java.security.Principal; - import static com.bernd.util.Auth.getPrincipal; import static com.bernd.util.Util.COLORS; @@ -144,4 +146,15 @@ public ResponseEntity accept(@RequestBody AcceptRequest acceptRequest) { operations.convertAndSend("/topic/lobby/active_games", activeGames.games()); return ResponseEntity.ok().build(); } + + @GetMapping("/api/sgf/{id}/{black}_vs_{white}.sgf") + public ResponseEntity getSgf( + @PathVariable String id) { + Game game = games.get(id); + if (game == null) { + return ResponseEntity.notFound().build(); + } + String sgf = SgfCreator.createSgf(game, LocalDate.now()); + return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(sgf); + } } diff --git a/src/main/java/com/bernd/game/Board.java b/src/main/java/com/bernd/game/Board.java index a67a6c3..6936c57 100644 --- a/src/main/java/com/bernd/game/Board.java +++ b/src/main/java/com/bernd/game/Board.java @@ -111,4 +111,5 @@ public static int[][] removeDeadStonesAround( } return result; } + } diff --git a/src/main/java/com/bernd/util/SgfCreator.java b/src/main/java/com/bernd/util/SgfCreator.java new file mode 100644 index 0000000..8712b8d --- /dev/null +++ b/src/main/java/com/bernd/util/SgfCreator.java @@ -0,0 +1,55 @@ +package com.bernd.util; + +import com.bernd.model.Game; +import com.bernd.model.Move; +import java.time.LocalDate; + +public final class SgfCreator { + + public static String createSgf(Game game, LocalDate date) { + int twoPass = 0; + int asciiAddOn = 97; + StringBuilder sb = new StringBuilder(); + sb.append("(;"); + sb + .append("FF[4]\n") + .append("CA[UTF-8]\n") + .append("GM[1]\n") + .append("DT[" + date.toString() + "]\n") + .append("GN[" + game.id() + "]\n") + .append("PB[" + game.black() + "]\n") + .append("PW[" + game.white() + "]\n") + .append("RE[" + (game.gameHasEnded() ? game.getScore() : "?") + "]\n") + .append("SZ[" + game.dim() + "]\n"); + for (Move move : game.moves().moves()) { + sb + .append(";") + .append(getColorFromValue(move.color())) + .append("["); + if (!move.pass()) { + twoPass = 0; + sb + .append((char) (move.x() + asciiAddOn)) + .append((char) (move.y() + asciiAddOn)); + } else { + twoPass++; + if (twoPass == 2) { + sb.append("]\n"); + break; + } + } + sb + .append("]\n"); + } + sb.append(")"); + return sb.toString(); + } + + private static String getColorFromValue(int value) { + if (value == 32) { + return "B"; + } + return "W"; + } + +} diff --git a/src/test/java/com/bernd/util/SgfCreatorTest.java b/src/test/java/com/bernd/util/SgfCreatorTest.java new file mode 100644 index 0000000..576ae12 --- /dev/null +++ b/src/test/java/com/bernd/util/SgfCreatorTest.java @@ -0,0 +1,26 @@ +package com.bernd.util; + +import com.bernd.game.Board; +import com.bernd.game.MoveList; +import com.bernd.model.Game; +import com.bernd.model.Move; +import java.time.LocalDate; +import java.time.Month; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SgfCreatorTest { + + @Test + void testCreate() { + MoveList moveList = MoveList.create(20); + moveList.add(new Move(Board.B, 0, null, 3, 4)); + moveList.add(new Move(Board.W, 0, null, 6, 4)); + Game game = new Game("1234", "B", "W", false, new int[9][], 9, 0, null, moveList); + String sgf = SgfCreator.createSgf(game, LocalDate.of(2024, Month.AUGUST, 30)); + assertEquals("(;FF[4]CA[UTF-8]GM[1]DT[2024-08-30]GN[1234]PB[B]PW[W]RE[?]SZ[9];B[de];W[ge])", + sgf.replace("\n", "")); + } + +}