Skip to content

Commit f0aa4c2

Browse files
author
Christopher Strauss
committed
create sgf
1 parent ac39d63 commit f0aa4c2

File tree

4 files changed

+81
-4
lines changed

4 files changed

+81
-4
lines changed

src/main/client/src/feature/game/BoardSettings.jsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
FaVolumeUp,
77
FaSearchPlus,
88
FaSearchMinus,
9+
FaDownload,
910
} from "react-icons/fa"
1011
import {
1112
useMuteStore,
@@ -14,11 +15,14 @@ import {
1415
useViewStateStore,
1516
} from "src/layout.js"
1617

17-
export function BoardSettings() {
18+
export function BoardSettings({gameState, setGameState}) {
19+
20+
1821
return (
1922
<div className="absolute pl-2 pt-1 flex flex-col items-center">
2023
<MuteIcon />
2124
<Zoom />
25+
<SaveGameFile gameState={gameState} setGameState={setGameState} />
2226
</div>
2327
)
2428
}
@@ -66,3 +70,19 @@ function Zoom() {
6670
</>
6771
)
6872
}
73+
74+
function SaveGameFile({gameState}) {
75+
return (
76+
<a
77+
href={"/app/api/sgf/" + gameState.id + "/" + gameState.black + "_vs_" + gameState.white + ".sgf"}
78+
target="_blank"
79+
download={gameState.id + "_" + gameState.black + "_vs_" + gameState.white + ".sgf"}
80+
className="mt-[0.25rem]">
81+
<IconContext.Provider value={{
82+
size: "1.5em",
83+
}}>
84+
<FaDownload />
85+
</IconContext.Provider>
86+
</a>
87+
)
88+
}

src/main/client/src/feature/game/Game.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export function Game() {
6969
<div
7070
style={{ width: vw() - sidebarWidth }}
7171
className="h-full">
72-
<BoardSettings />
72+
<BoardSettings gameState={gameState} setGameState={setGameState} />
7373
<Board gameState={gameState} setGameState={setGameState} />
7474
<GamePanel gameState={gameState} setGameState={setGameState} />
7575
</div>

src/main/java/com/bernd/GameController.java

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,15 @@
1111
import com.bernd.model.OpenGame;
1212
import com.bernd.model.ViewGame;
1313
import com.bernd.util.RandomString;
14+
import java.io.ByteArrayInputStream;
15+
import java.io.IOException;
16+
import java.security.Principal;
17+
import java.text.SimpleDateFormat;
18+
import java.util.Date;
19+
import org.springframework.core.io.InputStreamResource;
20+
import org.springframework.core.io.Resource;
1421
import org.springframework.http.HttpStatus;
22+
import org.springframework.http.MediaType;
1523
import org.springframework.http.ResponseEntity;
1624
import org.springframework.messaging.core.MessageSendingOperations;
1725
import org.springframework.messaging.handler.annotation.MessageMapping;
@@ -23,8 +31,6 @@
2331
import org.springframework.web.bind.annotation.ResponseBody;
2432
import org.springframework.web.server.ResponseStatusException;
2533

26-
import java.security.Principal;
27-
2834
import static com.bernd.util.Auth.getPrincipal;
2935
import static com.bernd.util.Util.COLORS;
3036

@@ -144,4 +150,47 @@ public ResponseEntity<?> accept(@RequestBody AcceptRequest acceptRequest) {
144150
operations.convertAndSend("/topic/lobby/active_games", activeGames.games());
145151
return ResponseEntity.ok().build();
146152
}
153+
154+
@GetMapping("/api/sgf/{id}/{black}_vs_{white}.sgf")
155+
public ResponseEntity<Resource> getSgf(
156+
@PathVariable String id, @PathVariable String black, @PathVariable String white) throws IOException {
157+
int asciiAddOn = 97;
158+
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
159+
Game game = games.get(id);
160+
StringBuilder stringBuilder = new StringBuilder();
161+
if (game.moves() != null) {
162+
stringBuilder.append("(;");
163+
stringBuilder
164+
.append("FF[4]\n")
165+
.append("CA[UTF-8]\n")
166+
.append("GM[1]\n")
167+
.append("DT[" + formatter.format(new Date()) + "]\n")
168+
.append("PC[localhost]\n")
169+
.append("GN[" + game.id() + "]\n")
170+
.append("PB[" + black + "]\n")
171+
.append("PW[" + white + "]\n")
172+
.append("RE[" + (game.gameHasEnded() ? game.getScore() : "?") + "]\n")
173+
.append("SZ[" + game.dim() + "]\n");
174+
for (Move move : game.moves().moves()) {
175+
stringBuilder
176+
.append(";")
177+
.append(Board.getColorFromValue(move.color()))
178+
.append("[")
179+
.append((char) (move.x() + asciiAddOn))
180+
.append((char) (move.y() + asciiAddOn));
181+
if (move == game.getLastMove()) {
182+
stringBuilder
183+
.append("]");
184+
} else {
185+
stringBuilder
186+
.append("]\n");
187+
}
188+
}
189+
stringBuilder.append(")");
190+
}
191+
ByteArrayInputStream bais = new ByteArrayInputStream(stringBuilder.toString().getBytes());
192+
InputStreamResource resource = new InputStreamResource(bais);
193+
194+
return ResponseEntity.ok().contentLength(stringBuilder.length()).contentType(MediaType.TEXT_PLAIN).body(resource);
195+
}
147196
}

src/main/java/com/bernd/game/Board.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,12 @@ public static int[][] removeDeadStonesAround(
111111
}
112112
return result;
113113
}
114+
115+
public static String getColorFromValue(int value) {
116+
if (value == 32) {
117+
return "B";
118+
}
119+
return "W";
120+
}
121+
114122
}

0 commit comments

Comments
 (0)