Search counting targets at safe alternate camera elevations

This commit is contained in:
NINI
2026-10-10 15:30:07 +09:00
parent 3bfcac8a58
commit d4128d713d
2 changed files with 95 additions and 4 deletions
+16 -4
View File
@@ -3,13 +3,13 @@ param([Parameter(Mandatory)][string]$ApkPath,[Parameter(Mandatory)][string]$Evid
# This suite never pushes a save or injects completed stages. Every checkpoint is read from the APK.
function Board($State,[int]$Stage) { return @($State.puzzleStates | Where-Object stageId -eq $Stage)[0] }
function Counts($Board) { return (@($Board.groups | ForEach-Object {$_.ballIds.Count} | Sort-Object) -join ',') }
function Orbit([string]$Name,$CurrentBoard,[switch]$Pitch,[int]$YawPixels=120) {
function Orbit([string]$Name,$CurrentBoard,[switch]$Pitch,[int]$YawPixels=120,[int]$PitchPixels=120) {
if(!$CurrentBoard){$saved=Save "$Name-view";$CurrentBoard=if($saved.puzzleStates.Count){$saved.puzzleStates[-1]}else{$saved.latestFreePlay}}
$points=@($CurrentBoard.balls|ForEach-Object{,(BallPoint $CurrentBoard $_.id)})
foreach($y in @(300,700)){foreach($x in @(650,900,1150,1400,1650)){
if(@($points|Where-Object{[Math]::Pow($_[0]-$x,2)+[Math]::Pow($_[1]-$y,2)-lt22500}).Count-eq0){
$endX=if($Pitch){$x}else{$x+$YawPixels};$endY=if($Pitch){$y+120}else{$y}
if($endY-gt750){continue}
$endX=if($Pitch){$x}else{$x+$YawPixels};$endY=if($Pitch){$y+$PitchPixels}else{$y}
if($endY-lt280-or$endY-gt750){continue}
if($YawPixels-ne120-and!$Pitch){
# Latch the real >14px orbit drag, then reverse to the small net yaw.
try{
@@ -257,7 +257,19 @@ function CountRemaining([int]$Stage) {
$beforeCount=$board.countedBallIds.Count
$id=$null
foreach($ball in $uncounted){if(BallClear $board $ball.id){$id=$ball.id;break}}
if(!$id){Orbit "stage-$Stage-count-safe-view-$attempt" $board;continue}
if(!$id){
$rotation=[Numerics.Quaternion]::new($board.camera.rotation.x,$board.camera.rotation.y,$board.camera.rotation.z,$board.camera.rotation.w)
# Local pitch reverses its elevation effect after crossing the vertical pole.
$pitchPixels=if([Numerics.Vector3]::Transform([Numerics.Vector3]::UnitY,$rotation).Y-ge0){-120}else{120}
if([Numerics.Vector3]::Transform(-[Numerics.Vector3]::UnitZ,$rotation).Y-lt.5){$pitchPixels=-$pitchPixels}
Orbit "stage-$Stage-count-safe-view-$attempt" $board -Pitch:($attempt%4-eq3) -PitchPixels $pitchPixels
$view=Save "stage-$Stage-count-view-after-$attempt"
$unchanged=$view|ConvertTo-Json -Depth 20|ConvertFrom-Json
$viewBoard=Board $unchanged $Stage
if($viewBoard){$viewBoard.camera=$board.camera}
Check "stage-$Stage-count-view-preserves-whole-save-$attempt" (Same $state $unchanged) 'Only the actual manual view may change while searching for an uncounted first hit'
continue
}
TapBall "stage-$Stage-count-$attempt" $board $id
$after=Save "stage-$Stage-count-$attempt-after"; $newBoard=Board $after $Stage
if($null-eq$newBoard){return $after}