Compare commits

...

2 Commits

Author SHA1 Message Date
Daniel Perelman 1caab5d112 Initial support for ricochet in hey. 2023-10-14 15:08:41 -07:00
Daniel Perelman 0bb4e2c051 Fix CirclePosition.fromSides() 2023-10-14 15:08:15 -07:00
2 changed files with 80 additions and 22 deletions

View File

@ -1972,16 +1972,14 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
case "hey":
type HeyStep = {
kind: "StandStill" | "Loop" | "CenterPass" | "EndsPassIn" | "EndsPassOut",
kind: "StandStill" | "Loop" | "CenterPass" | "EndsPassIn" | "EndsPassOut" | "Ricochet",
endPosition: SemanticPosition,
}
if (move.parameters.dir !== "across") {
throw new Error("Unsupported hey direction: " + move.parameters.dir);
}
if (move.parameters.rico1 || move.parameters.rico2 || move.parameters.rico3 || move.parameters.rico4) {
throw new Error("Ricochet hey is unsupported.");
}
let heyParts: number;
switch (move.parameters.until) {
case "half":
@ -2080,6 +2078,14 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
// TODO Loop should probably be its own kind? Or RotateAround?
kind: SemanticAnimationKind.Linear,
minRotation: endsShoulder === Hand.Right ? +180 : -180,
} : heyStep.kind === "Ricochet" ? {
// TODO This is a hack.
kind: SemanticAnimationKind.PassBy,
around: heyStep.endPosition.which.leftRightSide(),
withHands: false,
otherPath: "Swap",
facing: "Start",
side: endsShoulder,
} : {
kind: SemanticAnimationKind.PassBy,
around: heyStep.kind === "CenterPass" ? "Center" : heyStep.endPosition.which.leftRightSide(),
@ -2091,7 +2097,10 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
heyStep,
};
}
function continueHey(prevStep: HeyStep, stepsLeft: number): HeyStep {
function continueHey(prevStep: HeyStep, stepsLeft: number, beenInCenter: boolean): HeyStep {
// TODO Not sure why type checker requires rechecking this here.
if (move.move !== "hey") throw new Error("Unreachable.");
// Continuing hey so everyone is either passing (in center or on ends) or looping on ends.
if (prevStep.endPosition.kind === PositionKind.Circle) {
if (prevStep.endPosition.facing === prevStep.endPosition.which.facingAcross()) {
@ -2155,12 +2164,44 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
},
}
}
else if (!isFacingSide) {
const rico = inCenterFirst
? beenInCenter
? move.parameters.rico3
: move.parameters.rico1
: beenInCenter
? move.parameters.rico4
: move.parameters.rico2;
if (rico) {
const onLeftSide = prevStep.endPosition.which.isLeft();
return {
kind: "Ricochet",
endPosition: {
...prevStep.endPosition,
kind: PositionKind.Circle,
which: CirclePosition.fromSides(prevStep.endPosition.which.leftRightSide(),
// TODO might be swapped
(endsShoulder === Hand.Left) === onLeftSide ? CircleSide.Top : CircleSide.Bottom),
facing: onLeftSide ? Facing.Left : Facing.Right,
}
}
} else {
return {
kind: "CenterPass",
endPosition: {
...prevStep.endPosition,
which: prevStep.endPosition.which.swapSides()
},
}
}
}
else {
return {
kind: isFacingSide ? (inMiddle ? "EndsPassOut" : "EndsPassIn") : "CenterPass",
kind: inMiddle ? "EndsPassOut" : "EndsPassIn",
endPosition: {
...prevStep.endPosition,
which: isFacingSide ? prevStep.endPosition.which.swapOnSide() : prevStep.endPosition.which.swapSides()
which: prevStep.endPosition.which.swapOnSide()
},
}
}
@ -2169,13 +2210,15 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
}
}
const inCenterFirst = firstPassInCenter && findPairOpposite(move.parameters.who, id) !== null
|| move.parameters.who2 && findPairOpposite(move.parameters.who2, id) !== null;
let firstHeyStep: HeyStep;
let startingPos: SemanticPosition;
if (firstPassInCenter) {
if (startPos.kind !== PositionKind.Circle) {
throw new Error("Hey starting in center not from circle is unsupported.");
}
const inCenterFirst = findPairOpposite(move.parameters.who, id) !== null;
startingPos = {
kind: startPos.kind,
which: startPos.which,
@ -2184,16 +2227,29 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
lineOffset: startPos.lineOffset,
};
if (inCenterFirst) {
firstHeyStep = {
kind: "CenterPass",
endPosition: {
kind: PositionKind.ShortLines,
which: startPos.which.isLeft() ? ShortLinesPosition.MiddleRight : ShortLinesPosition.MiddleLeft,
facing: startingPos.facing,
setOffset: startPos.setOffset,
lineOffset: startPos.lineOffset,
}
};
if (move.parameters.rico1) {
firstHeyStep = {
kind: "Ricochet",
endPosition: {
kind: PositionKind.Circle,
which: startPos.which.swapUpAndDown(),
facing: startPos.which.facingOut(),
setOffset: startPos.setOffset,
lineOffset: startPos.lineOffset,
}
};
} else {
firstHeyStep = {
kind: "CenterPass",
endPosition: {
kind: PositionKind.ShortLines,
which: startPos.which.isLeft() ? ShortLinesPosition.MiddleRight : ShortLinesPosition.MiddleLeft,
facing: startingPos.facing,
setOffset: startPos.setOffset,
lineOffset: startPos.lineOffset,
}
};
}
} else {
firstHeyStep = {
kind: "StandStill",
@ -2220,9 +2276,11 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
}
const heySteps: HeyStep[] = [firstHeyStep];
let beenInCenter = firstHeyStep.kind === "CenterPass" || firstHeyStep.kind === "Ricochet";
for(let i = 1; i < heyParts; i++) {
const isLast = i === heyParts - 1;
const nextHeyStep = continueHey(heySteps[i - 1], heyParts - i - 1);
const nextHeyStep = continueHey(heySteps[i - 1], heyParts - i - 1, beenInCenter);
beenInCenter ||= nextHeyStep.kind === "CenterPass" || nextHeyStep.kind === "Ricochet";
heySteps.push(nextHeyStep);
}
return combine(heySteps.map(heyStepToPartialLowLevelMove), { ...startingPos, hands: undefined });

View File

@ -38,9 +38,9 @@ export class CirclePosition {
? topBottomSide === CircleSide.Top
? CirclePosition.TopLeft
: CirclePosition.BottomLeft
: topBottomSide === CircleSide.Bottom
? CirclePosition.BottomLeft
: CirclePosition.BottomLeft;
: topBottomSide === CircleSide.Top
? CirclePosition.TopRight
: CirclePosition.BottomRight;
}
private static enumValueToNumber(enumValue: CirclePositionEnum) : number {