WordGrid/ui/src/utils.ts

138 lines
3.7 KiB
TypeScript
Raw Normal View History

2023-08-24 03:46:43 +00:00
import {Letter as LetterData, Letter} from "word_grid";
import * as React from "react";
export enum CellType {
Normal = "Normal",
DoubleWord = "DoubleWord",
DoubleLetter = "DoubleLetter",
TripleLetter = "TripleLetter",
TripleWord = "TripleWord",
Start = "Start",
}
export interface Settings {
trayLength: number;
2023-09-15 02:14:19 +00:00
playerName: string;
2023-08-24 03:46:43 +00:00
}
export enum LocationType {
GRID,
TRAY
}
export interface CoordinateData {
location: LocationType;
index: number;
}
export type PlayableLetterData = LetterData & CoordinateData;
2023-09-15 02:38:34 +00:00
export type HighlightableLetterData = LetterData & {highlight: boolean};
2023-08-24 03:46:43 +00:00
export enum TileDispatchActionType {
MOVE,
RETRIEVE,
SET_BLANK,
RETURN,
}
export type TileDispatchAction = {action: TileDispatchActionType, start?: CoordinateData, end?: CoordinateData, newBlankValue?: string, blankIndex?: number};
export type TileDispatch = React.Dispatch<TileDispatchAction>;
export function matchCoordinate(playerLetters: PlayableLetterData[], coords: CoordinateData): number {
for (let i=0; i<playerLetters.length; i++){
let letter = playerLetters[i];
if (letter !== undefined && 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};
}
2023-08-22 02:42:22 +00:00
export function addNTimes<T>(array: T[], toAdd: T, times: number) {
for (let i=0; i<times; i++) {
array.push(toAdd);
}
2023-08-24 03:23:58 +00:00
}
export function mergeTrays(existing: PlayableLetterData[], newer: (Letter | undefined)[]): 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 !== undefined && 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 !== undefined) {
if (existing[i] !== undefined && 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;
});
2023-08-22 02:42:22 +00:00
}