Changed all occurrences of 'yahtzee' to 'superkadi', allowed the gameboards to be hydrated by JSON data upon instantiation (also after).
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import {ScoreCellValue} from "./ScoreCell";
|
||||
import ScoreBlock, {createBlockFromDef, BlockState, ScoreBlockJSONRepresentation} from "./ScoreBlock";
|
||||
import {BlockDef, GameSchema} from "../static/rulesets";
|
||||
import {BlockDef, Ruleset, CellFlag} from "../../../shared/rulesets";
|
||||
import { Memento, Originator } from "./Caretaker";
|
||||
import {CellFlag} from "../static/enums";
|
||||
|
||||
export type CellLocation = { blockId: string, cellId: string };
|
||||
|
||||
@@ -10,9 +9,23 @@ class PlayerScoreCard implements Originator {
|
||||
private readonly playerId: string;
|
||||
private readonly blocks: ScoreBlock[];
|
||||
|
||||
constructor(playerId: string, gameSchema: GameSchema) {
|
||||
this.playerId = playerId;
|
||||
this.blocks = PlayerScoreCard.generateBlocks(gameSchema.blocks);
|
||||
constructor(jsonRep: PlayerScoreCardJSONRepresentation, gameSchema: Ruleset);
|
||||
constructor(playerId: string, gameSchema: Ruleset)
|
||||
constructor(...args: any[]) {
|
||||
this.blocks = PlayerScoreCard.generateBlocks(args[1].blocks);
|
||||
if (typeof args[0] === "string") {
|
||||
this.playerId = args[0];
|
||||
}
|
||||
else {
|
||||
this.playerId = (args[0] as PlayerScoreCardJSONRepresentation).playerId;
|
||||
this.restoreFromJSON(args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private restoreFromJSON(jsonRep: PlayerScoreCardJSONRepresentation): void {
|
||||
for (const block of this.blocks) {
|
||||
block.restoreFromJSON(jsonRep.blocks[block.getId()]);
|
||||
}
|
||||
}
|
||||
|
||||
private static generateBlocks(blockDefs: Record<string, BlockDef>): ScoreBlock[] {
|
||||
@@ -97,9 +110,9 @@ class PlayerScoreCard implements Originator {
|
||||
getJSONRepresentation(): PlayerScoreCardJSONRepresentation {
|
||||
const JSONRepresentation: PlayerScoreCardJSONRepresentation = {
|
||||
playerId: this.playerId,
|
||||
blocks: []
|
||||
blocks: {}
|
||||
};
|
||||
this.blocks.forEach(block => JSONRepresentation.blocks.push(block.getJSONRepresentation()));
|
||||
this.blocks.forEach(block => JSONRepresentation.blocks[block.getId()] = block.getJSONRepresentation());
|
||||
return JSONRepresentation;
|
||||
}
|
||||
}
|
||||
@@ -110,7 +123,7 @@ interface PlayerScoreCardState {
|
||||
|
||||
export interface PlayerScoreCardJSONRepresentation {
|
||||
playerId: string;
|
||||
blocks: ScoreBlockJSONRepresentation[];
|
||||
blocks: Record<string, ScoreBlockJSONRepresentation>;
|
||||
}
|
||||
|
||||
class PlayerScoreCardMemento implements Memento {
|
||||
|
||||
@@ -4,8 +4,7 @@ import ScoreCell, {
|
||||
CellState,
|
||||
ScoreCellJSONRepresentation
|
||||
} from "./ScoreCell";
|
||||
import {CellDef, BlockDef, BonusBlockDef, NoBonusBlockDef } from "../static/rulesets";
|
||||
import {CellFlag} from "../static/enums";
|
||||
import {CellDef, BlockDef, BonusBlockDef, NoBonusBlockDef, CellFlag } from "../../../shared/rulesets";
|
||||
|
||||
export const createBlockFromDef = (blockId: string, blockDef: BlockDef) : ScoreBlock => {
|
||||
if (blockDef.hasBonus) {
|
||||
@@ -22,8 +21,7 @@ export interface BlockState {
|
||||
}
|
||||
|
||||
export interface ScoreBlockJSONRepresentation {
|
||||
id: string;
|
||||
cells: ScoreCellJSONRepresentation[];
|
||||
cells: Record<string, ScoreCellJSONRepresentation>;
|
||||
}
|
||||
|
||||
abstract class ScoreBlock {
|
||||
@@ -108,12 +106,17 @@ abstract class ScoreBlock {
|
||||
|
||||
getJSONRepresentation(): ScoreBlockJSONRepresentation {
|
||||
const JSONRepresentation: ScoreBlockJSONRepresentation = {
|
||||
id: this.id,
|
||||
cells: []
|
||||
cells: {}
|
||||
};
|
||||
this.cells.forEach(cell => JSONRepresentation.cells.push(cell.getJSONRepresentation()));
|
||||
this.cells.forEach(cell => JSONRepresentation.cells[cell.getId()] = cell.getJSONRepresentation());
|
||||
return JSONRepresentation;
|
||||
}
|
||||
|
||||
restoreFromJSON(jsonRep: ScoreBlockJSONRepresentation): void {
|
||||
for (const cell of this.cells) {
|
||||
cell.restoreFromJSON(jsonRep.cells[cell.getId()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ScoreBlockWithBonus extends ScoreBlock {
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import {CellFlag, FieldType} from "../static/enums";
|
||||
import {BoolCellDef, CellDef, MultiplierCellDef, NumberCellDef, YahtzeeCellDef} from "../static/rulesets"
|
||||
import {
|
||||
BoolCellDef,
|
||||
CellDef,
|
||||
CellFlag,
|
||||
FieldType,
|
||||
MultiplierCellDef,
|
||||
NumberCellDef,
|
||||
SuperkadiCellDef
|
||||
} from "../../../shared/rulesets";
|
||||
|
||||
export const createCellFromDef = (cellId: string, cellDef: CellDef) : ScoreCell => {
|
||||
export const createCellFromDef = (cellId: string, cellDef: CellDef): ScoreCell => {
|
||||
switch (cellDef.fieldType) {
|
||||
case FieldType.number:
|
||||
return new NumberScoreCell(cellId, cellDef);
|
||||
@@ -9,8 +16,8 @@ export const createCellFromDef = (cellId: string, cellDef: CellDef) : ScoreCell
|
||||
return new BoolScoreCell(cellId, cellDef);
|
||||
case FieldType.multiplier:
|
||||
return new MultiplierScoreCell(cellId, cellDef);
|
||||
case FieldType.yahtzee:
|
||||
return new YahtzeeScoreCell(cellId, cellDef);
|
||||
case FieldType.superkadi:
|
||||
return new SuperkadiScoreCell(cellId, cellDef);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24,7 +31,6 @@ export interface CellState {
|
||||
}
|
||||
|
||||
export interface ScoreCellJSONRepresentation {
|
||||
id: string;
|
||||
value: number | boolean | CellFlag.strike;
|
||||
}
|
||||
|
||||
@@ -79,7 +85,11 @@ abstract class ScoreCell {
|
||||
}
|
||||
|
||||
getJSONRepresentation(): ScoreCellJSONRepresentation {
|
||||
return { id: this.id, value: this.isStruck() ? CellFlag.strike : this.value };
|
||||
return { value: this.isStruck() ? CellFlag.strike : this.value };
|
||||
}
|
||||
|
||||
restoreFromJSON(jsonRep: ScoreCellJSONRepresentation): void {
|
||||
this.update(jsonRep.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,17 +212,17 @@ class BoolScoreCell extends IterableScoreCell {
|
||||
}
|
||||
}
|
||||
|
||||
class YahtzeeScoreCell extends IterableScoreCell {
|
||||
protected static readonly fieldType = FieldType.yahtzee;
|
||||
class SuperkadiScoreCell extends IterableScoreCell {
|
||||
protected static readonly fieldType = FieldType.superkadi;
|
||||
private readonly score: number;
|
||||
protected value: number;
|
||||
|
||||
constructor(cellId: string, cellDef: YahtzeeCellDef) {
|
||||
constructor(cellId: string, cellDef: SuperkadiCellDef) {
|
||||
super(cellId, cellDef);
|
||||
this.score = cellDef.score;
|
||||
this.value = 0;
|
||||
|
||||
for (let i = 0; i <= cellDef.maxYahtzees; i++) {
|
||||
for (let i = 0; i <= cellDef.maxSuperkadis; i++) {
|
||||
this.iteratedSequence.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {ReactNode} from "react";
|
||||
import KadiCell from "./KadiCell";
|
||||
import {FieldType} from "../static/enums";
|
||||
import {CellScores} from "./KadiBoard";
|
||||
import {FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface KadiBlockBonusRowProps {
|
||||
blockId: string;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import {BlockDef} from "../static/rulesets";
|
||||
import {CellLocation} from "../Classes/PlayerScoreCard";
|
||||
import React, {ReactElement} from "react";
|
||||
import {formatUnicorn} from "../static/strings";
|
||||
import {FieldType} from "../static/enums";
|
||||
import {BlockScores, CellEventResponse} from "./KadiBoard";
|
||||
import GenericKadiRowContainer from "./GenericKadiRowContainer";
|
||||
import KadiEditableRowCells from "./KadiEditableRowCells";
|
||||
@@ -10,6 +7,7 @@ import KadiBlockTotalRow from "./KadiBlockTotalRow";
|
||||
import KadiBlockSubtotalRow from "./KadiBlockSubtotalRow";
|
||||
import KadiBlockBonusRow from "./KadiBlockBonusRow";
|
||||
import LocaleContext from "../LocaleContext";
|
||||
import {BlockDef, FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface BlockRendererProps {
|
||||
blockId: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {ReactNode} from "react";
|
||||
import KadiCell from "./KadiCell";
|
||||
import {FieldType} from "../static/enums";
|
||||
import {CellScores} from "./KadiBoard";
|
||||
import {FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface KadiBlockSubtotalRowProps {
|
||||
blockId: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {ReactNode} from "react";
|
||||
import KadiCell from "./KadiCell";
|
||||
import {FieldType} from "../static/enums";
|
||||
import {CellScores} from "./KadiBoard";
|
||||
import {FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface KadiBlockTotalRowProps {
|
||||
blockId: string;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, {ReactElement, ReactNode, useContext} from "react";
|
||||
import PlayerScoreCard, {CellLocation, PlayerScoreCardJSONRepresentation} from "../Classes/PlayerScoreCard";
|
||||
import {GameSchema, getGameSchemaById} from "../static/rulesets";
|
||||
import {getGameSchemaById} from "../static/rulesets";
|
||||
import LocaleContext from "../LocaleContext";
|
||||
import {CellFlag} from "../static/enums";
|
||||
import {ScoreCellValue} from "../Classes/ScoreCell";
|
||||
import {CaretakerSet} from "../Classes/Caretaker";
|
||||
import {GameSettings} from "./GameSetup";
|
||||
@@ -15,6 +14,7 @@ import KadiBlockRenderer from "./KadiBlockRenderer";
|
||||
import {KadiCellDisplayValue} from "./KadiCell";
|
||||
import {Player} from "./Game";
|
||||
import {SERVER_BASE_NAME} from "../index";
|
||||
import {CellFlag, Ruleset} from "../../../shared/rulesets";
|
||||
|
||||
|
||||
export interface CellScores {
|
||||
@@ -53,7 +53,7 @@ interface ScoreSheet {
|
||||
}
|
||||
|
||||
class KadiBoard extends React.Component<KadiBoardProps, KadiBoardState> {
|
||||
private readonly gameSchema: GameSchema;
|
||||
private readonly gameSchema: Ruleset;
|
||||
private readonly caretaker: CaretakerSet;
|
||||
state: KadiBoardState;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, {ChangeEvent, FocusEvent, ReactNode, KeyboardEvent} from "react";
|
||||
import {CellFlag, FieldType} from "../static/enums";
|
||||
import {ScoreCellValue} from "../Classes/ScoreCell";
|
||||
import {CellEventResponse} from "./KadiBoard";
|
||||
import {CellLocation} from "../Classes/PlayerScoreCard";
|
||||
import {useLongPress} from "./useLongPress";
|
||||
import {CellFlag, FieldType} from "../../../shared/rulesets";
|
||||
|
||||
export type KadiCellDisplayValue = ScoreCellValue | CellFlag.strike;
|
||||
|
||||
@@ -93,8 +93,8 @@ class KadiCell extends React.Component<KadiCellProps, KadiCellState> {
|
||||
return <MultipleKadiCell {...propsForEditableCell}/>;
|
||||
case FieldType.number:
|
||||
return <NumberKadiCell {...propsForEditableCell}/>;
|
||||
case FieldType.yahtzee:
|
||||
return <YahtzeeKadiCell {...propsForEditableCell}/>;
|
||||
case FieldType.superkadi:
|
||||
return <SuperkadiKadiCell {...propsForEditableCell}/>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,16 +185,16 @@ const NumberKadiCell: React.FunctionComponent<EditableKadiCellProps> = ({ strike
|
||||
)
|
||||
};
|
||||
|
||||
const YahtzeeKadiCell: React.FunctionComponent<EditableKadiCellProps> = ({value, timeoutMs, strikeCell, updateCell}) => {
|
||||
const SuperkadiKadiCell: React.FunctionComponent<EditableKadiCellProps> = ({value, timeoutMs, strikeCell, updateCell}) => {
|
||||
const handleClick = (): void => updateCell(true);
|
||||
const strikeCellOnLongPress = useLongPress(strikeCell, timeoutMs);
|
||||
return (
|
||||
<td
|
||||
className={"kadiCell editable yahtzeeField"}
|
||||
className={"kadiCell editable superkadiField"}
|
||||
onClick={handleClick}
|
||||
{...strikeCellOnLongPress}
|
||||
>
|
||||
<div className={"yahtzeeField"}>
|
||||
<div className={"superkadiField"}>
|
||||
{value}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {CellLocation} from "../Classes/PlayerScoreCard";
|
||||
import {FieldType} from "../static/enums";
|
||||
import React, {ReactElement} from "react";
|
||||
import KadiCell from "./KadiCell";
|
||||
import {CellEventResponse, CellScores} from "./KadiBoard";
|
||||
import {FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface KadiEditableRowCellsProps {
|
||||
location: CellLocation;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, {ReactNode} from "react";
|
||||
import LocaleContext from "../LocaleContext";
|
||||
import KadiCell from "./KadiCell";
|
||||
import {FieldType} from "../static/enums";
|
||||
import {Icon} from "semantic-ui-react";
|
||||
import {CellScores} from "./KadiBoard";
|
||||
import {FieldType} from "../../../shared/rulesets";
|
||||
|
||||
interface KadiGrandTotalRowProps {
|
||||
showResults: boolean;
|
||||
|
||||
@@ -125,7 +125,7 @@ div.subtotalField,
|
||||
div.totalField,
|
||||
div.bonusField,
|
||||
div.globalTotalField,
|
||||
div.yahtzeeField,
|
||||
div.superkadiField,
|
||||
div.multipleField,
|
||||
div.numberField {
|
||||
width: var(--default-field-width);
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
export enum FieldType {
|
||||
number = "numberField",
|
||||
bool = "boolField",
|
||||
bonus = "bonusField",
|
||||
subtotal = "subtotalField",
|
||||
globalTotal = "globalTotalField",
|
||||
total = "totalField",
|
||||
yahtzee = "yahtzeeField",
|
||||
multiplier = "multiplierField",
|
||||
}
|
||||
|
||||
export enum CellFlag {
|
||||
strike = "cellFlagStrike",
|
||||
unstrike = "cellFlagUnstrike",
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { FieldType } from "./enums";
|
||||
export enum FieldType {
|
||||
number = "numberField",
|
||||
bool = "boolField",
|
||||
bonus = "bonusField",
|
||||
subtotal = "subtotalField",
|
||||
globalTotal = "globalTotalField",
|
||||
total = "totalField",
|
||||
superkadi = "superkadiField",
|
||||
multiplier = "multiplierField",
|
||||
}
|
||||
|
||||
export const defaultCellValues = {
|
||||
[FieldType.number]: 0,
|
||||
@@ -6,12 +15,11 @@ export const defaultCellValues = {
|
||||
[FieldType.subtotal]: 0,
|
||||
[FieldType.total]: 0,
|
||||
[FieldType.bonus]: 0,
|
||||
[FieldType.yahtzee]: 0,
|
||||
[FieldType.superkadi]: 0,
|
||||
[FieldType.multiplier]: 0,
|
||||
};
|
||||
|
||||
// ----- gameSchema interface definitions
|
||||
export interface GameSchema {
|
||||
export interface Ruleset {
|
||||
id: string;
|
||||
label: string;
|
||||
blocks: Record<string, BlockDef>;
|
||||
@@ -35,10 +43,10 @@ interface DefaultBlockDef {
|
||||
}
|
||||
|
||||
export type CellDef =
|
||||
| BoolCellDef
|
||||
| MultiplierCellDef
|
||||
| NumberCellDef
|
||||
| YahtzeeCellDef;
|
||||
| BoolCellDef
|
||||
| MultiplierCellDef
|
||||
| NumberCellDef
|
||||
| SuperkadiCellDef;
|
||||
|
||||
export interface BoolCellDef extends DefaultCellDef {
|
||||
fieldType: FieldType.bool;
|
||||
@@ -51,10 +59,10 @@ export interface MultiplierCellDef extends DefaultCellDef {
|
||||
maxMultiples: number;
|
||||
}
|
||||
|
||||
export interface YahtzeeCellDef extends DefaultCellDef {
|
||||
fieldType: FieldType.yahtzee;
|
||||
export interface SuperkadiCellDef extends DefaultCellDef {
|
||||
fieldType: FieldType.superkadi;
|
||||
score: number;
|
||||
maxYahtzees: number;
|
||||
maxSuperkadis: number;
|
||||
}
|
||||
|
||||
export interface NumberCellDef extends DefaultCellDef {
|
||||
@@ -65,11 +73,12 @@ interface DefaultCellDef {
|
||||
label: string;
|
||||
}
|
||||
|
||||
|
||||
// ----- Predefined sets
|
||||
const defaultDiceCount = 5;
|
||||
const DEFAULT_RULESET = "DEFAULT_RULESET";
|
||||
|
||||
const gameSchemas: GameSchema[] = [
|
||||
const gameSchemas: Ruleset[] = [
|
||||
{
|
||||
id: DEFAULT_RULESET,
|
||||
label: "Standard Kadi Rules (en)",
|
||||
@@ -127,39 +136,39 @@ const gameSchemas: GameSchema[] = [
|
||||
label: "Lower",
|
||||
hasBonus: false,
|
||||
cells: {
|
||||
three_kind: {
|
||||
threeKind: {
|
||||
fieldType: FieldType.number,
|
||||
label: "Three of a Kind",
|
||||
},
|
||||
|
||||
four_kind: {
|
||||
fourKind: {
|
||||
fieldType: FieldType.number,
|
||||
label: "Four of a Kind",
|
||||
},
|
||||
|
||||
full_house: {
|
||||
fullHouse: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Full House",
|
||||
score: 25,
|
||||
},
|
||||
|
||||
sml_straight: {
|
||||
smlStraight: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Small Straight",
|
||||
score: 30,
|
||||
},
|
||||
|
||||
lg_straight: {
|
||||
lgSraight: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Large Straight",
|
||||
score: 40,
|
||||
},
|
||||
|
||||
yahtzee: {
|
||||
fieldType: FieldType.yahtzee,
|
||||
label: "Kadi",
|
||||
kadi: {
|
||||
fieldType: FieldType.superkadi,
|
||||
label: "Super Kadis",
|
||||
score: 50,
|
||||
maxYahtzees: 5,
|
||||
maxSuperkadis: 5,
|
||||
},
|
||||
|
||||
chance: {
|
||||
@@ -227,34 +236,34 @@ const gameSchemas: GameSchema[] = [
|
||||
label: "Unten",
|
||||
hasBonus: false,
|
||||
cells: {
|
||||
three_kind: {
|
||||
threeKind: {
|
||||
fieldType: FieldType.number,
|
||||
label: "Dreierpasch",
|
||||
},
|
||||
four_kind: {
|
||||
fourKind: {
|
||||
fieldType: FieldType.number,
|
||||
label: "Viererpasch",
|
||||
},
|
||||
full_house: {
|
||||
fullSouse: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Full House",
|
||||
score: 25,
|
||||
},
|
||||
sml_straight: {
|
||||
smlStraight: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Kleine Straße",
|
||||
score: 30,
|
||||
},
|
||||
lg_straight: {
|
||||
lgStraight: {
|
||||
fieldType: FieldType.bool,
|
||||
label: "Große Straße",
|
||||
score: 40,
|
||||
},
|
||||
yahtzee: {
|
||||
fieldType: FieldType.yahtzee,
|
||||
label: "Kadi",
|
||||
kadi: {
|
||||
fieldType: FieldType.superkadi,
|
||||
label: "Ultrakadi",
|
||||
score: 50,
|
||||
maxYahtzees: 5,
|
||||
maxSuperkadis: 5,
|
||||
},
|
||||
change: {
|
||||
fieldType: FieldType.number,
|
||||
@@ -266,7 +275,7 @@ const gameSchemas: GameSchema[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export function getGameSchemaById(schemaId: string): GameSchema {
|
||||
export function getGameSchemaById(schemaId: string): Ruleset {
|
||||
for (const schema of gameSchemas) {
|
||||
if (schema.id === schemaId) {
|
||||
return schema;
|
||||
|
||||
Reference in New Issue
Block a user