diff --git a/Makefile b/Makefile index 50fa4b0..ba17302 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ check-format: .PHONY: watch watch: - pnpm run -r watch + pnpm run --parallel -r watch .PHONY: dev dev: diff --git a/game/package.json b/game/package.json index 55f7411..2344a7c 100644 --- a/game/package.json +++ b/game/package.json @@ -18,8 +18,8 @@ "test": "pnpm vitest run src" }, "dependencies": { - "@lefun/core": "1.4.0", - "@lefun/game": "1.4.0", + "@lefun/core": "1.5.0", + "@lefun/game": "1.5.0", "lodash-es": "^4.17.21" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bccbf04..f1deb7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,11 +18,11 @@ importers: game: dependencies: '@lefun/core': - specifier: 1.4.0 - version: 1.4.0 + specifier: 1.5.0 + version: 1.5.0 '@lefun/game': - specifier: 1.4.0 - version: 1.4.0(@lefun/core@1.4.0) + specifier: 1.5.0 + version: 1.5.0(@lefun/core@1.5.0) lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -86,20 +86,20 @@ importers: specifier: ^7.24.7 version: 7.24.7(@babel/core@7.24.7) '@lefun/core': - specifier: ^1.4.0 - version: 1.4.0 + specifier: ^1.5.0 + version: 1.5.0 '@lefun/dev-server': - specifier: ^1.4.0 - version: 1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@lefun/ui@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.5.0 + version: 1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@lefun/ui@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@lefun/game': - specifier: ^1.4.0 - version: 1.4.0(@lefun/core@1.4.0) + specifier: ^1.5.0 + version: 1.5.0(@lefun/core@1.5.0) '@lefun/ui': - specifier: ^1.4.0 - version: 1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.5.0 + version: 1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@lefun/ui-testing': - specifier: ^1.4.0 - version: 1.4.0(@lefun/ui@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@lingui/core@4.11.2)(@lingui/react@4.11.1(react@18.3.1))(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^1.5.0 + version: 1.5.0(@lefun/ui@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@lingui/core@4.11.2)(@lingui/react@4.11.1(react@18.3.1))(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@lingui/cli': specifier: ^4.11.1 version: 4.11.1(typescript@5.4.5) @@ -683,37 +683,37 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@lefun/core@1.4.0': - resolution: {integrity: sha512-nqGk38F6L6dsZck5Up2ZcOsgVakTYIc8FiGHAt9OWR1JrgTn9xprTQj6/YG4KvZ34+tK2miGB8HEBzXu96LAmw==} + '@lefun/core@1.5.0': + resolution: {integrity: sha512-ksqPKpmChEsABJB3KGwzNpr8vH3oyEP9v5N4fCswdVAMfK00GN1O6UjkJgI04JLefY+DLOpYaG5N7xrzdEl40Q==} - '@lefun/dev-server@1.4.0': - resolution: {integrity: sha512-Fy6lu5xVmTV0Pw+k1zCybcoRzofDZlPA4/9ne1Ub0wlRpFITelyVsHDck4slW43v8dWjRr/dOYmho2DJWIZlNg==} + '@lefun/dev-server@1.5.0': + resolution: {integrity: sha512-QJZdZYOG+BWgdwN7y/6iszlS19K0TU4vmNxlp1QHFyAmOWq9etZMaL1o96zzaCw/jipHVchEACAKcZX0m/VFNA==} peerDependencies: - '@lefun/core': 1.4.0 - '@lefun/game': 1.4.0 - '@lefun/ui': 1.4.0 + '@lefun/core': 1.5.0 + '@lefun/game': 1.5.0 + '@lefun/ui': 1.5.0 react: '>=17.0.2' react-dom: '>=17.0.2' - '@lefun/game@1.4.0': - resolution: {integrity: sha512-ASRYY3bx7lzA8rH4N/4YETfwlPm+q5dJ7F6U0RPmGEdmTCb0YEJQT/E5vQGmw/FDSmOTTQKkSC+FobluPyZP1g==} + '@lefun/game@1.5.0': + resolution: {integrity: sha512-SgljHumLdTrRVeOv5K/thvxxomO29Onq8k+K1zGRfUx7nmVh0Mo5IxPROsCYwG0VwJocOoebNhKA3O3dclfehQ==} peerDependencies: - '@lefun/core': 1.4.0 + '@lefun/core': 1.5.0 - '@lefun/ui-testing@1.4.0': - resolution: {integrity: sha512-jcd6cjXH4q8tlKNRVImjoeKthPk5GUZ9RUtdFkP7EDaJhmUU+S4gS33glPIg3lC+FObuOEZTpUB1MevQWXfrCg==} + '@lefun/ui-testing@1.5.0': + resolution: {integrity: sha512-9D80aKRqJg7C+SM2ghgK5orNOx9Kj+RfajRGVb3dlWT5kk6GlKaZ90/ozCcfCsgDsCOzk9yXR919XhjcMZBLPw==} peerDependencies: - '@lefun/ui': 1.4.0 + '@lefun/ui': 1.5.0 '@lingui/core': ^4.7.1 '@lingui/react': ^4.7.1 react: '>=17.0.2' react-dom: '>=17.0.2' - '@lefun/ui@1.4.0': - resolution: {integrity: sha512-WThSp92bf8Q0ISmw8qsBIgcF6pCJCY+OJuD8WPQQKwb87KKHRD/lLjplu6rXohjOCHXpb06h27yQceva+Tx0TA==} + '@lefun/ui@1.5.0': + resolution: {integrity: sha512-BJs91Fd+EMdC7W2b+CQdLi1HydRqSsIk4pvrzEUXq0v87l6n0qrzMXQRBv3c0aKQk/LI8fxYCrd7FEnjg+ycqA==} peerDependencies: - '@lefun/core': 1.4.0 - '@lefun/game': 1.4.0 + '@lefun/core': 1.5.0 + '@lefun/game': 1.5.0 react: '>=17.0.2' react-dom: '>=17.0.2' @@ -3582,13 +3582,13 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@lefun/core@1.4.0': {} + '@lefun/core@1.5.0': {} - '@lefun/dev-server@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@lefun/ui@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@lefun/dev-server@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@lefun/ui@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@lefun/core': 1.4.0 - '@lefun/game': 1.4.0(@lefun/core@1.4.0) - '@lefun/ui': 1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@lefun/core': 1.5.0 + '@lefun/game': 1.5.0(@lefun/core@1.5.0) + '@lefun/ui': 1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@lingui/core': 4.11.2 '@lingui/react': 4.11.1(react@18.3.1) classnames: 2.5.1 @@ -3600,14 +3600,14 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@lefun/game@1.4.0(@lefun/core@1.4.0)': + '@lefun/game@1.5.0(@lefun/core@1.5.0)': dependencies: - '@lefun/core': 1.4.0 + '@lefun/core': 1.5.0 lodash-es: 4.17.21 - '@lefun/ui-testing@1.4.0(@lefun/ui@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@lingui/core@4.11.2)(@lingui/react@4.11.1(react@18.3.1))(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@lefun/ui-testing@1.5.0(@lefun/ui@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@lingui/core@4.11.2)(@lingui/react@4.11.1(react@18.3.1))(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@lefun/ui': 1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@lefun/ui': 1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@lingui/core': 4.11.2 '@lingui/react': 4.11.1(react@18.3.1) '@testing-library/react': 16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -3620,10 +3620,10 @@ snapshots: - '@types/react-dom' - immer - '@lefun/ui@1.4.0(@lefun/core@1.4.0)(@lefun/game@1.4.0(@lefun/core@1.4.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@lefun/ui@1.5.0(@lefun/core@1.5.0)(@lefun/game@1.5.0(@lefun/core@1.5.0))(@types/react@18.3.3)(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@lefun/core': 1.4.0 - '@lefun/game': 1.4.0(@lefun/core@1.4.0) + '@lefun/core': 1.5.0 + '@lefun/game': 1.5.0(@lefun/core@1.5.0) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) zustand: 4.5.4(@types/react@18.3.3)(immer@10.1.1)(react@18.3.1) diff --git a/ui/package.json b/ui/package.json index 9393d3c..1ddd0f3 100644 --- a/ui/package.json +++ b/ui/package.json @@ -26,11 +26,11 @@ }, "devDependencies": { "@babel/preset-react": "^7.24.7", - "@lefun/core": "^1.4.0", - "@lefun/dev-server": "^1.4.0", - "@lefun/game": "^1.4.0", - "@lefun/ui": "^1.4.0", - "@lefun/ui-testing": "^1.4.0", + "@lefun/core": "^1.5.0", + "@lefun/dev-server": "^1.5.0", + "@lefun/game": "^1.5.0", + "@lefun/ui": "^1.5.0", + "@lefun/ui-testing": "^1.5.0", "@lingui/cli": "^4.11.1", "@lingui/conf": "^4.11.1", "@lingui/macro": "^4.11.1", diff --git a/ui/src/Board.tsx b/ui/src/Board.tsx index 6063374..b79e466 100644 --- a/ui/src/Board.tsx +++ b/ui/src/Board.tsx @@ -2,12 +2,7 @@ import "tippy.js/dist/tippy.css"; import { msg, Trans } from "@lingui/macro"; import { useLingui } from "@lingui/react"; -import { - animated, - config as springConfig, - useSpring, - useTransition, -} from "@react-spring/web"; +import { animated, config as springConfig, useSpring } from "@react-spring/web"; import Tippy from "@tippyjs/react"; import classNames from "classnames"; import { ReactNode, useEffect, useState } from "react"; @@ -31,27 +26,13 @@ import { } from "dudo-game"; import { Die } from "./Die"; +import { useFonts } from "./hooks"; import { iAmAliveSelector, iHaveRolledSelector, itsMyTurnSelector, } from "./selectors"; -const useSetFont = () => { - // Add the google font. This is a bit hacky but we have no other way to control the - // "outer" HTML. - useEffect(() => { - const parent = document.getElementsByTagName("head")[0]; - parent.insertAdjacentHTML( - "beforeend", - ` - - - `, - ); - }, []); -}; - type PlayerColor = { text: string; bg: string; @@ -472,36 +453,33 @@ const WildsInfo = () => { palifico && (step === "play" || (step === "revealed" && (!iHaveRolled || !iAmAlive))); - const palificoTrans = useTransition(shouldSeePalifico, { + const style = useSpring({ + opacity: shouldSeePalifico ? 1 : 0, + transform: shouldSeePalifico + ? "scale(1) rotate(-5deg)" + : "scale(0) rotate(12deg)", + immediate: !shouldSeePalifico, config: { - tension: 200, - friction: 22, - clamp: true, + tension: 500, + friction: 12, + precision: 0.02, }, - from: { opacity: 0, transform: "scale(4) rotate(12deg)" }, - enter: { opacity: 1, transform: "scale(1) rotate(-5deg)" }, - leave: { opacity: 0 }, }); return (
- {palificoTrans( - (style, item) => - item && ( -
- {/* absolute so that it doesn't influence the height of the container. */} -
- - - -
-
- ), - )} -
+
+ {/* absolute so that it doesn't influence the height of the container. */} +
+ + + +
+
+
{shouldSeePalifico ? ( @@ -867,7 +845,7 @@ const Header = () => { }; const Board = () => { - useSetFont(); + useFonts(); const playerOrder = useSelectorShallow((state) => { return state.board.playerOrder; @@ -893,13 +871,13 @@ const Board = () => { `} >
-
+
{playerOrder.map((u) => ( ))}
-
+
diff --git a/ui/src/Rules.tsx b/ui/src/Rules.tsx index 9707e48..ac83b17 100644 --- a/ui/src/Rules.tsx +++ b/ui/src/Rules.tsx @@ -1,7 +1,9 @@ +import { Trans } from "@lingui/macro"; import classNames from "classnames"; import { ReactNode } from "react"; import { Die as _Die } from "./Die"; +import { useFonts } from "./hooks"; const Die = ({ value }: { value: number }) => { return ( @@ -12,7 +14,7 @@ const Die = ({ value }: { value: number }) => { }; const Dudo = () => { - return ; + return ; }; const Increase = ({ @@ -61,84 +63,149 @@ const Arrow = ({ className = "" }: { className?: string }) => { }; const Rules = () => { + useFonts(); + return ( -
-

Rules of Dudo

-

Overview

-

- Each player starts with a set number of dice, hidden from the other - players. -

-

- The first player makes a bid about how many dice of a certain value are - showing among all players, at a minimum. Ones () - are wild. For example, a bid of 5 is a claim - that between all players, there are at least 5{" "} - or . -

-

- The next player must either raise the bid or call . -

-

- Calling ends the round. If the bidder's claim is met, the - player who called loses one die. If not, then the bidder loses - one die. The loosing player starts the next round. -

-

Raising the bid

-

The player raising must

-
    -
  • Increase the quantity and/or the value of the dice.
  • -
  • Not lower the quantity of dice.
  • -
-
-
-

Valid raises

-

-

-
- - - -
-
-

-
-
-
-

Invalid raises

+
+

+ Rules of Dudo +

+
+

+ Overview +

+

+ The game is played over several rounds. +

+

+ + Each round, all the players roll their dice, hiding the result from + the other players. + +

+

+ + The first player makes a bid about how many dice of a certain value + are showing among all players, at a minimum. Ones ( + ) are wild. For example, a bid of 5{" "} + is a claim that between all players, there are{" "} + at least 5 or . + +

+

+ + The next player must either raise the bid or call . + +

+

+ + Calling ends the round. If the bidder's claim is met, the + player who called loses one die. If not, then the bidder + loses one die. The loosing player starts the next round. + +

+
+
+

+ Raising the bid +

+

+ The player raising must +

+
    +
  • + Increase the quantity and/or the value of the dice. +
  • +
  • + Not lower the quantity of dice. +
  • +
+
+
+

+ Valid raises +

- - - + + +

+
+
+
+

+ Invalid raises +

+

+

+
+ + + +
+
+

+
-
-

Bidding wilds

-

- You can also bid the total number of . When doing so, - you can halve (rounded up) the number of dice of a non-wild bid. You can - go back to a non-wild bid by doubling and adding one to the quantity of - dice. -

-

Valid raises

-

-

- - - - -
-

-

End of the game

-

- Once you have lost all your dice, you are eliminated. The last player - left wins. -

+ +
+

+ Bidding wilds +

+

+ + You can also bid the total number of . When doing + so, you can halve (rounded up) the number of dice of a non-wild bid. + You can go back to a non-wild bid by doubling and adding one to the + quantity of dice. + +

+
+

+ Valid raises +

+

+

+ + + + +
+

+
+
+
+

¡Palifico!

+

+ + When a player has only 1 die left, they start a Palifico{" "} + round. In that round, only players with 1 die left can change the{" "} + value of the dice in the bid. + +

+

+ + There needs to be at least 3 players remaining for Palifico to take + effect. + +

+
+
+

+ End of the game +

+

+ + Once you have lost all your dice, you are eliminated. The last + player left wins. + +

+
); }; diff --git a/ui/src/hooks.ts b/ui/src/hooks.ts new file mode 100644 index 0000000..5a59265 --- /dev/null +++ b/ui/src/hooks.ts @@ -0,0 +1,16 @@ +import { useEffect } from "react"; + +export const useFonts = () => { + // Add the google font. This is a bit hacky but we have no other way to control the + // "outer" HTML. + useEffect(() => { + const parent = document.getElementsByTagName("head")[0]; + parent.insertAdjacentHTML( + "beforeend", + ` + + + `, + ); + }, []); +}; diff --git a/ui/src/index.css b/ui/src/index.css index e7abebb..00b998f 100644 --- a/ui/src/index.css +++ b/ui/src/index.css @@ -10,6 +10,12 @@ html { @apply tracking-wide; } +html, +body, +#home { + @apply h-full w-full; +} + :root { --die-size: min( /* how much horizontal space is there */ calc(50vw / var(--num-dice)), @@ -36,7 +42,7 @@ html { width: min(5rem, 40%); } -@layer components { +@layer base { button { cursor: pointer; @apply rounded-lg p-2 bg-gray-200 border-2 border-gray-500 shadow select-none; @@ -60,3 +66,42 @@ html { .manipulation { touch-action: manipulation; } + +.rules { + @apply px-2 sm:px-6 pb-12; + @apply text-gray-700; + font-size: 19px; + font-family: sans-serif; + + button { + font-family: "Hammersmith One", sans-serif; + } + + h1 { + @apply text-3xl; + @apply text-blue-800; + @apply pt-16; + @apply font-semibold; + } + + h2 { + @apply text-2xl; + @apply text-blue-900; + @apply pt-8; + @apply font-medium; + } + + h3 { + @apply text-lg; + @apply text-blue-900; + @apply pt-4; + @apply font-medium; + } + + p, + .paragraph { + @apply ml-0.5; + @apply pt-4; + @apply text-justify; + } +} diff --git a/ui/src/locales/en/messages.po b/ui/src/locales/en/messages.po index 2863af8..921236a 100644 --- a/ui/src/locales/en/messages.po +++ b/ui/src/locales/en/messages.po @@ -140,6 +140,30 @@ msgstr "<0>You lost one die" msgid "Bet" msgstr "Bet" +#: src/Rules.tsx +msgid "Bidding wilds" +msgstr "Bidding wilds" + +#: src/Rules.tsx +msgid "Calling <0/> ends the round. If the bidder's claim is met, the player who called <1/> loses one die. If not, then the bidder loses one die. The loosing player starts the next round." +msgstr "Calling <0/> ends the round. If the bidder's claim is met, the player who called <1/> loses one die; if not, then the bidder loses one die. The loosing player starts the next round." + +#: src/Rules.tsx +msgid "Each round, all the players roll their dice, hiding the result from the other players." +msgstr "Each round, the players roll their dice, hiding the result from the other players." + +#: src/Rules.tsx +msgid "End of the game" +msgstr "End of the game" + +#: src/Rules.tsx +msgid "Increase the quantity and/or the value of the dice." +msgstr "Increase the quantity and/or the value of the dice." + +#: src/Rules.tsx +msgid "Invalid raises" +msgstr "Invalid raises" + #: src/Board.tsx msgid "It's your turn!" msgstr "It's your turn!" @@ -148,14 +172,59 @@ msgstr "It's your turn!" msgid "No wilds. Only players with 1 die left can change the value of the dice." msgstr "No wilds. Only players with 1 die left can change the value of the dice." +#: src/Rules.tsx +msgid "Not lower the quantity of dice." +msgstr "Not lower the quantity of dice." + +#: src/Rules.tsx +msgid "Once you have lost all your dice, you are eliminated. The last player left wins." +msgstr "Players with no dice left are eliminated. The last player left wins." + +#: src/Rules.tsx +msgid "Overview" +msgstr "Overview" + +#: src/Rules.tsx +msgid "Raising the bid" +msgstr "Raising the bid" + #: src/Board.tsx msgid "Roll" msgstr "Roll" +#: src/Rules.tsx +msgid "Rules of Dudo" +msgstr "Rules of Dudo" + +#: src/Rules.tsx +msgid "The first player makes a bid about how many dice of a certain value are showing <0>among all players, at a minimum. Ones (<1/>) are wild. For example, a bid of <2>5 <3/> is a claim that between all players, there are <4>at least <5>5 <6/> or <7/>." +msgstr "Taking turns, players make bids about how many dice of a certain value are showing <0>among all players. 1s (<1/>) are wild, meaning they can count as any value. For example, a bid of <2>5 <3/> is a claim that between all players, there are <4>at least <5>5 <6/> or <7/>." + +#: src/Rules.tsx +msgid "The game is played over several rounds." +msgstr "The game is played over several rounds." + +#: src/Rules.tsx +msgid "The next player must either raise the bid or call <0/>." +msgstr "Players must raise the previous bid or call <0/>." + +#: src/Rules.tsx +msgid "The player raising must" +msgstr "The player raising must" + +#: src/Rules.tsx +msgid "There needs to be at least 3 players remaining for Palifico to take effect." +msgstr "There needs to be at least 3 players remaining for Palifico to take effect." + #: src/Board.tsx msgid "Total" msgstr "Total" +#: src/Rules.tsx +#: src/Rules.tsx +msgid "Valid raises" +msgstr "Valid raises" + #: src/Board.tsx msgid "Waiting for <0>{username} to roll" msgstr "Waiting for <0>{username} to roll" @@ -163,3 +232,11 @@ msgstr "Waiting for <0>{username} to roll" #: src/Board.tsx msgid "Waiting for everyone to roll..." msgstr "Waiting for everyone to roll..." + +#: src/Rules.tsx +msgid "When a player has only 1 die left, they start a <0>Palifico round. In that round, only players with 1 die left can change the <1>value of the dice in the bid." +msgstr "When a player has only 1 die left, they start a <0>Palifico round. In that round, only players with 1 die left can change the <1>value of the dice in the bid." + +#: src/Rules.tsx +msgid "You can also bid the total number of <0/>. When doing so, you can halve (rounded up) the number of dice of a non-wild bid. You can go back to a non-wild bid by doubling and adding one to the quantity of dice." +msgstr "Players can also bid the total number of <0/>. When doing so, they can halve (rounded up) the number of dice of a non-wild bid. One can go back to a non-wild bid by doubling and adding one to the quantity of dice." diff --git a/ui/src/locales/fr/messages.po b/ui/src/locales/fr/messages.po index e7ada16..8970087 100644 --- a/ui/src/locales/fr/messages.po +++ b/ui/src/locales/fr/messages.po @@ -140,6 +140,30 @@ msgstr "<0>Vous avez perdu un dé" msgid "Bet" msgstr "Miser" +#: src/Rules.tsx +msgid "Bidding wilds" +msgstr "Miser les frimes" + +#: src/Rules.tsx +msgid "Calling <0/> ends the round. If the bidder's claim is met, the player who called <1/> loses one die. If not, then the bidder loses one die. The loosing player starts the next round." +msgstr "Annoncer <0/> met fin à la ronde. Si la mise du joueur précédent est confirmée, le joueur qui a annoncé <1/> perd un dé ; sinon, c'est le joueur qui a fait la mise erronée qui perd un dé. Le perdant commence la ronde suivante." + +#: src/Rules.tsx +msgid "Each round, all the players roll their dice, hiding the result from the other players." +msgstr "À chaque ronde, les joueurs roulent leurs dés, tout en dissimulant le résultat aux autres joueurs." + +#: src/Rules.tsx +msgid "End of the game" +msgstr "Fin de la partie" + +#: src/Rules.tsx +msgid "Increase the quantity and/or the value of the dice." +msgstr "Augmenter la quantité et/ou la valeur des dés." + +#: src/Rules.tsx +msgid "Invalid raises" +msgstr "Mises invalides" + #: src/Board.tsx msgid "It's your turn!" msgstr "C'est votre tour!" @@ -148,14 +172,59 @@ msgstr "C'est votre tour!" msgid "No wilds. Only players with 1 die left can change the value of the dice." msgstr "Aucune frime. Seuls les joueurs avec 1 dé restant peuvent changer la valeur des dés." +#: src/Rules.tsx +msgid "Not lower the quantity of dice." +msgstr "Ne pas réduire le nombre de dés." + +#: src/Rules.tsx +msgid "Once you have lost all your dice, you are eliminated. The last player left wins." +msgstr "Un joueur est éliminé du jeu lorsqu'il n'a plus de dés. Le dernier joueur restant gagne." + +#: src/Rules.tsx +msgid "Overview" +msgstr "Aperçu" + +#: src/Rules.tsx +msgid "Raising the bid" +msgstr "Augmenter la mise" + #: src/Board.tsx msgid "Roll" msgstr "Lancer les dés" +#: src/Rules.tsx +msgid "Rules of Dudo" +msgstr "Règles de Dudo" + +#: src/Rules.tsx +msgid "The first player makes a bid about how many dice of a certain value are showing <0>among all players, at a minimum. Ones (<1/>) are wild. For example, a bid of <2>5 <3/> is a claim that between all players, there are <4>at least <5>5 <6/> or <7/>." +msgstr "À tour de rôle, les joueurs misent sur le nombre de dés d'une certaine valeur qui doivent être présents <0>parmi tous les joueurs. Les 1 (<1/>) sont frimés, c'est-à-dire qu'ils peuvent prendre n'importe quelle valeur. Par exemple, une mise de <2>5 <3/> signifie qu'entre tous les joueurs, il y en a <4>au moins <5>5 <6/> ou <7/>." + +#: src/Rules.tsx +msgid "The game is played over several rounds." +msgstr "Une partie se déroule sur plusieurs rondes." + +#: src/Rules.tsx +msgid "The next player must either raise the bid or call <0/>." +msgstr "Les joueurs doivent augmenter la mise précédente ou la contester en annonçant <0/>." + +#: src/Rules.tsx +msgid "The player raising must" +msgstr "Le joueur qui augmente la mise doit" + +#: src/Rules.tsx +msgid "There needs to be at least 3 players remaining for Palifico to take effect." +msgstr "Il doit y avoir au moins 3 joueurs restants pour que Palifico soit activé." + #: src/Board.tsx msgid "Total" msgstr "Total" +#: src/Rules.tsx +#: src/Rules.tsx +msgid "Valid raises" +msgstr "Mises valides" + #: src/Board.tsx msgid "Waiting for <0>{username} to roll" msgstr "<0>{username} doit lancer les dés" @@ -163,3 +232,11 @@ msgstr "<0>{username} doit lancer les dés" #: src/Board.tsx msgid "Waiting for everyone to roll..." msgstr "Tous les joueurs doivent lancer les dé..." + +#: src/Rules.tsx +msgid "When a player has only 1 die left, they start a <0>Palifico round. In that round, only players with 1 die left can change the <1>value of the dice in the bid." +msgstr "Lorsqu'un joueur n'a plus qu'un dé restant, il commence alors une ronde <0>Palifico. Dans cette ronde, seuls les joueurs avec 1 dé restant peuvent changer la <1>valeur des dés de la mise." + +#: src/Rules.tsx +msgid "You can also bid the total number of <0/>. When doing so, you can halve (rounded up) the number of dice of a non-wild bid. You can go back to a non-wild bid by doubling and adding one to the quantity of dice." +msgstr "Un joueur peut également miser sur le nombre total de <0/>. Ce faisant, il peut diviser par 2 (arrondi à la hausse) le nombre de dés de la mise précédente avec frimes. On peut revenir à une enchère avec frimes en doublant, plus 1, la quantité de dés." diff --git a/ui/src/main.tsx b/ui/src/main.tsx index c082b8b..db4d6f3 100644 --- a/ui/src/main.tsx +++ b/ui/src/main.tsx @@ -13,6 +13,12 @@ render({ const { default: Board } = await import("./Board"); return ; }, + rules: async () => { + // @ts-expect-error the import is there even if TS does not see it! + await import("./index.css"); + const { default: Rules } = await import("./Rules"); + return ; + }, gameDef: game, matchSettings: { startNumDice: "3" }, messages: { en, fr }, diff --git a/ui/tailwind.config.cjs b/ui/tailwind.config.cjs index 5330fc3..24e0bdb 100644 --- a/ui/tailwind.config.cjs +++ b/ui/tailwind.config.cjs @@ -4,6 +4,7 @@ const sm = "576px"; const md = "768px"; const units = { + 0: "0", auto: "auto", 0.5: "0.125rem", 1: "0.25rem",