Use ball first-hit rays and retry native prop-occluded split selections through normal merge
This commit is contained in:
@@ -24,6 +24,14 @@ function ZoomOut([int]$Stage,$CurrentBoard) {
|
||||
Check "stage-$Stage-pinch-preserves-board" ((Same $CurrentBoard.balls $after.balls)-and(Same $CurrentBoard.groups $after.groups)-and(Same $CurrentBoard.countedBallIds $after.countedBallIds)-and$after.camera.distance-gt$CurrentBoard.camera.distance) 'Actual two-finger zoom-out; no ball, membership or count edits'
|
||||
return $after
|
||||
}
|
||||
function RevealBall([int]$Stage,[string]$Id,[string]$Name) {
|
||||
for($view=0;$view-lt12;$view++){
|
||||
$board=Board (Save "$Name-view-$view") $Stage
|
||||
if(BallClear $board $Id){return $board}
|
||||
Orbit "$Name-orbit-$view" $board
|
||||
}
|
||||
throw "No safe first-hit view for actual ball $Id within a full native orbit."
|
||||
}
|
||||
function MergeReal([int]$Stage,[string]$Name) {
|
||||
for($attempt=0;$attempt-lt16;$attempt++) {
|
||||
$before=Save "$Name-before-$attempt"; $board=Board $before $Stage
|
||||
@@ -35,8 +43,9 @@ function MergeReal([int]$Stage,[string]$Name) {
|
||||
$delta=[Numerics.Vector3]::Transform([Numerics.Vector3]::new($s.x-$t.x,$s.y-$t.y,$s.z-$t.z),[Numerics.Quaternion]::Inverse($rotation))
|
||||
[pscustomobject]@{sid=$sid;tid=$tid;depth=[Math]::Abs($delta.Z);size=$source.ballIds.Count}
|
||||
}}}}) | Sort-Object depth,size
|
||||
$pair=$pairs[0]
|
||||
if($pair.depth-lt.9) {
|
||||
$pair=$null
|
||||
foreach($candidate in $pairs){if($candidate.depth-lt.9-and(BallClear $board $candidate.sid)){$pair=$candidate;break}}
|
||||
if($pair) {
|
||||
$start=BallPoint $board $pair.sid; $end=BallPoint $board $pair.tid
|
||||
# Try a short lateral contact offset, then orbit to expose another depth plane if blocked.
|
||||
$offset=if($attempt%2-eq0){-35}else{35}
|
||||
@@ -53,15 +62,22 @@ function SplitReal([int]$Stage,[int]$Selected,[string]$Name) {
|
||||
$before=Save "$Name-before-$attempt"; $board=Board $before $Stage
|
||||
$group=@($board.groups|Sort-Object {$_.ballIds.Count} -Descending)[0]
|
||||
$ids=@(if($Stage-eq13-and$Selected-eq2){$group.ballIds[0];$group.ballIds[-1]}else{$group.ballIds|Select-Object -First $Selected})
|
||||
if(@($ids|Where-Object{!(BallClear $board $_)}).Count){Orbit "$Name-reveal-selected-$attempt" $board;continue}
|
||||
$board=RevealBall $Stage $ids[0] "$Name-choose-reveal-$attempt"
|
||||
TapBall "$Name-choose-$attempt" $board $ids[0]
|
||||
Step "$Name-mode-$attempt" @('shell','input','tap','312','832')
|
||||
foreach($id in $ids){TapBall "$Name-select-$attempt-$id" $board $id}
|
||||
foreach($id in $ids){$board=RevealBall $Stage $id "$Name-select-reveal-$attempt-$id";TapBall "$Name-select-$attempt-$id" $board $id}
|
||||
$board=RevealBall $Stage $ids[0] "$Name-drag-reveal-$attempt"
|
||||
$point=BallPoint $board $ids[0]
|
||||
Step "$Name-drag-$attempt" @('shell','input','swipe',"$($point[0])","$($point[1])","$($point[0])","$($point[1]-160)",'500')
|
||||
$after=Save "$Name-after-$attempt"; $actual=Board $after $Stage
|
||||
if($null-eq$actual){$actual=$after.latestFreePlay}
|
||||
if($actual.groups.Count-gt$board.groups.Count){
|
||||
if(@($actual.groups|Where-Object{(($_.ballIds|Sort-Object)-join',')-eq(($ids|Sort-Object)-join',')}).Count-ne1){
|
||||
$commands.Add(@{command='Actual split selected IDs differ: preserve attempt and retry through native merge/orbit';expected=$ids;actualGroups=$actual.groups;utc=[DateTime]::UtcNow.ToString('o')})
|
||||
MergeReal $Stage "$Name-remerge-$attempt"|Out-Null
|
||||
Orbit "$Name-retry-view-$attempt" (Board (Save "$Name-retry-state-$attempt") $Stage)
|
||||
continue
|
||||
}
|
||||
Check "$Name-exact-selected-ids-$attempt" (@($actual.groups|Where-Object{(($_.ballIds|Sort-Object)-join',')-eq(($ids|Sort-Object)-join',')}).Count-eq1) 'Native split group is exactly the tapped selection, not an occluded substitute'
|
||||
return $after
|
||||
}
|
||||
@@ -98,7 +114,7 @@ function CountRemaining([int]$Stage) {
|
||||
$uncounted=@($board.balls|Where-Object {$board.countedBallIds-notcontains$_.id})
|
||||
$beforeCount=$board.countedBallIds.Count
|
||||
$id=$null
|
||||
foreach($ball in $uncounted){if(WorldSafe (BallPoint $board $ball.id)){$id=$ball.id;break}}
|
||||
foreach($ball in $uncounted){if(BallClear $board $ball.id){$id=$ball.id;break}}
|
||||
if(!$id){Orbit "stage-$Stage-count-safe-view-$attempt" $board;continue}
|
||||
TapBall "stage-$Stage-count-$attempt" $board $id
|
||||
$after=Save "stage-$Stage-count-$attempt-after"; $newBoard=Board $after $Stage
|
||||
|
||||
Reference in New Issue
Block a user