@@ -370,85 +370,87 @@ export class Player {
370
370
while ( found_new_playable ) {
371
371
found_new_playable = false ;
372
372
373
- for ( const order of state . hands . flat ( ) ) {
374
- if ( ignoreOrders ?. has ( order ) )
375
- continue ;
376
-
377
- const card = this . thoughts [ order ] ;
378
-
379
- if ( ! card . saved || good_touch_elim . has ( card ) || linked_orders . has ( order ) || unknown_plays . has ( order ) || already_played . has ( order ) )
380
- continue ;
381
-
382
- const fake_wcs = this . waiting_connections . filter ( wc =>
383
- wc . focus === order && ! state . deck [ wc . focus ] . matches ( wc . inference , { assume : true } ) ) ;
384
-
385
- // Ignore all waiting connections that will be proven wrong
386
- const playable = state . hasConsistentInferences ( card ) &&
387
- ( delayed_playable ( card . possible . array ) ||
388
- delayed_playable ( card . inferred . subtract ( fake_wcs . flatMap ( wc => wc . inference ) ) . array ) ||
389
- ( card . finessed && delayed_playable ( [ card ] ) ) ||
390
- this . play_links . some ( pl => pl . connected === order && pl . orders . every ( o => unknown_plays . has ( o ) ) ) ) ;
373
+ for ( let i = 0 ; i < state . numPlayers ; i ++ ) {
374
+ for ( const order of state . hands [ i ] ) {
375
+ if ( ignoreOrders ?. has ( order ) )
376
+ continue ;
391
377
392
- if ( ! playable )
393
- continue ;
378
+ const card = this . thoughts [ order ] ;
394
379
395
- const id = card . identity ( { infer : true } ) ;
396
- const actual_id = state . deck [ order ] . identity ( ) ;
380
+ if ( ! card . saved || good_touch_elim . has ( card ) || linked_orders . has ( order ) || unknown_plays . has ( order ) || already_played . has ( order ) )
381
+ continue ;
397
382
398
- // Do not allow false updating of hypo stacks
399
- if ( this . playerIndex === - 1 && (
400
- ( id && state . deck . filter ( c => c ?. matches ( id ) && c . order !== order ) . length === cardCount ( state . variant , id ) ) ||
401
- ( actual_id && ! card . inferred . has ( actual_id ) ) // None of the inferences match
402
- ) )
403
- continue ;
383
+ const fake_wcs = this . waiting_connections . filter ( wc =>
384
+ wc . focus === order && ! state . deck [ wc . focus ] . matches ( wc . inference , { assume : true } ) ) ;
404
385
405
- if ( this . playerIndex === - 1 && actual_id ) {
406
- const existing = Array . from ( unknown_plays ) . find ( o => state . deck [ o ] . matches ( actual_id ) ) ;
386
+ // Ignore all waiting connections that will be proven wrong
387
+ const playable = state . hasConsistentInferences ( card ) &&
388
+ ( delayed_playable ( card . possible . array ) ||
389
+ delayed_playable ( card . inferred . subtract ( fake_wcs . flatMap ( wc => wc . inference ) ) . array ) ||
390
+ ( card . finessed && delayed_playable ( [ card ] ) ) ||
391
+ this . play_links . some ( pl => pl . connected === order && pl . orders . every ( o => unknown_plays . has ( o ) ) ) ) ;
407
392
408
- // An unknown play matches this identity, try swapping it out later
409
- if ( existing !== undefined ) {
410
- const hash = logCard ( actual_id ) ;
411
- duplicated_plays . set ( hash , ( duplicated_plays . get ( hash ) ?? [ existing ] ) . concat ( order ) ) ;
393
+ if ( ! playable )
412
394
continue ;
413
- }
414
- }
415
395
416
- if ( id === undefined ) {
417
- // Playable, but the player doesn't know what card it is
418
- unknown_plays . add ( order ) ;
419
- already_played . add ( order ) ;
420
- found_new_playable = true ;
396
+ const id = card . identity ( { infer : true , symmetric : this . playerIndex === i } ) ;
397
+ const actual_id = state . deck [ order ] . identity ( ) ;
421
398
422
- const fulfilled_links = this . links . filter ( link =>
423
- link . promised && link . orders . includes ( order ) && link . orders . every ( o => unknown_plays . has ( o ) ) ) ;
399
+ // Do not allow false updating of hypo stacks
400
+ if ( this . playerIndex === - 1 && (
401
+ ( id && state . deck . filter ( c => c ?. matches ( id ) && c . order !== order ) . length === cardCount ( state . variant , id ) ) ||
402
+ ( actual_id && ! card . inferred . has ( actual_id ) ) // None of the inferences match
403
+ ) )
404
+ continue ;
424
405
425
- // All cards in a promised link will be played
426
- for ( const link of fulfilled_links ) {
427
- const id2 = link . identities [ 0 ] ;
406
+ if ( this . playerIndex === - 1 && actual_id ) {
407
+ const existing = Array . from ( unknown_plays ) . find ( o => state . deck [ o ] . matches ( actual_id ) ) ;
428
408
429
- if ( id2 . rank !== hypo_stacks [ id2 . suitIndex ] + 1 ) {
430
- logger . warn ( `tried to add ${ logCard ( id2 ) } onto hypo stacks, but they were at ${ hypo_stacks [ id2 . suitIndex ] } ??` ) ;
409
+ // An unknown play matches this identity, try swapping it out later
410
+ if ( existing !== undefined ) {
411
+ const hash = logCard ( actual_id ) ;
412
+ duplicated_plays . set ( hash , ( duplicated_plays . get ( hash ) ?? [ existing ] ) . concat ( order ) ) ;
413
+ continue ;
431
414
}
432
- else {
433
- hypo_stacks [ id2 . suitIndex ] = id2 . rank ;
434
- good_touch_elim = good_touch_elim . union ( id2 ) ;
415
+ }
416
+
417
+ if ( id === undefined ) {
418
+ // Playable, but the player doesn't know what card it is
419
+ unknown_plays . add ( order ) ;
420
+ already_played . add ( order ) ;
421
+ found_new_playable = true ;
422
+
423
+ const fulfilled_links = this . links . filter ( link =>
424
+ link . promised && link . orders . includes ( order ) && link . orders . every ( o => unknown_plays . has ( o ) ) ) ;
425
+
426
+ // All cards in a promised link will be played
427
+ for ( const link of fulfilled_links ) {
428
+ const id2 = link . identities [ 0 ] ;
429
+
430
+ if ( id2 . rank !== hypo_stacks [ id2 . suitIndex ] + 1 ) {
431
+ logger . warn ( `tried to add ${ logCard ( id2 ) } onto hypo stacks, but they were at ${ hypo_stacks [ id2 . suitIndex ] } ??` ) ;
432
+ }
433
+ else {
434
+ hypo_stacks [ id2 . suitIndex ] = id2 . rank ;
435
+ good_touch_elim = good_touch_elim . union ( id2 ) ;
436
+ }
435
437
}
438
+ continue ;
436
439
}
437
- continue ;
438
- }
439
440
440
- const { suitIndex, rank } = id ;
441
+ const { suitIndex, rank } = id ;
441
442
442
- if ( rank !== hypo_stacks [ suitIndex ] + 1 ) {
443
- // e.g. a duplicated 1 before any 1s have played will have all bad possibilities eliminated by good touch
444
- logger . warn ( `tried to add new playable card ${ logCard ( id ) } ${ order } , hypo stacks at ${ hypo_stacks [ suitIndex ] } ` ) ;
445
- continue ;
446
- }
443
+ if ( rank !== hypo_stacks [ suitIndex ] + 1 ) {
444
+ // e.g. a duplicated 1 before any 1s have played will have all bad possibilities eliminated by good touch
445
+ logger . warn ( `tried to add new playable card ${ logCard ( id ) } ${ order } , hypo stacks at ${ hypo_stacks [ suitIndex ] } ` ) ;
446
+ continue ;
447
+ }
447
448
448
- hypo_stacks [ suitIndex ] = rank ;
449
- good_touch_elim = good_touch_elim . union ( id ) ;
450
- found_new_playable = true ;
451
- already_played . add ( order ) ;
449
+ hypo_stacks [ suitIndex ] = rank ;
450
+ good_touch_elim = good_touch_elim . union ( id ) ;
451
+ found_new_playable = true ;
452
+ already_played . add ( order ) ;
453
+ }
452
454
}
453
455
}
454
456
0 commit comments