Skip to content

Commit

Permalink
Add some stubs for instructions (##36)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcreedcmu committed Oct 15, 2023
1 parent f0537b3 commit 404a080
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 33 deletions.
57 changes: 40 additions & 17 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,49 @@ type CanvasProps = {
};


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 (state.t == 'menu') {
const style: React.CSSProperties = {
backgroundColor: 'white',
padding: 15,
border: '1px solid gray',
borderRadius: 10,
fontFamily: 'sans-serif',
fontWeight: 'bold',
cursor: 'pointer',
};
return <div style={{ textAlign: 'center', fontSize: 48, fontFamily: 'sans-serif' }}>
Wordlike<p />
<button style={style} onClick={() => dispatch({ t: 'newGame' })}>Start Game</button>
</div>;
}
else {
return <Game dispatch={dispatch} state={state.gameState} />;
switch (state.t) {
case 'menu': {
const style: React.CSSProperties = {
backgroundColor: 'white',
padding: 15,
border: '1px solid gray',
borderRadius: 10,
fontFamily: 'sans-serif',
fontWeight: 'bold',
cursor: 'pointer',
};
return <div style={{ textAlign: 'center', fontSize: 48, fontFamily: 'sans-serif' }}>
Wordlike<p />
<button style={style} onClick={() => dispatch({ t: 'newGame' })}>Start Game</button>
<p /><p />
<button style={style} onClick={() => dispatch({ t: 'setSceneState', state: { t: 'instructions' } })}>Instructions</button>
</div>;
}
case 'game':
return <Game dispatch={dispatch} state={state.gameState} />;
case 'instructions': {
return <Instructions dispatch={dispatch} />;
}
}
}

Expand Down
29 changes: 15 additions & 14 deletions src/core/reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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, GameState, SceneState, mkGameSceneState, mkGameState } from './state';
import { Action, Effect, GameAction, GameState, SceneState, mkGameSceneState, mkGameState } from './state';
import { checkValid, drawOfState, is_occupied, killTileOfState } from './state-helpers';

function resolveDrag(state: GameState): GameState {
Expand Down Expand Up @@ -166,7 +166,7 @@ export function reduceMouseDown(state: GameState, wp: WidgetPoint, button: numbe
}
}

export function reduceGameAction(state: GameState, action: Action): effectful.Result<SceneState, Effect> {
export function reduceGameAction(state: GameState, action: GameAction): effectful.Result<SceneState, Effect> {
function gs(state: GameState): effectful.Result<SceneState, Effect> {
return { state: { t: 'game', gameState: state, revision: 0 }, effects: [] };
}
Expand Down Expand Up @@ -200,7 +200,6 @@ export function reduceGameAction(state: GameState, action: Action): effectful.Re
case 'mouseMove': return gs(produce(state, s => {
s.mouseState.p = action.p;
}));
case 'resize': return gs(state); // XXX maybe stash viewdata this in state somewhere?
case 'repaint':
if (state.panic !== undefined) {
if (getPanicFraction(state.panic) > 1) {
Expand All @@ -211,22 +210,24 @@ export function reduceGameAction(state: GameState, action: Action): effectful.Re
else {
return gs(state);
}
case 'newGame':
throw new Error('lifecycle error');
}
}

export function reduce(scState: SceneState, action: Action): effectful.Result<SceneState, Effect> {
switch (scState.t) {
case 'game':
return reduceGameAction(scState.gameState, action);
case 'menu':
switch (action.t) {
case 'newGame':
return { state: mkGameSceneState(Date.now()), effects: [] };
default:
return { state: scState, effects: [] };
switch (action.t) {
case 'resize': return { state: scState, effects: [] }; // XXX maybe stash viewdata this in state somewhere?
case 'newGame':
return { state: mkGameSceneState(Date.now()), effects: [] };
case 'setSceneState':
return { state: action.state, effects: [] };
default:
if (scState.t == 'game') {
return reduceGameAction(scState.gameState, action);
}
else {
return { state: scState, effects: [] };
}
}


}
7 changes: 5 additions & 2 deletions src/core/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ export type UiAction =
| { t: 'mouseUp', p: Point }
| { t: 'mouseMove', p: Point }
| { t: 'wheel', p: Point, delta: number }
| { t: 'repaint' }
;

export type Action =
| { t: 'resize', vd: ViewData }
| { t: 'repaint' }
| { t: 'newGame' }
| { t: 'setSceneState', state: SceneState }
| GameAction
;

Expand All @@ -53,7 +54,9 @@ export type SceneState =
// It's updated in reduce.ts.
revision: number,
}
| { t: 'menu' };
| { t: 'menu' }
| { t: 'instructions' }
;

export type State = {
sceneState: SceneState,
Expand Down

0 comments on commit 404a080

Please sign in to comment.