-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6fbca26
commit 511808e
Showing
8 changed files
with
604 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import { Typography } from "@mui/material"; | ||
import Box from "@mui/material/Box"; | ||
import HashIcon from "@mui/icons-material/NumbersRounded"; | ||
import Button from "@mui/material/Button"; | ||
import Snackbar from "@mui/material/Snackbar"; | ||
import Alert from "@mui/material/Alert"; | ||
import { alpha, useTheme } from "@mui/material/styles"; | ||
import TextField from "components/TextField"; | ||
import { useAppDispatch } from "hooks/useAppDispatch"; | ||
import { useAppSelector } from "hooks/useAppSelector"; | ||
import { FC, useState } from "react"; | ||
import { commentsActions } from "store/slices/commentsSlice"; | ||
import { digitCodeActions } from "store/slices/digitCodeSlice"; | ||
import { registrationActions } from "store/slices/registrationSlice"; | ||
import { roundsActions } from "store/slices/roundsSlice"; | ||
import { parse as parseTuringInfo } from "parsing/turing-copy-paste"; | ||
import { parse as parseProblemBook } from "parsing/problem-book"; | ||
|
||
const PasteRegistration: FC = () => { | ||
const dispatch = useAppDispatch(); | ||
const registration = useAppSelector((state) => state.registration); | ||
const [cardText, setCardText] = useState(""); | ||
const [showNotFound, setShowNotFound] = useState(false); | ||
const theme = useTheme(); | ||
|
||
function onSubmit() { | ||
const problem = parseTuringInfo(cardText) || parseProblemBook(cardText); | ||
console.log(problem); | ||
if (problem === null) { | ||
setShowNotFound(true); | ||
return; | ||
} | ||
dispatch(registrationActions.updateHash(problem.code.toUpperCase())); | ||
dispatch(roundsActions.reset()); | ||
dispatch(commentsActions.reset()); | ||
dispatch(digitCodeActions.reset()); | ||
dispatch(registrationActions.fetchDone()); | ||
dispatch(commentsActions.setCards(problem)); | ||
} | ||
|
||
if (registration.status !== "new") { | ||
return ( | ||
<TextField | ||
prefixId="registration__hash" | ||
disabled={true} | ||
iconRender={<HashIcon />} | ||
value={registration.hash} | ||
maxChars={10} | ||
customRadius={ | ||
registration.status === "ready" | ||
? theme.spacing(0, 0, 2, 2) | ||
: undefined | ||
} | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
<Snackbar | ||
anchorOrigin={{ horizontal: "center", vertical: "bottom" }} | ||
open={showNotFound} | ||
onClose={() => { | ||
setShowNotFound(false); | ||
}} | ||
> | ||
<Alert | ||
onClose={() => { | ||
setShowNotFound(false); | ||
}} | ||
severity="error" | ||
sx={{ width: "100%" }} | ||
variant="filled" | ||
> | ||
Could not parse the game setup. Did you copy&paste the whole setup | ||
from <a href="https://turingmachine.info/">turingmachine.info</a> or | ||
the{" "} | ||
<a href="https://boardgamegeek.com/filepage/251409/book-8500-problems-offline-or-analog-use"> | ||
problem book | ||
</a> | ||
? | ||
</Alert> | ||
</Snackbar> | ||
<form | ||
onSubmit={(e) => { | ||
e.preventDefault(); | ||
onSubmit(); | ||
}} | ||
> | ||
<Alert severity="info"> | ||
You can paste a game setup string in the following text box. Supported | ||
methods are: <br /> | ||
1. You can copy a generated game from{" "} | ||
<a href="https://turingmachine.info/">turingmachine.info</a>. The | ||
copied text needs to include the "#" and all the cards and verifiers. | ||
<br /> | ||
2. You can copy from the{" "} | ||
<a href="https://boardgamegeek.com/filepage/251409/book-8500-problems-offline-or-analog-use"> | ||
problem book | ||
</a> | ||
. Be sure to include the whole problem line. | ||
</Alert> | ||
<Typography>Paste Game Setup</Typography> | ||
<TextField | ||
iconRender={<div />} | ||
value={cardText} | ||
onChange={(value) => { | ||
setCardText(value); | ||
}} | ||
withReset={true} | ||
onReset={() => { | ||
setCardText(""); | ||
}} | ||
/> | ||
|
||
<Box pt={0.5}> | ||
<Button | ||
aria-label="search" | ||
disabled={cardText === ""} | ||
fullWidth | ||
size="large" | ||
type="submit" | ||
sx={(theme) => ({ | ||
background: alpha(theme.palette.primary.main, 0.1), | ||
borderRadius: theme.spacing(0, 0, 2, 2), | ||
fontFamily: "Kalam", | ||
fontSize: 24, | ||
height: theme.spacing(6), | ||
"&:hover": { | ||
background: alpha(theme.palette.primary.main, 0.2), | ||
}, | ||
})} | ||
> | ||
Start Game | ||
</Button> | ||
</Box> | ||
</form> | ||
</> | ||
); | ||
}; | ||
|
||
export default PasteRegistration; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { parse } from "parsing/problem-book"; | ||
|
||
test("C65 6FF P", () => { | ||
expect( | ||
parse("5,#C65 6FF P,->,5,22,24,27,33,48,O252,O536,O658,O213,O613,O289") | ||
).toStrictEqual({ | ||
code: "C656FFP", | ||
color: 1, | ||
ind: [5, 22, 24, 27, 33, 48], | ||
crypt: [252, 536, 658, 213, 613, 289], | ||
m: 0, | ||
}); | ||
}); | ||
|
||
test("F4D EXI", () => { | ||
expect( | ||
parse("10,#F4D EXI,->,25,23,24,16,36,4,42,14,B749,B643,B586,B325") | ||
).toStrictEqual({ | ||
code: "F4DEXI", | ||
color: 2, | ||
ind: [25, 24, 36, 42], | ||
fake: [23, 16, 4, 14], | ||
crypt: [749, 643, 586, 325], | ||
m: 1, | ||
}); | ||
}); | ||
|
||
test("I51 ZKH K", () => { | ||
expect( | ||
parse("4,#I51 ZKH K,->,N23,N24,N25,N41,N48,G681,G746,G440,G350,G771") | ||
).toStrictEqual({ | ||
code: "I51ZKHK", | ||
color: 0, | ||
ind: [23, 24, 25, 41, 48], | ||
crypt: [681, 746, 440, 350, 771], | ||
m: 2, | ||
}); | ||
}); |
102 changes: 102 additions & 0 deletions
102
frontend/src/parsing/__test__/turing-copy-paste.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import { parse } from "parsing/turing-copy-paste"; | ||
|
||
test("A518FRM", () => { | ||
expect( | ||
parse( | ||
`op #A51 8FR M Share Get Criteria and Verification cards in the box. A 1 652 B 7 405 C 12 616 D 15 331 E 16 505 Back to Homepage` | ||
) | ||
).toStrictEqual({ | ||
ind: [1, 7, 12, 15, 16], | ||
crypt: [652, 405, 616, 331, 505], | ||
color: 2, | ||
m: 0, | ||
code: "A518FRM", | ||
}); | ||
}); | ||
|
||
test("A4BL4O", () => { | ||
expect( | ||
parse( | ||
`op #A4B L4O Share Get Criteria and Verification cards in the box. A 5 578 B 10 376 C 11 566 D 17 618 Back to Homepage` | ||
) | ||
).toStrictEqual({ | ||
ind: [5, 10, 11, 17], | ||
crypt: [578, 376, 566, 618], | ||
color: 0, | ||
m: 0, | ||
code: "A4BL4O", | ||
}); | ||
}); | ||
|
||
test("A4BL4O lowercase", () => { | ||
expect( | ||
parse( | ||
`op #A4B L4O Share Get Criteria and Verification cards in the box. A 5 578 B 10 376 C 11 566 D 17 618 Back to Homepage`.toLowerCase() | ||
) | ||
).toStrictEqual({ | ||
ind: [5, 10, 11, 17], | ||
crypt: [578, 376, 566, 618], | ||
color: 0, | ||
m: 0, | ||
code: "A4BL4O", | ||
}); | ||
}); | ||
|
||
test("A4BL4O uppercase", () => { | ||
expect( | ||
parse( | ||
`op #A4B L4O Share Get Criteria and Verification cards in the box. A 5 578 B 10 376 C 11 566 D 17 618 Back to Homepage`.toUpperCase() | ||
) | ||
).toStrictEqual({ | ||
ind: [5, 10, 11, 17], | ||
crypt: [578, 376, 566, 618], | ||
color: 0, | ||
m: 0, | ||
code: "A4BL4O", | ||
}); | ||
}); | ||
|
||
test("C65 6FF P", () => { | ||
expect( | ||
parse( | ||
`op #C65 6FF P Share Get Criteria and Verification cards in the box. A 5 252 B 22 536 C 24 658 D 27 213 E 33 613 F 48 289 Back to Homepage` | ||
) | ||
).toStrictEqual({ | ||
ind: [5, 22, 24, 27, 33, 48], | ||
crypt: [252, 536, 658, 213, 613, 289], | ||
color: 1, | ||
m: 0, | ||
code: "C656FFP", | ||
}); | ||
}); | ||
|
||
test("E52 NBU A", () => { | ||
expect( | ||
parse( | ||
`rulebook page 3 #E52 NBU A Share Get Criteria and Verification cards in the box. a 1721 499 b 2214 296 c 2319 237 d 210 378 e 1815 594 Back t` | ||
) | ||
).toStrictEqual({ | ||
ind: [17, 22, 23, 2, 18], | ||
fake: [21, 14, 19, 10, 15], | ||
crypt: [499, 296, 237, 378, 594], | ||
color: 2, | ||
m: 1, | ||
code: "E52NBUA", | ||
}); | ||
}); | ||
|
||
// | ||
|
||
test("H5K M7S", () => { | ||
expect( | ||
parse( | ||
`Nightmare Mode: see rulebook page 3 #H5K M7S Share Get Criteria and Verification cards in the box. 212171922 A 485 B 537 C 315 D 413 E 614 Back to Homepage` | ||
) | ||
).toStrictEqual({ | ||
ind: [2, 12, 17, 19, 22], | ||
crypt: [485, 537, 315, 413, 614], | ||
color: 0, | ||
m: 2, | ||
code: "H5KM7S", | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { parseCode, getColor, type ParsedGame } from "./util"; | ||
|
||
export function parse(text: string): ParsedGame | null { | ||
const problem = text.split("#")[1]; | ||
if (!problem) { | ||
return null; | ||
} | ||
const hashEnd = problem.indexOf(","); | ||
const code = problem.slice(0, hashEnd).replace(/\s+/g, ""); | ||
const parsedCode = parseCode(code); | ||
if (parsedCode === null) { | ||
return null; | ||
} | ||
const { mode, numVerifiers } = parsedCode; | ||
const cardText = problem.split("->,")[1]; | ||
if (!cardText) { | ||
return null; | ||
} | ||
const cards = cardText.split(","); | ||
if (mode === 0) { | ||
// CLASSIC | ||
const ind = []; | ||
for (let i = 0; i < numVerifiers; i += 1) { | ||
ind.push(Number(cards[i])); | ||
} | ||
const crypt = []; | ||
for (let i = numVerifiers; i < numVerifiers * 2; i += 1) { | ||
crypt.push(Number(cards[i].slice(1))); | ||
} | ||
const color = getColor(crypt[0]); | ||
if (color === null) { | ||
return null; | ||
} | ||
return { ind, m: mode, crypt, code, color }; | ||
} else if (mode === 1) { | ||
// EXTREME | ||
const ind = []; | ||
const fake = []; | ||
for (let i = 0; i < numVerifiers * 2; i += 2) { | ||
ind.push(Number(cards[i])); | ||
fake.push(Number(cards[i + 1])); | ||
} | ||
const crypt = []; | ||
for (let i = numVerifiers * 2; i < numVerifiers * 3; i += 1) { | ||
crypt.push(Number(cards[i].slice(1))); | ||
} | ||
const color = getColor(crypt[0]); | ||
if (color === null) { | ||
return null; | ||
} | ||
return { ind, fake, m: mode, crypt, code, color }; | ||
} else if (mode === 2) { | ||
// NIGHTMARE | ||
const ind = []; | ||
for (let i = 0; i < numVerifiers; i += 1) { | ||
ind.push(Number(cards[i].slice(1))); | ||
} | ||
const crypt = []; | ||
for (let i = numVerifiers; i < numVerifiers * 2; i += 1) { | ||
crypt.push(Number(cards[i].slice(1))); | ||
} | ||
const color = getColor(crypt[0]); | ||
if (color === null) { | ||
return null; | ||
} | ||
return { ind, m: mode, crypt, code, color }; | ||
} else { | ||
return null; | ||
} | ||
} |
Oops, something went wrong.