diff --git a/src/core/reduce.ts b/src/core/reduce.ts index c27ee69..68399ee 100644 --- a/src/core/reduce.ts +++ b/src/core/reduce.ts @@ -16,7 +16,7 @@ import { mkOverlayFrom } from './layer'; import { resolveSelection } from './selection'; import { tryReduceShortcut } from './shortcuts'; import { CoreState, GameState, HAND_TILE_LIMIT, Location, SceneState, mkGameSceneState } from './state'; -import { MoveTile, addWorldTiles, bonusOfStatePoint, checkValid, drawOfState, filterExpiredAnimations, isCollision, isOccupied, isTilePinned, tileFall, unpauseState, withCoreState } from './state-helpers'; +import { MoveTile, addWorldTiles, bonusOfStatePoint, checkValid, drawOfState, dropTopHandTile, filterExpiredAnimations, isCollision, isOccupied, isTilePinned, tileFall, unpauseState, withCoreState } from './state-helpers'; import { getTileId, get_hand_tiles, get_tiles, putTileInHand, putTileInWorld, putTilesInHand, removeAllTiles, setTileLoc, tileAtPoint } from "./tile-helpers"; import { bombIntent, dynamiteIntent, getCurrentTool, reduceToolSelect } from './tools'; @@ -266,6 +266,9 @@ function reduceGameAction(state: GameState, action: GameAction): effectful.Resul if (action.code == 'k') { return gs(withCoreState(state, cs => tryKillTileOfState(cs, getWidgetPoint(cs, state.mouseState.p_in_canvas), dynamiteIntent))); } + if (action.code == 'a') { + return gs(dropTopHandTile(state)); + } if (action.code == 'S-d') { return gs(withCoreState(state, cs => checkValid(produce(addWorldTiles(removeAllTiles(cs), debugTiles()), s => { s.score = 1000; diff --git a/src/core/state-helpers.ts b/src/core/state-helpers.ts index 777ecd3..9e9d5c6 100644 --- a/src/core/state-helpers.ts +++ b/src/core/state-helpers.ts @@ -1,4 +1,5 @@ import { canvas_from_drag_tile } from "../ui/view-helpers"; +import { getWidgetPoint } from "../ui/widget-helpers"; import { DEBUG, logger } from "../util/debug"; import { produce } from "../util/produce"; import * as se1 from '../util/se1'; @@ -13,7 +14,7 @@ import { DrawForce, getLetterSample } from "./distribution"; import { checkConnected, checkGridWords, mkGridOfMainTiles } from "./grid"; import { Layer, Overlay, getOverlayLayer, mkOverlayFrom, overlayAny, overlayPoints, setOverlay } from "./layer"; import { CoreState, GameState, HAND_TILE_LIMIT, Location, MouseState, Tile, TileEntity } from "./state"; -import { addHandTile, addWorldTile, ensureTileId, get_hand_tiles, get_main_tiles, get_tiles } from "./tile-helpers"; +import { addHandTile, addWorldTile, ensureTileId, get_hand_tiles, get_main_tiles, get_tiles, putTileInWorld, removeTile } from "./tile-helpers"; export function addWorldTiles(state: CoreState, tiles: Tile[]): CoreState { return produce(state, s => { @@ -169,3 +170,19 @@ export function withCoreState(state: GameState, k: (cs: CoreState) => CoreState) s.coreState = ncs; }); } + +export function dropTopHandTile(state: GameState): GameState { + const cs = state.coreState; + const handTiles = get_hand_tiles(cs); + if (handTiles.length == 0) { + return state; + } + const tile = handTiles[0]; + if (state.mouseState.t == 'up' && getWidgetPoint(cs, state.mouseState.p_in_canvas).t == 'world') { + const p_in_world_int = pointFall(cs, state.mouseState.p_in_canvas); + if (!isOccupied(cs, { id: tile.id, letter: tile.letter, p_in_world_int })) { + return withCoreState(state, cs => checkValid(putTileInWorld(cs, tile.id, p_in_world_int))); + } + } + return state; +}