diff --git a/src/app.tsx b/src/app.tsx
index 029a97e..119a18e 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -1,17 +1,18 @@
import * as React from 'react';
import { useEffect } from 'react';
+import { Action, Dispatch, Effect } from './core/action';
import { reduce } from './core/reduce';
-import { Action, Effect, GameState, MouseState, SceneState, mkSceneState } from './core/state';
+import { GameState, MouseState, SceneState, mkSceneState } from './core/state';
+import { Instructions } from './ui/instructions';
import { key } from './ui/key';
import { paint } from './ui/render';
import { CanvasInfo, useCanvas } from './ui/use-canvas';
import { useEffectfulReducer } from './ui/use-effectful-reducer';
+import { canvas_bds_in_canvas } from './ui/widget-helpers';
+import { DEBUG } from './util/debug';
import { relpos } from './util/dutil';
import { Point } from './util/types';
import { vint } from './util/vutil';
-import { canvas_bds_in_canvas } from './ui/widget-helpers';
-
-type Dispatch = (action: Action) => void;
export type GameProps = {
state: GameState,
@@ -23,27 +24,13 @@ type CanvasProps = {
main: ForRenderState,
};
-
-function Instructions(props: { dispatch: Dispatch }): JSX.Element {
- const { dispatch } = props;
- function mouseDownListener(e: MouseEvent) {
- dispatch({ t: 'setSceneState', state: { t: 'menu' } });
- e.preventDefault();
- e.stopPropagation();
- }
-
- useEffect(() => {
- document.addEventListener('mousedown', mouseDownListener);
- return () => {
- document.removeEventListener('mousedown', mouseDownListener);
- }
- });
- return Instructions go here;
-}
-
export function App(props: {}): JSX.Element {
const [state, dispatch] = useEffectfulReducer(mkSceneState(), reduce, doEffect);
+ if (DEBUG.stateExporter) {
+ (window as any).state = () => { return state; }
+ }
+
switch (state.t) {
case 'menu': {
const style: React.CSSProperties = {
diff --git a/src/core/action.ts b/src/core/action.ts
new file mode 100644
index 0000000..cf42c17
--- /dev/null
+++ b/src/core/action.ts
@@ -0,0 +1,27 @@
+import { ViewData } from '../app';
+import { Point } from '../util/types';
+import { SceneState } from './state';
+
+// There are UiActions, which might have different behavior depending
+// on view state, and other GameActions, which should be treated
+// uniformly.
+
+export type GameAction = { t: 'none'; } |
+ UiAction;
+// I think I want to migrate some of these up to GameAction
+
+export type UiAction = { t: 'key'; code: string; } |
+{ t: 'mouseDown'; button: number; p: Point; } |
+{ t: 'mouseUp'; p: Point; } |
+{ t: 'mouseMove'; p: Point; } |
+{ t: 'wheel'; p: Point; delta: number; } |
+{ t: 'repaint'; };
+
+export type Action = { t: 'resize'; vd: ViewData; } |
+{ t: 'newGame'; } |
+{ t: 'setSceneState'; state: SceneState; } |
+ GameAction;
+
+export type Effect = { t: 'none'; };
+
+export type Dispatch = (action: Action) => void;
diff --git a/src/core/reduce.ts b/src/core/reduce.ts
index bc6be3f..b3f9ca2 100644
--- a/src/core/reduce.ts
+++ b/src/core/reduce.ts
@@ -6,7 +6,8 @@ import { compose, composen, inverse, scale, translate } from '../util/se2';
import { Point } from '../util/types';
import { vequal, vm, vscale } from '../util/vutil';
import { getPanicFraction } from './clock';
-import { Action, Effect, GameAction, GameState, SceneState, mkGameSceneState, mkGameState } from './state';
+import { GameState, SceneState, mkGameSceneState, mkGameState } from './state';
+import { Action, Effect, GameAction } from './action';
import { checkValid, drawOfState, is_occupied, killTileOfState } from './state-helpers';
function resolveDrag(state: GameState): GameState {
diff --git a/src/core/state.ts b/src/core/state.ts
index a9d82e7..522b4f4 100644
--- a/src/core/state.ts
+++ b/src/core/state.ts
@@ -1,4 +1,3 @@
-import { ViewData } from '../app';
import { SE2 } from '../util/se2';
import { Point } from '../util/types';
import { Bonus, bonusGenerator } from './bonus';
@@ -7,35 +6,6 @@ import { Energies, initialEnergies } from './distribution';
import { Grid, LocatedWord, mkGrid, mkGridOf } from './grid';
import { Layer, Overlay, mkLayer, mkOverlay } from './layer';
-// There are UiActions, which might have different behavior depending
-// on view state, and other GameActions, which should be treated
-// uniformly.
-export type GameAction =
- | { t: 'none' }
- | UiAction
- ;
-
-// I think I want to migrate some of these up to GameAction
-export type UiAction =
- | { t: 'key', code: string }
- | { t: 'mouseDown', button: number, p: Point }
- | { t: 'mouseUp', p: Point }
- | { t: 'mouseMove', p: Point }
- | { t: 'wheel', p: Point, delta: number }
- | { t: 'repaint' }
- ;
-
-export type Action =
- | { t: 'resize', vd: ViewData }
- | { t: 'newGame' }
- | { t: 'setSceneState', state: SceneState }
- | GameAction
- ;
-
-export type Effect =
- | { t: 'none' }
- ;
-
export type MouseState =
| { t: 'up', p: Point }
| { t: 'down', p: Point }
diff --git a/src/ui/instructions.tsx b/src/ui/instructions.tsx
new file mode 100644
index 0000000..837fec9
--- /dev/null
+++ b/src/ui/instructions.tsx
@@ -0,0 +1,141 @@
+import * as React from 'react';
+import { useEffect } from 'react';
+import { Dispatch } from '../core/action';
+import { bonusGenerator } from '../core/bonus';
+import { mkGridOf } from '../core/grid';
+import { mkLayer } from '../core/layer';
+import { SceneState } from '../core/state';
+
+export function Instructions(props: { dispatch: Dispatch }): JSX.Element {
+ const { dispatch } = props;
+ function mouseDownListener(e: MouseEvent) {
+ dispatch({ t: 'setSceneState', state: { t: 'menu' } });
+ e.preventDefault();
+ e.stopPropagation();
+ }
+
+ useEffect(() => {
+ document.addEventListener('mousedown', mouseDownListener);
+ return () => {
+ document.removeEventListener('mousedown', mouseDownListener);
+ }
+ });
+ return Instructions go here;
+}
+
+const state: SceneState = {
+ t: "game",
+ gameState: {
+ invalidWords: [],
+ connectedSet: mkGridOf([]),
+ energies: [
+ -0.20972339977922094,
+ 0.7840271889992784,
+ 1.3068528194400546,
+ 0.3068528194400547,
+ 0.5636791674230779,
+ 1.6534264097200273,
+ 0.3068528194400547,
+ 0.7840271889992784,
+ 0.6791654891096679,
+ 4,
+ 4,
+ 1.1041202653859723,
+ 0.7840271889992784,
+ 0.4602792291600821,
+ 0.4602792291600821,
+ 0.7840271889992784,
+ 4,
+ 0.4602792291600821,
+ -0.0047189562170500965,
+ -0.039720770839917874,
+ 0.79528104378295,
+ 1.6534264097200273,
+ 1.6534264097200273,
+ 4,
+ 1.6534264097200273,
+ 0
+ ],
+ seed: 1533311107,
+ main_tiles: [
+ { letter: "p", p_in_world_int: { x: 0, y: 0 }, used: true },
+ { letter: "i", p_in_world_int: { x: 2, y: 2 }, used: true },
+ { letter: "t", p_in_world_int: { x: 2, y: 0 }, used: true },
+ { letter: "o", p_in_world_int: { x: 1, y: 0 }, used: true },
+ { letter: "w", p_in_world_int: { x: 2, y: 1 }, used: true },
+ { letter: "c", p_in_world_int: { x: 9, y: -3 }, used: true },
+ { letter: "e", p_in_world_int: { x: 2, y: 4 }, used: true },
+ { letter: "q", p_in_world_int: { x: 1, y: 2 }, used: true },
+ { letter: "h", p_in_world_int: { x: 1, y: 4 }, used: true },
+ { letter: "n", p_in_world_int: { x: 6, y: 2 }, used: true },
+ { letter: "l", p_in_world_int: { x: 3, y: 4 }, used: true },
+ { letter: "s", p_in_world_int: { x: 0, y: 4 }, used: true },
+ { letter: "v", p_in_world_int: { x: 4, y: 4 }, used: true },
+ { letter: "e", p_in_world_int: { x: 5, y: 4 }, used: true },
+ { letter: "d", p_in_world_int: { x: 6, y: 4 }, used: true },
+ { letter: "l", p_in_world_int: { x: 9, y: -1 }, used: true },
+ { letter: "i", p_in_world_int: { x: 6, y: 1 }, used: true },
+ { letter: "e", p_in_world_int: { x: 6, y: 3 }, used: true },
+ { letter: "i", p_in_world_int: { x: 8, y: 4 }, used: true },
+ { letter: "m", p_in_world_int: { x: 9, y: 0 }, used: true },
+ { letter: "r", p_in_world_int: { x: 11, y: -2 }, used: true },
+ { letter: "r", p_in_world_int: { x: 6, y: 0 }, used: true },
+ { letter: "n", p_in_world_int: { x: 2, y: 3 }, used: true },
+ { letter: "a", p_in_world_int: { x: 9, y: -2 }, used: true },
+ { letter: "u", p_in_world_int: { x: 0, y: -1 }, used: true },
+ { letter: "o", p_in_world_int: { x: 7, y: -1 }, used: true },
+ { letter: "n", p_in_world_int: { x: 8, y: 5 }, used: true },
+ { letter: "e", p_in_world_int: { x: 7, y: 3 }, used: true },
+ { letter: "i", p_in_world_int: { x: 8, y: -1 }, used: true },
+ { letter: "b", p_in_world_int: { x: 6, y: -1 }, used: true },
+ { letter: "l", p_in_world_int: { x: 8, y: 3 }, used: true },
+ { letter: "t", p_in_world_int: { x: 8, y: 6 }, used: true },
+ { letter: "c", p_in_world_int: { x: 11, y: 0 }, used: true },
+ { letter: "k", p_in_world_int: { x: 12, y: 0 }, used: true },
+ { letter: "f", p_in_world_int: { x: 11, y: -4 }, used: true },
+ { letter: "r", p_in_world_int: { x: 10, y: -3 }, used: true },
+ { letter: "a", p_in_world_int: { x: 11, y: -3 }, used: true },
+ { letter: "g", p_in_world_int: { x: 12, y: -3 }, used: true },
+ { letter: "e", p_in_world_int: { x: 12, y: -2 }, used: true },
+ { letter: "e", p_in_world_int: { x: 12, y: -1 }, used: true },
+ { letter: "u", p_in_world_int: { x: 10, y: 0 }, used: true },
+ { letter: "y", p_in_world_int: { x: 13, y: 0 }, used: true },
+ { letter: "x", p_in_world_int: { x: 13, y: -2 }, used: true },
+ { letter: "j", p_in_world_int: { x: 6, y: 6 }, used: true },
+ { letter: "o", p_in_world_int: { x: 7, y: 6 }, used: true }
+ ],
+ hand_tiles: [],
+ canvas_from_world: {
+ scale: {
+ x: 39.6694214876033,
+ y: 39.6694214876033
+ },
+ translate: {
+ x: 50.80991735537191,
+ y: 215.56198347107437
+ }
+ },
+ mouseState: {
+ t: "up",
+ p: {
+ x: 962,
+ y: 88
+ }
+ },
+ bonusLayer: mkLayer(bonusGenerator),
+ bonusOverlay: {
+ cells: {
+ "5,6": "empty",
+ "7,1": "empty",
+ "5,1": "empty",
+ "8,0": "empty",
+ "9,-1": "empty",
+ "2,7": "empty",
+ "8,4": "empty"
+ }
+ },
+ score: 7,
+ panic: undefined,
+ },
+ revision: 0,
+};
diff --git a/src/util/debug.ts b/src/util/debug.ts
index e6d3825..2bec042 100644
--- a/src/util/debug.ts
+++ b/src/util/debug.ts
@@ -6,6 +6,7 @@ export const DEBUG = {
produce: false,
letterSample: false,
words: false,
+ stateExporter: true,
};
export type DebugLevel = keyof (typeof DEBUG);