From 6d70cc9953d73cc74191a8c9c5c8db1647338ac1 Mon Sep 17 00:00:00 2001 From: Daniel Perelman <perelman@cs.washington.edu> Date: Wed, 13 Sep 2023 00:31:08 -0700 Subject: [PATCH] Interpreter: added some support for turn alone and slice. --- www/js/interpreter.ts | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/www/js/interpreter.ts b/www/js/interpreter.ts index 1752e4d..4123d99 100644 --- a/www/js/interpreter.ts +++ b/www/js/interpreter.ts @@ -64,6 +64,20 @@ function handsInLine(args: { wavy: boolean } & ({ which: ShortLinesPosition, fac ]); } } +function handToDancerToSideInCircleFacingAcross(which: CirclePosition): Map<Hand, HandConnection> { + return new Map<Hand, HandConnection>([ + which.isOnLeftLookingAcross() + ? [Hand.Right, { hand: Hand.Left, to: HandTo.DancerRight }] + : [Hand.Left, { hand: Hand.Right, to: HandTo.DancerLeft }] + ]); +} +function handToDancerToSideInCircleFacingUpOrDown(which: CirclePosition): Map<Hand, HandConnection> { + return new Map<Hand, HandConnection>([ + which.isOnLeftLookingUpAndDown() + ? [Hand.Right, { hand: Hand.Left, to: HandTo.DancerRight }] + : [Hand.Left, { hand: Hand.Right, to: HandTo.DancerLeft }] + ]); +} function balanceCircleInAndOut(move: Move, startPos: SemanticPosition, balanceBeats?: number): [LowLevelMove, LowLevelMove] { if (startPos.kind !== PositionKind.Circle) { @@ -1240,6 +1254,45 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: { }], startingPos); }); + case "slice": + if (move.parameters["slice increment"] === "dancer") { + // TODO Maybe this only actually gets used to move an entire couple by going diagonal back? + throw new Error("Slicing by a single dancer is unsupported."); + } + + const sliceLeft = move.parameters.slide; + const sliceReturns = move.parameters["slice return"] !== "none"; + + const sliceForwardBeats = sliceReturns ? move.beats / 2 : move.beats; + const sliceBackwardBeats = move.beats - sliceForwardBeats; + + return handleCircleMove(({ startPos }) => { + const startingPos: SemanticPosition & { setOffset: number } = { + kind: PositionKind.Circle, + which: startPos.which, + facing: startPos.which.facingAcross(), + hands: handToDancerToSideInCircleFacingAcross(startPos.which), + setOffset: startPos.setOffset ?? 0, + lineOffset: startPos.lineOffset, + }; + const sliceAmount = startingPos.which.isLeft() === sliceLeft ? +0.5 : -0.5; + const forwardOffset = startingPos.setOffset + sliceAmount; + const endOffset = move.parameters["slice return"] === "diagonal" ? forwardOffset + sliceAmount : forwardOffset; + + const sliceForward: PartialLowLevelMove = { + beats: sliceForwardBeats, + endPosition: { ...startingPos, setOffset: forwardOffset, longLines: LongLines.Forward }, + movementPattern: { kind: SemanticAnimationKind.Linear }, + }; + const maybeSliceBackward: PartialLowLevelMove[] = sliceReturns ? [{ + beats: sliceBackwardBeats, + endPosition: { ...startingPos, setOffset: endOffset }, + movementPattern: { kind: SemanticAnimationKind.Linear }, + }] : []; + + return combine([sliceForward, ...maybeSliceBackward], startingPos); + }); + case "down the hall": if (move.parameters.who !== "everyone") { throw new Error("Don't know what it means for not everyone to go down the hall."); @@ -1683,6 +1736,26 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: { return combine(heySteps.map(heyStepToPartialLowLevelMove), { ...startingPos, hands: undefined }); }); + case "turn alone": + if (move.parameters.who !== "everyone" || move.beats !== 0) { + throw new Error("turn alone unsupported except for changing to new circle."); + } + return handleCircleMove(({startPos}) => { + const which = startPos.which.swapUpAndDown(); + const startAndEndPos: SemanticPosition = { + ...startPos, + which, + facing: which.facingUpOrDown(), + setOffset: (startPos.setOffset ?? 0) + (startPos.which.isTop() ? +0.5 : -0.5), + } + + return combine([{ + beats: move.beats, + endPosition: startAndEndPos, + movementPattern: { kind: SemanticAnimationKind.StandStill }, + }], startAndEndPos); + }) + case "custom": if (move.parameters.custom.includes("mirrored mad robin")) { return handleCircleMove(({ id, startPos }) => {