Joel Therrien
1224035d7a
Reviewed-on: #1 Co-authored-by: Joel Therrien <joel@joeltherrien.ca> Co-committed-by: Joel Therrien <joel@joeltherrien.ca>
155 lines
No EOL
4.1 KiB
TypeScript
155 lines
No EOL
4.1 KiB
TypeScript
import * as React from "react";
|
|
import {CellType, Letter as LetterData} from "./api";
|
|
|
|
|
|
export interface Settings {
|
|
trayLength: number;
|
|
playerName: string;
|
|
}
|
|
|
|
export enum LocationType {
|
|
GRID,
|
|
TRAY
|
|
}
|
|
|
|
export interface CoordinateData {
|
|
location: LocationType;
|
|
index: number;
|
|
}
|
|
|
|
export type PlayableLetterData = LetterData & CoordinateData;
|
|
export type HighlightableLetterData = LetterData & {highlight: boolean};
|
|
|
|
export enum TileDispatchActionType {
|
|
MOVE,
|
|
RETRIEVE,
|
|
SET_BLANK,
|
|
RETURN,
|
|
MOVE_TO_ARROW,
|
|
}
|
|
export type TileDispatchAction = {action: TileDispatchActionType, start?: CoordinateData, end?: CoordinateData, newBlankValue?: string, blankIndex?: number, override?: boolean};
|
|
export type TileDispatch = React.Dispatch<TileDispatchAction>;
|
|
|
|
export enum Direction {
|
|
RIGHT = "right",
|
|
DOWN = "down",
|
|
}
|
|
export interface GridArrowData {
|
|
direction: Direction,
|
|
position: number,
|
|
}
|
|
|
|
export enum GridArrowDispatchActionType {
|
|
CLEAR,
|
|
CYCLE,
|
|
SHIFT,
|
|
}
|
|
|
|
// I need to include the playerLetters as an argument because I can't define gridArrow after defining the playerLetters in <Game>
|
|
export type GridArrowDispatchAction = {
|
|
action: GridArrowDispatchActionType,
|
|
position?: number,
|
|
playerLetters?: PlayableLetterData[] // only needs to be defined on action type SHIFT
|
|
};
|
|
export type GridArrowDispatch = React.Dispatch<GridArrowDispatchAction>;
|
|
|
|
export function matchCoordinate(playerLetters: PlayableLetterData[], coords: CoordinateData): number {
|
|
|
|
for (let i=0; i<playerLetters.length; i++){
|
|
let letter = playerLetters[i];
|
|
|
|
if (letter != null && letter.location === coords.location && letter.index === coords.index) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return null; // no match
|
|
|
|
}
|
|
|
|
export function cellTypeToDetails(cell_type: CellType): {className: string, text: string} {
|
|
let className: string;
|
|
let text: string;
|
|
|
|
switch (cell_type) {
|
|
case CellType.Normal:
|
|
className = "grid-spot-normal";
|
|
text = "";
|
|
break;
|
|
case CellType.DoubleWord:
|
|
className = "grid-spot-double-word";
|
|
text = "Double Word Score";
|
|
break;
|
|
case CellType.DoubleLetter:
|
|
className = "grid-spot-double-letter";
|
|
text = "Double Letter Score";
|
|
break;
|
|
case CellType.TripleLetter:
|
|
className = "grid-spot-triple-letter";
|
|
text = "Triple Letter Score";
|
|
break;
|
|
case CellType.TripleWord:
|
|
className = "grid-spot-triple-word";
|
|
text = "Triple Word Score";
|
|
break;
|
|
case CellType.Start:
|
|
className = "grid-spot-start";
|
|
text = "★";
|
|
break;
|
|
|
|
}
|
|
|
|
return {className: className, text: text};
|
|
}
|
|
|
|
export function addNTimes<T>(array: T[], toAdd: T, times: number) {
|
|
for (let i=0; i<times; i++) {
|
|
array.push(toAdd);
|
|
}
|
|
}
|
|
|
|
export function mergeTrays(existing: PlayableLetterData[], newer: (LetterData | null)[]): PlayableLetterData[] {
|
|
|
|
let trayLength = Math.max(existing.length, newer.length);
|
|
|
|
// we may need to check against the existing tray to retain whatever user reorderings there are
|
|
const freeSpots = new Array<number | null>();
|
|
for (let i = 0; i<trayLength; i++) {
|
|
freeSpots.push(i);
|
|
}
|
|
|
|
existing.filter((x) => {
|
|
return x != null;
|
|
}).forEach((x) => {
|
|
if (x.location === LocationType.TRAY) {
|
|
freeSpots[x.index] = null;
|
|
}
|
|
});
|
|
|
|
const firstNotNull = (): number => {
|
|
for (let i of freeSpots) {
|
|
if (i !== null) {
|
|
freeSpots[i] = null;
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
return newer.map((ld, i) => {
|
|
if (ld != null) {
|
|
|
|
if (existing[i] != null && existing[i].location === LocationType.TRAY) {
|
|
ld["index"] = existing[i].index;
|
|
} else {
|
|
ld["index"] = firstNotNull();
|
|
}
|
|
ld["location"] = LocationType.TRAY;
|
|
}
|
|
return ld as PlayableLetterData;
|
|
});
|
|
|
|
}
|
|
|
|
export const GRID_LENGTH = 15; |