Skip to content

Commit

Permalink
Factor out instructions into its own file, with some sample state
Browse files Browse the repository at this point in the history
  • Loading branch information
jcreedcmu committed Oct 15, 2023
1 parent 404a080 commit e3a4dd3
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 53 deletions.
31 changes: 9 additions & 22 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 <span>Instructions go here</span>;
}

export function App(props: {}): JSX.Element {
const [state, dispatch] = useEffectfulReducer<Action, SceneState, Effect>(mkSceneState(), reduce, doEffect);

if (DEBUG.stateExporter) {
(window as any).state = () => { return state; }
}

switch (state.t) {
case 'menu': {
const style: React.CSSProperties = {
Expand Down
27 changes: 27 additions & 0 deletions src/core/action.ts
Original file line number Diff line number Diff line change
@@ -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;
3 changes: 2 additions & 1 deletion src/core/reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 0 additions & 30 deletions src/core/state.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ViewData } from '../app';
import { SE2 } from '../util/se2';
import { Point } from '../util/types';
import { Bonus, bonusGenerator } from './bonus';
Expand All @@ -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 }
Expand Down
141 changes: 141 additions & 0 deletions src/ui/instructions.tsx
Original file line number Diff line number Diff line change
@@ -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 <span>Instructions go here</span>;
}

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,
};
1 change: 1 addition & 0 deletions src/util/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const DEBUG = {
produce: false,
letterSample: false,
words: false,
stateExporter: true,
};

export type DebugLevel = keyof (typeof DEBUG);
Expand Down

0 comments on commit e3a4dd3

Please sign in to comment.