-rw-r--r-- | noncore/games/go/goplayutils.c | 2 | ||||
-rw-r--r-- | noncore/games/go/killable.c | 4 |
2 files changed, 3 insertions, 3 deletions
diff --git a/noncore/games/go/goplayutils.c b/noncore/games/go/goplayutils.c index 9e2ce4c..91c6db2 100644 --- a/noncore/games/go/goplayutils.c +++ b/noncore/games/go/goplayutils.c | |||
@@ -535,769 +535,769 @@ respreicen() | |||
535 | maxGroupID = gID; | 535 | maxGroupID = gID; |
536 | newGID = gID; | 536 | newGID = gID; |
537 | grpMark = 0; | 537 | grpMark = 0; |
538 | } /* respreicen */ | 538 | } /* respreicen */ |
539 | 539 | ||
540 | /* | 540 | /* |
541 | play z at [x, y]. | 541 | play z at [x, y]. |
542 | killFlag is set true if anything is killed. | 542 | killFlag is set true if anything is killed. |
543 | */ | 543 | */ |
544 | killGroup(x, y, me, him) | 544 | killGroup(x, y, me, him) |
545 | short x, y, me, him; | 545 | short x, y, me, him; |
546 | { /* killGroup */ | 546 | { /* killGroup */ |
547 | #ifdef DEBUG | 547 | #ifdef DEBUG |
548 | printf( "killGroup\n" ); | 548 | printf( "killGroup\n" ); |
549 | #endif | 549 | #endif |
550 | playMark = playMark + 1; | 550 | playMark = playMark + 1; |
551 | /* record this kill */ | 551 | /* record this kill */ |
552 | playStack[playMark].kind = rem; | 552 | playStack[playMark].kind = rem; |
553 | playStack[playMark].uval.rem.who = him; | 553 | playStack[playMark].uval.rem.who = him; |
554 | playStack[playMark].uval.rem.xl = x; | 554 | playStack[playMark].uval.rem.xl = x; |
555 | playStack[playMark].uval.rem.yl = y; | 555 | playStack[playMark].uval.rem.yl = y; |
556 | playStack[playMark].gID = groupIDs[x][y]; | 556 | playStack[playMark].gID = groupIDs[x][y]; |
557 | playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum; | 557 | playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum; |
558 | if (showTrees) | 558 | if (showTrees) |
559 | rstone(x, y); | 559 | rstone(x, y); |
560 | numCapt = numCapt + 1; | 560 | numCapt = numCapt + 1; |
561 | bord[x][y] = 0; | 561 | bord[x][y] = 0; |
562 | groupIDs[x][y] = 0; | 562 | groupIDs[x][y] = 0; |
563 | if (x > 0) | 563 | if (x > 0) |
564 | { | 564 | { |
565 | if (bord[x - 1][y] == me) | 565 | if (bord[x - 1][y] == me) |
566 | { | 566 | { |
567 | nlcGroup.indx = nlcGroup.indx + 1; | 567 | nlcGroup.indx = nlcGroup.indx + 1; |
568 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; | 568 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; |
569 | } | 569 | } |
570 | else if (bord[x - 1][y] == him) | 570 | else if (bord[x - 1][y] == him) |
571 | killGroup(x - 1, y, me , him); | 571 | killGroup(x - 1, y, me , him); |
572 | } | 572 | } |
573 | if (x < maxPoint) | 573 | if (x < maxPoint) |
574 | { | 574 | { |
575 | if (bord[x + 1][y] == me) | 575 | if (bord[x + 1][y] == me) |
576 | { | 576 | { |
577 | nlcGroup.indx = nlcGroup.indx + 1; | 577 | nlcGroup.indx = nlcGroup.indx + 1; |
578 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; | 578 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; |
579 | } | 579 | } |
580 | else if (bord[x + 1][y] == him) | 580 | else if (bord[x + 1][y] == him) |
581 | killGroup(x + 1, y, me, him); | 581 | killGroup(x + 1, y, me, him); |
582 | } | 582 | } |
583 | if (y > 0) | 583 | if (y > 0) |
584 | { | 584 | { |
585 | if (bord[x][y - 1] == me) | 585 | if (bord[x][y - 1] == me) |
586 | { | 586 | { |
587 | nlcGroup.indx = nlcGroup.indx + 1; | 587 | nlcGroup.indx = nlcGroup.indx + 1; |
588 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; | 588 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; |
589 | } | 589 | } |
590 | else if (bord[x][y - 1] == him) | 590 | else if (bord[x][y - 1] == him) |
591 | killGroup(x, y - 1, me, him); | 591 | killGroup(x, y - 1, me, him); |
592 | } | 592 | } |
593 | if (y < maxPoint) | 593 | if (y < maxPoint) |
594 | { | 594 | { |
595 | if (bord[x][y + 1] == me) | 595 | if (bord[x][y + 1] == me) |
596 | { | 596 | { |
597 | nlcGroup.indx = nlcGroup.indx + 1; | 597 | nlcGroup.indx = nlcGroup.indx + 1; |
598 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; | 598 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; |
599 | } | 599 | } |
600 | else if (bord[x][y + 1] == him) | 600 | else if (bord[x][y + 1] == him) |
601 | killGroup(x, y + 1, me, him); | 601 | killGroup(x, y + 1, me, him); |
602 | } | 602 | } |
603 | } /* killGroup */ | 603 | } /* killGroup */ |
604 | 604 | ||
605 | mergeGroup(sGID, myGID) | 605 | mergeGroup(sGID, myGID) |
606 | short sGID, myGID; | 606 | short sGID, myGID; |
607 | { /* mergeGroup */ | 607 | { /* mergeGroup */ |
608 | short i; | 608 | short i; |
609 | #ifdef DEBUG | 609 | #ifdef DEBUG |
610 | printf( "mergeGroup\n" ); | 610 | printf( "mergeGroup\n" ); |
611 | #endif | 611 | #endif |
612 | for (i = 1; i <= newGID; i++) | 612 | for (i = 1; i <= newGID; i++) |
613 | if (gMap[i] == sGID) | 613 | if (gMap[i] == sGID) |
614 | { | 614 | { |
615 | playMark = playMark + 1; | 615 | playMark = playMark + 1; |
616 | playStack[playMark].kind = reMap; | 616 | playStack[playMark].kind = reMap; |
617 | playStack[playMark].gID = i; | 617 | playStack[playMark].gID = i; |
618 | playStack[playMark].uval.reMap.oldGID = sGID; | 618 | playStack[playMark].uval.reMap.oldGID = sGID; |
619 | gMap[i] = myGID; | 619 | gMap[i] = myGID; |
620 | } | 620 | } |
621 | } /* mergeGroup */ | 621 | } /* mergeGroup */ |
622 | 622 | ||
623 | tryPlay(x, y, z) | 623 | tryPlay(x, y, z) |
624 | short x, y, z; | 624 | short x, y, z; |
625 | { /* plei */ | 625 | { /* plei */ |
626 | short i, me, him, myGID; | 626 | short i, me, him, myGID; |
627 | short isNew; | 627 | short isNew; |
628 | #ifdef DEBUG | 628 | #ifdef DEBUG |
629 | printf( "tryPlay\n" ); | 629 | printf( "tryPlay\n" ); |
630 | #endif | 630 | #endif |
631 | me = z; | 631 | me = z; |
632 | him = -me; | 632 | him = -me; |
633 | killFlag = FALSE; /* set true if something is killed */ | 633 | killFlag = FALSE; /* set true if something is killed */ |
634 | numCapt = 0; | 634 | numCapt = 0; |
635 | tryLevel = tryLevel + 1; | 635 | tryLevel = tryLevel + 1; |
636 | isNew = FALSE; | 636 | isNew = FALSE; |
637 | bord[x][y] = z; /* play the stone */ | 637 | bord[x][y] = z; /* play the stone */ |
638 | if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */ | 638 | if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */ |
639 | myGID = gMap[groupIDs[x - 1][y]]; | 639 | myGID = gMap[groupIDs[x - 1][y]]; |
640 | else if ((x < maxPoint) && (bord[x + 1][y] == me)) | 640 | else if ((x < maxPoint) && (bord[x + 1][y] == me)) |
641 | myGID = gMap[groupIDs[x + 1][y]]; | 641 | myGID = gMap[groupIDs[x + 1][y]]; |
642 | else if ((y > 0) && (bord[x][y - 1] == me)) | 642 | else if ((y > 0) && (bord[x][y - 1] == me)) |
643 | myGID = gMap[groupIDs[x][y - 1]]; | 643 | myGID = gMap[groupIDs[x][y - 1]]; |
644 | else if ((y < maxPoint) && (bord[x][y + 1] == me)) | 644 | else if ((y < maxPoint) && (bord[x][y + 1] == me)) |
645 | myGID = gMap[groupIDs[x][y + 1]]; | 645 | myGID = gMap[groupIDs[x][y + 1]]; |
646 | else /* nobody to connect to */ | 646 | else /* nobody to connect to */ |
647 | { | 647 | { |
648 | newGID = newGID + 1; | 648 | newGID = newGID + 1; |
649 | isNew = TRUE; | 649 | isNew = TRUE; |
650 | myGID = newGID; | 650 | myGID = newGID; |
651 | gList[myGID].groupMark = 0; | 651 | gList[myGID].groupMark = 0; |
652 | gList[myGID].atLevel = tryLevel; | 652 | gList[myGID].atLevel = tryLevel; |
653 | gList[myGID].isLive = FALSE; | 653 | gList[myGID].isLive = FALSE; |
654 | gList[myGID].numEyes = -1; | 654 | gList[myGID].numEyes = -1; |
655 | gList[myGID].size = -1; | 655 | gList[myGID].size = -1; |
656 | gList[myGID].lx = x; | 656 | gList[myGID].lx = x; |
657 | gList[myGID].ly = y; | 657 | gList[myGID].ly = y; |
658 | gMap[myGID] = myGID; | 658 | gMap[myGID] = myGID; |
659 | } | 659 | } |
660 | groupIDs[x][y] = myGID; | 660 | groupIDs[x][y] = myGID; |
661 | playMark = playMark + 1; | 661 | playMark = playMark + 1; |
662 | /* record this move */ | 662 | /* record this move */ |
663 | playStack[playMark].kind = add; | 663 | playStack[playMark].kind = add; |
664 | playStack[playMark].uval.add.who = me; | 664 | playStack[playMark].uval.add.who = me; |
665 | playStack[playMark].uval.add.xl = x; | 665 | playStack[playMark].uval.add.xl = x; |
666 | playStack[playMark].uval.add.yl = y; | 666 | playStack[playMark].uval.add.yl = y; |
667 | playStack[playMark].gID = myGID; | 667 | playStack[playMark].gID = myGID; |
668 | playStack[playMark].uval.add.sNumber = 0; | 668 | playStack[playMark].uval.add.sNumber = 0; |
669 | if (isNew) | 669 | if (isNew) |
670 | playStack[playMark].uval.add.nextGID = newGID - 1; | 670 | playStack[playMark].uval.add.nextGID = newGID - 1; |
671 | else | 671 | else |
672 | playStack[playMark].uval.add.nextGID = newGID; | 672 | playStack[playMark].uval.add.nextGID = newGID; |
673 | if (showTrees) | 673 | if (showTrees) |
674 | sstone(me, x, y, 0); | 674 | sstone(me, x, y, 0); |
675 | /* merge adjacent groups */ | 675 | /* merge adjacent groups */ |
676 | if ((x > 0) && (bord[x - 1][y] == me) && | 676 | if ((x > 0) && (bord[x - 1][y] == me) && |
677 | (gMap[groupIDs[x - 1][y]] != myGID)) | 677 | (gMap[groupIDs[x - 1][y]] != myGID)) |
678 | mergeGroup(gMap[groupIDs[x - 1][y]], myGID); | 678 | mergeGroup(gMap[groupIDs[x - 1][y]], myGID); |
679 | if ((x < maxPoint) && (bord[x + 1][y] == me) && | 679 | if ((x < maxPoint) && (bord[x + 1][y] == me) && |
680 | (gMap[groupIDs[x + 1][y]] != myGID)) | 680 | (gMap[groupIDs[x + 1][y]] != myGID)) |
681 | mergeGroup(gMap[groupIDs[x + 1][y]], myGID); | 681 | mergeGroup(gMap[groupIDs[x + 1][y]], myGID); |
682 | if ((y > 0) && (bord[x][y - 1] == me) && | 682 | if ((y > 0) && (bord[x][y - 1] == me) && |
683 | (gMap[groupIDs[x][y - 1]] != myGID)) | 683 | (gMap[groupIDs[x][y - 1]] != myGID)) |
684 | mergeGroup(gMap[groupIDs[x][y - 1]], myGID); | 684 | mergeGroup(gMap[groupIDs[x][y - 1]], myGID); |
685 | if ((y < maxPoint) && (bord[x][y + 1] == me) && | 685 | if ((y < maxPoint) && (bord[x][y + 1] == me) && |
686 | (gMap[groupIDs[x][y + 1]] != myGID)) | 686 | (gMap[groupIDs[x][y + 1]] != myGID)) |
687 | mergeGroup(gMap[groupIDs[x][y + 1]], myGID); | 687 | mergeGroup(gMap[groupIDs[x][y + 1]], myGID); |
688 | /* kill opposing groups, listing affected groups */ | 688 | /* kill opposing groups, listing affected groups */ |
689 | nlcGroup.indx = 1; | 689 | nlcGroup.indx = 1; |
690 | nlcGroup.v[1] = myGID; /* init list to include me */ | 690 | nlcGroup.v[1] = myGID; /* init list to include me */ |
691 | if ((x > 0) && (bord[x - 1][y] == him) && | 691 | if ((x > 0) && (bord[x - 1][y] == him) && |
692 | (gList[gMap[groupIDs[x - 1][y]]].libC == 1)) | 692 | (gList[gMap[groupIDs[x - 1][y]]].libC == 1)) |
693 | { | 693 | { |
694 | killFlag = TRUE; | 694 | killFlag = TRUE; |
695 | killGroup(x - 1, y, me, him); | 695 | killGroup(x - 1, y, me, him); |
696 | } | 696 | } |
697 | if ((x < maxPoint) && (bord[x + 1][y] == him) && | 697 | if ((x < maxPoint) && (bord[x + 1][y] == him) && |
698 | (gList[gMap[groupIDs[x + 1][y]]].libC == 1)) | 698 | (gList[gMap[groupIDs[x + 1][y]]].libC == 1)) |
699 | { | 699 | { |
700 | killFlag = TRUE; | 700 | killFlag = TRUE; |
701 | killGroup(x + 1, y, me, him); | 701 | killGroup(x + 1, y, me, him); |
702 | } | 702 | } |
703 | if ((y > 0) && (bord[x][y - 1] == him) && | 703 | if ((y > 0) && (bord[x][y - 1] == him) && |
704 | (gList[gMap[groupIDs[x][y - 1]]].libC == 1)) | 704 | (gList[gMap[groupIDs[x][y - 1]]].libC == 1)) |
705 | { | 705 | { |
706 | killFlag = TRUE; | 706 | killFlag = TRUE; |
707 | killGroup(x, y - 1, me, him); | 707 | killGroup(x, y - 1, me, him); |
708 | } | 708 | } |
709 | if ((y < maxPoint) && (bord[x][y + 1] == him) && | 709 | if ((y < maxPoint) && (bord[x][y + 1] == him) && |
710 | (gList[gMap[groupIDs[x][y + 1]]].libC == 1)) | 710 | (gList[gMap[groupIDs[x][y + 1]]].libC == 1)) |
711 | { | 711 | { |
712 | killFlag = TRUE; | 712 | killFlag = TRUE; |
713 | killGroup(x, y + 1, me, him); | 713 | killGroup(x, y + 1, me, him); |
714 | } | 714 | } |
715 | /* list groups adjacent to me */ | 715 | /* list groups adjacent to me */ |
716 | if ((x > 0) && (bord[x - 1][y] == him)) | 716 | if ((x > 0) && (bord[x - 1][y] == him)) |
717 | { | 717 | { |
718 | nlcGroup.indx = nlcGroup.indx + 1; | 718 | nlcGroup.indx = nlcGroup.indx + 1; |
719 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; | 719 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]]; |
720 | } | 720 | } |
721 | if ((x < maxPoint) && (bord[x + 1][y] == him)) | 721 | if ((x < maxPoint) && (bord[x + 1][y] == him)) |
722 | { | 722 | { |
723 | nlcGroup.indx = nlcGroup.indx + 1; | 723 | nlcGroup.indx = nlcGroup.indx + 1; |
724 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; | 724 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]]; |
725 | } | 725 | } |
726 | if ((y > 0) && (bord[x][y - 1] == him)) | 726 | if ((y > 0) && (bord[x][y - 1] == him)) |
727 | { | 727 | { |
728 | nlcGroup.indx = nlcGroup.indx + 1; | 728 | nlcGroup.indx = nlcGroup.indx + 1; |
729 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; | 729 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]]; |
730 | } | 730 | } |
731 | if ((y < maxPoint) && (bord[x][y + 1] == him)) | 731 | if ((y < maxPoint) && (bord[x][y + 1] == him)) |
732 | { | 732 | { |
733 | nlcGroup.indx = nlcGroup.indx + 1; | 733 | nlcGroup.indx = nlcGroup.indx + 1; |
734 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; | 734 | nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]]; |
735 | } | 735 | } |
736 | /* fix liberty count for affected groups */ | 736 | /* fix liberty count for affected groups */ |
737 | grpMark = grpMark + 1; | 737 | grpMark = grpMark + 1; |
738 | for (i = 1; i <= nlcGroup.indx; i++) | 738 | for (i = 1; i <= nlcGroup.indx; i++) |
739 | if (gList[nlcGroup.v[i]].groupMark != grpMark) | 739 | if (gList[nlcGroup.v[i]].groupMark != grpMark) |
740 | { | 740 | { |
741 | if (gList[nlcGroup.v[i]].atLevel != tryLevel) | 741 | if (gList[nlcGroup.v[i]].atLevel != tryLevel) |
742 | { | 742 | { |
743 | playMark = playMark + 1; | 743 | playMark = playMark + 1; |
744 | playStack[playMark].kind = chLib; | 744 | playStack[playMark].kind = chLib; |
745 | playStack[playMark].gID = nlcGroup.v[i]; | 745 | playStack[playMark].gID = nlcGroup.v[i]; |
746 | playStack[playMark].uval.chLib.oldLevel = | 746 | playStack[playMark].uval.chLib.oldLevel = |
747 | gList[nlcGroup.v[i]].atLevel; | 747 | gList[nlcGroup.v[i]].atLevel; |
748 | playStack[playMark].uval.chLib.oldLC = | 748 | playStack[playMark].uval.chLib.oldLC = |
749 | gList[nlcGroup.v[i]].libC; | 749 | gList[nlcGroup.v[i]].libC; |
750 | } | 750 | } |
751 | gList[nlcGroup.v[i]].groupMark = grpMark; | 751 | gList[nlcGroup.v[i]].groupMark = grpMark; |
752 | gList[nlcGroup.v[i]].atLevel = tryLevel; | 752 | gList[nlcGroup.v[i]].atLevel = tryLevel; |
753 | spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist); | 753 | spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist); |
754 | gList[nlcGroup.v[i]].libC = pPlist.indx; | 754 | gList[nlcGroup.v[i]].libC = pPlist.indx; |
755 | } | 755 | } |
756 | } /* plei */ | 756 | } /* plei */ |
757 | 757 | ||
758 | saveState() | 758 | saveState() |
759 | { /* saveState */ | 759 | { /* saveState */ |
760 | playMark = 0; | 760 | playMark = 0; |
761 | tryLevel = 0; | 761 | tryLevel = 0; |
762 | newGID = maxGroupID; | 762 | newGID = maxGroupID; |
763 | } /* saveState */ | 763 | } /* saveState */ |
764 | 764 | ||
765 | /* | 765 | /* |
766 | undoes a move sequence back to uMark | 766 | undoes a move sequence back to uMark |
767 | */ | 767 | */ |
768 | undoTo(uMark) | 768 | undoTo(uMark) |
769 | short uMark; | 769 | short uMark; |
770 | { /* undoTo */ | 770 | { /* undoTo */ |
771 | short i, xl, yl; | 771 | short i, xl, yl; |
772 | #ifdef DEBUG | 772 | #ifdef DEBUG |
773 | printf( "undoTo\n" ); | 773 | printf( "undoTo\n" ); |
774 | #endif | 774 | #endif |
775 | for (i = playMark; i >= uMark + 1; i--) | 775 | for (i = playMark; i >= uMark + 1; i--) |
776 | if (playStack[i].kind == rem) | 776 | if (playStack[i].kind == rem) |
777 | { | 777 | { |
778 | xl = playStack[i].uval.rem.xl; | 778 | xl = playStack[i].uval.rem.xl; |
779 | yl = playStack[i].uval.rem.yl; | 779 | yl = playStack[i].uval.rem.yl; |
780 | bord[xl][yl] = playStack[i].uval.rem.who; | 780 | bord[xl][yl] = playStack[i].uval.rem.who; |
781 | groupIDs[xl][yl] = playStack[i].gID; | 781 | groupIDs[xl][yl] = playStack[i].gID; |
782 | if (showTrees) | 782 | if (showTrees) |
783 | sstone(playStack[i].uval.rem.who, xl, yl, | 783 | sstone(playStack[i].uval.rem.who, xl, yl, |
784 | playStack[i].uval.rem.sNumber); | 784 | playStack[i].uval.rem.sNumber); |
785 | } | 785 | } |
786 | else if (playStack[i].kind == add) | 786 | else if (playStack[i].kind == add) |
787 | { | 787 | { |
788 | xl = playStack[i].uval.add.xl; | 788 | xl = playStack[i].uval.add.xl; |
789 | yl = playStack[i].uval.add.yl; | 789 | yl = playStack[i].uval.add.yl; |
790 | bord[xl][yl] = 0; | 790 | bord[xl][yl] = 0; |
791 | groupIDs[xl][yl] = 0; | 791 | groupIDs[xl][yl] = 0; |
792 | tryLevel = tryLevel - 1; | 792 | tryLevel = tryLevel - 1; |
793 | newGID = playStack[i].uval.add.nextGID; | 793 | newGID = playStack[i].uval.add.nextGID; |
794 | if (showTrees) | 794 | if (showTrees) |
795 | rstone(xl, yl); | 795 | rstone(xl, yl); |
796 | } | 796 | } |
797 | else if (playStack[i].kind == reMap) | 797 | else if (playStack[i].kind == reMap) |
798 | gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID; | 798 | gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID; |
799 | else /* change libs of group - gID is pre-mapped */ | 799 | else /* change libs of group - gID is pre-mapped */ |
800 | { | 800 | { |
801 | gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC; | 801 | gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC; |
802 | gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel; | 802 | gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel; |
803 | } | 803 | } |
804 | playMark = uMark; | 804 | playMark = uMark; |
805 | } /* undoTo */ | 805 | } /* undoTo */ |
806 | 806 | ||
807 | /* | 807 | /* |
808 | restores the state of the world after trying a move sequence | 808 | restores the state of the world after trying a move sequence |
809 | */ | 809 | */ |
810 | restoreState() | 810 | restoreState() |
811 | { /* restoreState */ | 811 | { /* restoreState */ |
812 | #ifdef DEBUG | 812 | #ifdef DEBUG |
813 | printf( "restoreState\n" ); | 813 | printf( "restoreState\n" ); |
814 | #endif | 814 | #endif |
815 | if (playMark > 0) | 815 | if (playMark > 0) |
816 | { | 816 | { |
817 | undoTo(0); | 817 | undoTo(0); |
818 | playMark = 0; | 818 | playMark = 0; |
819 | tryLevel = 0; | 819 | tryLevel = 0; |
820 | } | 820 | } |
821 | } /* restoreState */ | 821 | } /* restoreState */ |
822 | 822 | ||
823 | /* exception bpt; */ | 823 | /* exception bpt; */ |
824 | 824 | ||
825 | 825 | ||
826 | /* | 826 | /* |
827 | returns true if (the group (at gx, gy) is saveable. | 827 | returns true if (the group (at gx, gy) is saveable. |
828 | if so, returns the point to play at in savex, savey | 828 | if so, returns the point to play at in savex, savey |
829 | */ | 829 | */ |
830 | short saveable(gx, gy, savex, savey) | 830 | short saveable(gx, gy, savex, savey) |
831 | short gx, gy, *savex, *savey; | 831 | short gx, gy, *savex, *savey; |
832 | { /* saveable */ | 832 | { /* saveable */ |
833 | short me, him, gx1, gx2, i, j, smark, mark2, tl, result; | 833 | short me, him, gx1, gx2, i, j, smark, mark2, tl, result; |
834 | char sChar; | 834 | char sChar; |
835 | sPointList dList; | 835 | sPointList dList; |
836 | point tp; | 836 | point tp; |
837 | short libList[maxSPoint+1]; | 837 | short libList[maxSPoint+1]; |
838 | #ifdef DEBUG | 838 | #ifdef DEBUG |
839 | printf( "saveable\n" ); | 839 | printf( "saveable\n" ); |
840 | #endif | 840 | #endif |
841 | dbStop = TRUE; | 841 | dbStop = TRUE; |
842 | me = bord[gx][gy]; | 842 | me = bord[gx][gy]; |
843 | him = -me; | 843 | him = -me; |
844 | if (me == 1) | 844 | if (me == 1) |
845 | sChar = '|'; | 845 | sChar = '|'; |
846 | else | 846 | else |
847 | sChar = '>'; | 847 | sChar = '>'; |
848 | /* write(sChar); */ | 848 | /* write(sChar); */ |
849 | spanGroup(gx, gy, &plist3); /* find my liberties */ | 849 | spanGroup(gx, gy, &plist3); /* find my liberties */ |
850 | if (adjInAtari) /* one of my options is to kill */ | 850 | if (adjInAtari) /* one of my options is to kill */ |
851 | { | 851 | { |
852 | listAdjacents(gx, gy, &aList); | 852 | listAdjacents(gx, gy, &aList); |
853 | for (i = 1; i <= aList.indx; i++) | 853 | for (i = 1; i <= aList.indx; i++) |
854 | if (gList[aList.v[i]].libC == 1) | 854 | if (gList[aList.v[i]].libC == 1) |
855 | { | 855 | { |
856 | spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly, | 856 | spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly, |
857 | &pList1); /* find it's liberty */ | 857 | &pList1); /* find it's liberty */ |
858 | plist3.indx = plist3.indx + 1; | 858 | plist3.indx = plist3.indx + 1; |
859 | plist3.p[plist3.indx].px = pList1.p[1].px; | 859 | plist3.p[plist3.indx].px = pList1.p[1].px; |
860 | plist3.p[plist3.indx].py = pList1.p[1].py; | 860 | plist3.p[plist3.indx].py = pList1.p[1].py; |
861 | } | 861 | } |
862 | } | 862 | } |
863 | for (i = 1; i <= maxSPoint; i++) | 863 | for (i = 1; i <= maxSPoint; i++) |
864 | libList[i] = -1; | 864 | libList[i] = -1; |
865 | if ((utilPlayLevel > 4) && | 865 | if ((utilPlayLevel > 4) && |
866 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */ | 866 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */ |
867 | { | 867 | { |
868 | listDiags(gx, gy, &dList); | 868 | listDiags(gx, gy, &dList); |
869 | j = 0; | 869 | j = 0; |
870 | i = plist3.indx; | 870 | i = plist3.indx; |
871 | while ((j < dList.indx) && | 871 | while ((j < dList.indx) && |
872 | (i < maxSPoint)) | 872 | (i < maxSPoint)) |
873 | { | 873 | { |
874 | j = j + 1; | 874 | j = j + 1; |
875 | i = i + 1; | 875 | i = i + 1; |
876 | libList[i] = 100; | 876 | libList[i] = 100; |
877 | plist3.p[i].px = dList.p[j].px; | 877 | plist3.p[i].px = dList.p[j].px; |
878 | plist3.p[i].py = dList.p[j].py; | 878 | plist3.p[i].py = dList.p[j].py; |
879 | } | 879 | } |
880 | plist3.indx = i; | 880 | plist3.indx = i; |
881 | } | 881 | } |
882 | if (plist3.indx > 1) /* sort by decreasing lib count */ | 882 | if (plist3.indx > 1) /* sort by decreasing lib count */ |
883 | { | 883 | { |
884 | for (i = 1; i <= plist3.indx; i++) | 884 | for (i = 1; i <= plist3.indx; i++) |
885 | if (libList[i] != 100) | 885 | if (libList[i] != 100) |
886 | { | 886 | { |
887 | mark2 = playMark; | 887 | mark2 = playMark; |
888 | tryPlay(plist3.p[i].px, plist3.p[i].py, me); | 888 | tryPlay(plist3.p[i].px, plist3.p[i].py, me); |
889 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | 889 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; |
890 | if (libList[i] > treeLibLim) /* i'm safe */ | 890 | if (libList[i] > treeLibLim) /* i'm safe */ |
891 | { | 891 | { |
892 | *savex = plist3.p[i].px; | 892 | *savex = plist3.p[i].px; |
893 | *savey = plist3.p[i].py; | 893 | *savey = plist3.p[i].py; |
894 | result = TRUE; | 894 | result = TRUE; |
895 | goto one; | 895 | goto one; |
896 | } | 896 | } |
897 | undoTo(mark2); | 897 | undoTo(mark2); |
898 | } | 898 | } |
899 | for (i = 1; i <= plist3.indx - 1; i++) | 899 | for (i = 1; i <= plist3.indx - 1; i++) |
900 | for (j = i + 1; j <= plist3.indx; j++) | 900 | for (j = i + 1; j <= plist3.indx; j++) |
901 | if (libList[i] < libList[j]) | 901 | if (libList[i] < libList[j]) |
902 | { | 902 | { |
903 | tl = libList[i]; | 903 | tl = libList[i]; |
904 | libList[i] = libList[j]; | 904 | libList[i] = libList[j]; |
905 | libList[j] = tl; | 905 | libList[j] = tl; |
906 | tp = plist3.p[i]; | 906 | tp = plist3.p[i]; |
907 | plist3.p[i] = plist3.p[j]; | 907 | plist3.p[i] = plist3.p[j]; |
908 | plist3.p[j] = tp; | 908 | plist3.p[j] = tp; |
909 | } | 909 | } |
910 | } | 910 | } |
911 | for (i = 1; i <= plist3.indx; i++) | 911 | for (i = 1; i <= plist3.indx; i++) |
912 | { | 912 | { |
913 | *savex = plist3.p[i].px; | 913 | *savex = plist3.p[i].px; |
914 | *savey = plist3.p[i].py; | 914 | *savey = plist3.p[i].py; |
915 | if (legal[*savex][*savey]) | 915 | if (legal[*savex][*savey]) |
916 | { | 916 | { |
917 | smark = playMark; | 917 | smark = playMark; |
918 | tryPlay(*savex, *savey, me); | 918 | tryPlay(*savex, *savey, me); |
919 | pause(); | 919 | //pause(); |
920 | if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1) | 920 | if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1) |
921 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) | 921 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) |
922 | { | 922 | { |
923 | restoreState(); | 923 | restoreState(); |
924 | /* sClearChar(sChar, rXor); */ | 924 | /* sClearChar(sChar, rXor); */ |
925 | return TRUE; | 925 | return TRUE; |
926 | } | 926 | } |
927 | else if (gList[gMap[groupIDs[gx][gy]]].libC > 1) | 927 | else if (gList[gMap[groupIDs[gx][gy]]].libC > 1) |
928 | if (! killable(gx, gy, &gx1, &gx2)) | 928 | if (! killable(gx, gy, &gx1, &gx2)) |
929 | { | 929 | { |
930 | restoreState(); | 930 | restoreState(); |
931 | /* sClearChar(sChar, rXor); */ | 931 | /* sClearChar(sChar, rXor); */ |
932 | return TRUE; | 932 | return TRUE; |
933 | } | 933 | } |
934 | undoTo(smark); | 934 | undoTo(smark); |
935 | } | 935 | } |
936 | } | 936 | } |
937 | result = FALSE; | 937 | result = FALSE; |
938 | one: | 938 | one: |
939 | restoreState(); | 939 | restoreState(); |
940 | /* sClearChar(sChar, rXor); */ | 940 | /* sClearChar(sChar, rXor); */ |
941 | return result; | 941 | return result; |
942 | } /* saveable */ | 942 | } /* saveable */ |
943 | 943 | ||
944 | /* | 944 | /* |
945 | marks unsavable groups as dead | 945 | marks unsavable groups as dead |
946 | */ | 946 | */ |
947 | markDead() | 947 | markDead() |
948 | { /* markDead */ | 948 | { /* markDead */ |
949 | short i, j, gx, gy, result; | 949 | short i, j, gx, gy, result; |
950 | #ifdef DEBUG | 950 | #ifdef DEBUG |
951 | printf( "markDead\n" ); | 951 | printf( "markDead\n" ); |
952 | #endif | 952 | #endif |
953 | for (i = 1; i <= maxGroupID; i++) | 953 | for (i = 1; i <= maxGroupID; i++) |
954 | if (killable(gList[i].lx, gList[i].ly, &gx, &gy)) | 954 | if (killable(gList[i].lx, gList[i].ly, &gx, &gy)) |
955 | result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy); | 955 | result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy); |
956 | else | 956 | else |
957 | result = FALSE; | 957 | result = FALSE; |
958 | for (i = 0; i <= maxPoint; i++) | 958 | for (i = 0; i <= maxPoint; i++) |
959 | for (j = 0; j <= maxPoint; j++) | 959 | for (j = 0; j <= maxPoint; j++) |
960 | if (bord[i][j] == 0) | 960 | if (bord[i][j] == 0) |
961 | ndbord[i][j] = 0; | 961 | ndbord[i][j] = 0; |
962 | else if (gList[groupIDs[i][j]].isDead) | 962 | else if (gList[groupIDs[i][j]].isDead) |
963 | ndbord[i][j] = 0; | 963 | ndbord[i][j] = 0; |
964 | else | 964 | else |
965 | ndbord[i][j] = bord[i][j]; | 965 | ndbord[i][j] = bord[i][j]; |
966 | } /* markDead */ | 966 | } /* markDead */ |
967 | 967 | ||
968 | /* | 968 | /* |
969 | marks groups with two eyes as live | 969 | marks groups with two eyes as live |
970 | */ | 970 | */ |
971 | MLspan(x, y, saw1, sawm1, size, sMark) | 971 | MLspan(x, y, saw1, sawm1, size, sMark) |
972 | short x, y, *saw1, *sawm1, *size, sMark; | 972 | short x, y, *saw1, *sawm1, *size, sMark; |
973 | { /* span */ | 973 | { /* span */ |
974 | if (ndbord[x][y] == 1) | 974 | if (ndbord[x][y] == 1) |
975 | *saw1 = TRUE; | 975 | *saw1 = TRUE; |
976 | else if (ndbord[x][y] == -1) | 976 | else if (ndbord[x][y] == -1) |
977 | *sawm1 = TRUE; | 977 | *sawm1 = TRUE; |
978 | else if (sGroups[x][y] == 0) | 978 | else if (sGroups[x][y] == 0) |
979 | { | 979 | { |
980 | sGroups[x][y] = sMark; | 980 | sGroups[x][y] = sMark; |
981 | *size = *size + 1; | 981 | *size = *size + 1; |
982 | if (x > 0) | 982 | if (x > 0) |
983 | MLspan(x - 1, y, saw1, sawm1, size, sMark); | 983 | MLspan(x - 1, y, saw1, sawm1, size, sMark); |
984 | if (x < maxPoint) | 984 | if (x < maxPoint) |
985 | MLspan(x + 1, y, saw1, sawm1, size, sMark); | 985 | MLspan(x + 1, y, saw1, sawm1, size, sMark); |
986 | if (y > 0) | 986 | if (y > 0) |
987 | MLspan(x, y - 1, saw1, sawm1, size, sMark); | 987 | MLspan(x, y - 1, saw1, sawm1, size, sMark); |
988 | if (y < maxPoint) | 988 | if (y < maxPoint) |
989 | MLspan(x, y + 1, saw1, sawm1, size, sMark); | 989 | MLspan(x, y + 1, saw1, sawm1, size, sMark); |
990 | } | 990 | } |
991 | } /* span */ | 991 | } /* span */ |
992 | 992 | ||
993 | short CLspan(x, y, numEyes, who) | 993 | short CLspan(x, y, numEyes, who) |
994 | short x, y, *numEyes, who; | 994 | short x, y, *numEyes, who; |
995 | { /* span */ | 995 | { /* span */ |
996 | markBoard[x][y] = marker; | 996 | markBoard[x][y] = marker; |
997 | if (ndbord[x][y] == 0) | 997 | if (ndbord[x][y] == 0) |
998 | { | 998 | { |
999 | if ((sList[sGroups[x][y]].sm != marker) && | 999 | if ((sList[sGroups[x][y]].sm != marker) && |
1000 | (sList[sGroups[x][y]].w == who)) | 1000 | (sList[sGroups[x][y]].w == who)) |
1001 | { | 1001 | { |
1002 | sList[sGroups[x][y]].sm = marker; | 1002 | sList[sGroups[x][y]].sm = marker; |
1003 | if (sList[sGroups[x][y]].s > 6) | 1003 | if (sList[sGroups[x][y]].s > 6) |
1004 | return TRUE; | 1004 | return TRUE; |
1005 | *numEyes = *numEyes + 1; | 1005 | *numEyes = *numEyes + 1; |
1006 | if (*numEyes > 1) | 1006 | if (*numEyes > 1) |
1007 | return TRUE; | 1007 | return TRUE; |
1008 | } | 1008 | } |
1009 | } | 1009 | } |
1010 | else if (bord[x][y] == who) | 1010 | else if (bord[x][y] == who) |
1011 | { | 1011 | { |
1012 | if ((x > 0) && | 1012 | if ((x > 0) && |
1013 | (markBoard[x - 1][y] != marker)) | 1013 | (markBoard[x - 1][y] != marker)) |
1014 | if (CLspan(x - 1, y, numEyes, who)) return TRUE; | 1014 | if (CLspan(x - 1, y, numEyes, who)) return TRUE; |
1015 | if ((x < maxPoint) && | 1015 | if ((x < maxPoint) && |
1016 | (markBoard[x + 1][y] != marker)) | 1016 | (markBoard[x + 1][y] != marker)) |
1017 | if (CLspan(x + 1, y, numEyes, who)) return TRUE; | 1017 | if (CLspan(x + 1, y, numEyes, who)) return TRUE; |
1018 | if ((y > 0) && | 1018 | if ((y > 0) && |
1019 | (markBoard[x][y - 1] != marker)) | 1019 | (markBoard[x][y - 1] != marker)) |
1020 | if (CLspan(x, y - 1, numEyes, who)) return TRUE; | 1020 | if (CLspan(x, y - 1, numEyes, who)) return TRUE; |
1021 | if ((y < maxPoint) && | 1021 | if ((y < maxPoint) && |
1022 | (markBoard[x][y + 1] != marker)) | 1022 | (markBoard[x][y + 1] != marker)) |
1023 | if (CLspan(x, y + 1, numEyes, who)) return TRUE; | 1023 | if (CLspan(x, y + 1, numEyes, who)) return TRUE; |
1024 | } | 1024 | } |
1025 | return FALSE; | 1025 | return FALSE; |
1026 | } /* span */ | 1026 | } /* span */ |
1027 | 1027 | ||
1028 | short checkLive(x, y) | 1028 | short checkLive(x, y) |
1029 | short x, y; | 1029 | short x, y; |
1030 | { /* checkLive */ | 1030 | { /* checkLive */ |
1031 | short numEyes, who; | 1031 | short numEyes, who; |
1032 | #ifdef DEBUG | 1032 | #ifdef DEBUG |
1033 | printf( "checkLive\n" ); | 1033 | printf( "checkLive\n" ); |
1034 | #endif | 1034 | #endif |
1035 | numEyes = 0; | 1035 | numEyes = 0; |
1036 | who = bord[x][y]; | 1036 | who = bord[x][y]; |
1037 | marker = marker + 1; | 1037 | marker = marker + 1; |
1038 | return CLspan(x, y, &numEyes, who); | 1038 | return CLspan(x, y, &numEyes, who); |
1039 | } /* checkLive */ | 1039 | } /* checkLive */ |
1040 | 1040 | ||
1041 | markLive() | 1041 | markLive() |
1042 | { /* markLive */ | 1042 | { /* markLive */ |
1043 | short i, j, size, sMark = 0; | 1043 | short i, j, size, sMark = 0; |
1044 | short saw1, sawm1; | 1044 | short saw1, sawm1; |
1045 | #ifdef DEBUG | 1045 | #ifdef DEBUG |
1046 | printf( "markLive\n" ); | 1046 | printf( "markLive\n" ); |
1047 | #endif | 1047 | #endif |
1048 | initArray(sGroups); | 1048 | initArray(sGroups); |
1049 | for (i = 0; i <= maxPoint; i++) | 1049 | for (i = 0; i <= maxPoint; i++) |
1050 | for (j = 0; j <= maxPoint; j++) | 1050 | for (j = 0; j <= maxPoint; j++) |
1051 | if ((sGroups[i][j] == 0) && | 1051 | if ((sGroups[i][j] == 0) && |
1052 | (ndbord[i][j] == 0)) | 1052 | (ndbord[i][j] == 0)) |
1053 | { | 1053 | { |
1054 | size = 0; | 1054 | size = 0; |
1055 | sMark = sMark + 1; | 1055 | sMark = sMark + 1; |
1056 | sawm1 = FALSE; | 1056 | sawm1 = FALSE; |
1057 | saw1 = FALSE; | 1057 | saw1 = FALSE; |
1058 | MLspan(i, j, &saw1, &sawm1, &size, sMark); | 1058 | MLspan(i, j, &saw1, &sawm1, &size, sMark); |
1059 | sList[sMark].s = size; | 1059 | sList[sMark].s = size; |
1060 | sList[sMark].sm = 0; | 1060 | sList[sMark].sm = 0; |
1061 | if (sawm1) | 1061 | if (sawm1) |
1062 | if (saw1) | 1062 | if (saw1) |
1063 | sList[sMark].w = 0; | 1063 | sList[sMark].w = 0; |
1064 | else | 1064 | else |
1065 | sList[sMark].w = -1; | 1065 | sList[sMark].w = -1; |
1066 | else if (saw1) | 1066 | else if (saw1) |
1067 | sList[sMark].w = 1; | 1067 | sList[sMark].w = 1; |
1068 | else | 1068 | else |
1069 | sList[sMark].w = 0; | 1069 | sList[sMark].w = 0; |
1070 | } | 1070 | } |
1071 | for (i = 1; i <= maxGroupID; i++) | 1071 | for (i = 1; i <= maxGroupID; i++) |
1072 | if (! gList[i].isDead) | 1072 | if (! gList[i].isDead) |
1073 | gList[i].isLive = checkLive(gList[i].lx, gList[i].ly); | 1073 | gList[i].isLive = checkLive(gList[i].lx, gList[i].ly); |
1074 | } /* markLive */ | 1074 | } /* markLive */ |
1075 | 1075 | ||
1076 | /* | 1076 | /* |
1077 | generates the connection map and the protected point map. | 1077 | generates the connection map and the protected point map. |
1078 | */ | 1078 | */ |
1079 | genConnects() | 1079 | genConnects() |
1080 | { /* genConnects */ | 1080 | { /* genConnects */ |
1081 | short x, y, numStones; | 1081 | short x, y, numStones; |
1082 | #ifdef DEBUG | 1082 | #ifdef DEBUG |
1083 | printf( "genConnects\n" ); | 1083 | printf( "genConnects\n" ); |
1084 | #endif | 1084 | #endif |
1085 | for (x = 0; x <= maxPoint; x++) | 1085 | for (x = 0; x <= maxPoint; x++) |
1086 | for (y = 0; y <= maxPoint; y++) | 1086 | for (y = 0; y <= maxPoint; y++) |
1087 | { | 1087 | { |
1088 | connectMap[x][y] = 0; | 1088 | connectMap[x][y] = 0; |
1089 | protPoints[x][y] = 0; | 1089 | protPoints[x][y] = 0; |
1090 | } | 1090 | } |
1091 | for (x = 0; x <= maxPoint; x++) | 1091 | for (x = 0; x <= maxPoint; x++) |
1092 | for (y = 0; y <= maxPoint; y++) | 1092 | for (y = 0; y <= maxPoint; y++) |
1093 | if (bord[x][y] == 1) /* map connections to this stone */ | 1093 | if (bord[x][y] == 1) /* map connections to this stone */ |
1094 | { | 1094 | { |
1095 | if (x > 0) /* direct connection */ | 1095 | if (x > 0) /* direct connection */ |
1096 | connectMap[x - 1][y] += 1; | 1096 | connectMap[x - 1][y] += 1; |
1097 | if (x < maxPoint) | 1097 | if (x < maxPoint) |
1098 | connectMap[x + 1][y] += 1; | 1098 | connectMap[x + 1][y] += 1; |
1099 | if (y > 0) | 1099 | if (y > 0) |
1100 | connectMap[x][y - 1] += 1; | 1100 | connectMap[x][y - 1] += 1; |
1101 | if (y < maxPoint) | 1101 | if (y < maxPoint) |
1102 | connectMap[x][y + 1] += 1; | 1102 | connectMap[x][y + 1] += 1; |
1103 | if ((x > 0) && (y > 0) && /* diagonal connection */ | 1103 | if ((x > 0) && (y > 0) && /* diagonal connection */ |
1104 | (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0)) | 1104 | (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0)) |
1105 | connectMap[x - 1][y - 1] += 1; | 1105 | connectMap[x - 1][y - 1] += 1; |
1106 | if ((x < maxPoint) && (y > 0) && | 1106 | if ((x < maxPoint) && (y > 0) && |
1107 | (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0)) | 1107 | (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0)) |
1108 | connectMap[x + 1][y - 1] += 1; | 1108 | connectMap[x + 1][y - 1] += 1; |
1109 | if ((x < maxPoint) && (y < maxPoint) && | 1109 | if ((x < maxPoint) && (y < maxPoint) && |
1110 | (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0)) | 1110 | (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0)) |
1111 | connectMap[x + 1][y + 1] += 1; | 1111 | connectMap[x + 1][y + 1] += 1; |
1112 | if ((x > 0) && (y < maxPoint) && | 1112 | if ((x > 0) && (y < maxPoint) && |
1113 | (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0)) | 1113 | (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0)) |
1114 | connectMap[x - 1][y + 1] += 1; | 1114 | connectMap[x - 1][y + 1] += 1; |
1115 | if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */ | 1115 | if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */ |
1116 | connectMap[x - 2][y] += 1; | 1116 | connectMap[x - 2][y] += 1; |
1117 | if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3)) | 1117 | if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3)) |
1118 | connectMap[x + 2][y] += 1; | 1118 | connectMap[x + 2][y] += 1; |
1119 | if ((y > 1) && (claim[x][y - 1] > 3)) | 1119 | if ((y > 1) && (claim[x][y - 1] > 3)) |
1120 | connectMap[x][y - 2] += 1; | 1120 | connectMap[x][y - 2] += 1; |
1121 | if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3)) | 1121 | if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3)) |
1122 | connectMap[x][y + 2] += 1; | 1122 | connectMap[x][y + 2] += 1; |
1123 | if ((x > 1) && (y > 0) && /* knight's move */ | 1123 | if ((x > 1) && (y > 0) && /* knight's move */ |
1124 | (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3)) | 1124 | (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3)) |
1125 | connectMap[x - 2][y - 1] += 1; | 1125 | connectMap[x - 2][y - 1] += 1; |
1126 | if ((x > 0) && (y > 1) && | 1126 | if ((x > 0) && (y > 1) && |
1127 | (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3)) | 1127 | (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3)) |
1128 | connectMap[x - 1][y - 2] += 1; | 1128 | connectMap[x - 1][y - 2] += 1; |
1129 | if ((x < (maxPoint - 1)) && (y > 0) && | 1129 | if ((x < (maxPoint - 1)) && (y > 0) && |
1130 | (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3)) | 1130 | (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3)) |
1131 | connectMap[x + 2][y - 1] += 1; | 1131 | connectMap[x + 2][y - 1] += 1; |
1132 | if ((x < maxPoint) && (y > 1) && | 1132 | if ((x < maxPoint) && (y > 1) && |
1133 | (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3)) | 1133 | (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3)) |
1134 | connectMap[x + 1][y - 2] += 1; | 1134 | connectMap[x + 1][y - 2] += 1; |
1135 | if ((x > 1) && (y < maxPoint) && | 1135 | if ((x > 1) && (y < maxPoint) && |
1136 | (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3)) | 1136 | (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3)) |
1137 | connectMap[x - 2][y + 1] += 1; | 1137 | connectMap[x - 2][y + 1] += 1; |
1138 | if ((x > 0) && (y < (maxPoint - 1)) && | 1138 | if ((x > 0) && (y < (maxPoint - 1)) && |
1139 | (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3)) | 1139 | (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3)) |
1140 | connectMap[x - 1][y + 2] += 1; | 1140 | connectMap[x - 1][y + 2] += 1; |
1141 | if ((x < (maxPoint - 1)) && (y < maxPoint) && | 1141 | if ((x < (maxPoint - 1)) && (y < maxPoint) && |
1142 | (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3)) | 1142 | (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3)) |
1143 | connectMap[x + 2][y + 1] += 1; | 1143 | connectMap[x + 2][y + 1] += 1; |
1144 | if ((x < maxPoint) && (y < (maxPoint - 1)) && | 1144 | if ((x < maxPoint) && (y < (maxPoint - 1)) && |
1145 | (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3)) | 1145 | (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3)) |
1146 | connectMap[x + 1][y + 2] += 1; | 1146 | connectMap[x + 1][y + 2] += 1; |
1147 | } | 1147 | } |
1148 | else if (bord[x][y] == 0) /* see if protected point */ | 1148 | else if (bord[x][y] == 0) /* see if protected point */ |
1149 | { | 1149 | { |
1150 | numStones = 0; | 1150 | numStones = 0; |
1151 | if (x == 0) | 1151 | if (x == 0) |
1152 | numStones = numStones + 1; | 1152 | numStones = numStones + 1; |
1153 | if (y == 0) | 1153 | if (y == 0) |
1154 | numStones = numStones + 1; | 1154 | numStones = numStones + 1; |
1155 | if (x == maxPoint) | 1155 | if (x == maxPoint) |
1156 | numStones = numStones + 1; | 1156 | numStones = numStones + 1; |
1157 | if (y == maxPoint) | 1157 | if (y == maxPoint) |
1158 | numStones = numStones + 1; | 1158 | numStones = numStones + 1; |
1159 | if ((x > 0) && (bord[x - 1][y] == 1)) | 1159 | if ((x > 0) && (bord[x - 1][y] == 1)) |
1160 | numStones = numStones + 1; | 1160 | numStones = numStones + 1; |
1161 | if ((y > 0) && (bord[x][y - 1] == 1)) | 1161 | if ((y > 0) && (bord[x][y - 1] == 1)) |
1162 | numStones = numStones + 1; | 1162 | numStones = numStones + 1; |
1163 | if ((x < maxPoint) && (bord[x + 1][y] == 1)) | 1163 | if ((x < maxPoint) && (bord[x + 1][y] == 1)) |
1164 | numStones = numStones + 1; | 1164 | numStones = numStones + 1; |
1165 | if ((y < maxPoint) && (bord[x][y + 1] == 1)) | 1165 | if ((y < maxPoint) && (bord[x][y + 1] == 1)) |
1166 | numStones = numStones + 1; | 1166 | numStones = numStones + 1; |
1167 | if (numStones == 4) | 1167 | if (numStones == 4) |
1168 | protPoints[x][y] = 1; | 1168 | protPoints[x][y] = 1; |
1169 | else if (numStones == 3) | 1169 | else if (numStones == 3) |
1170 | { | 1170 | { |
1171 | if ((x > 0) && | 1171 | if ((x > 0) && |
1172 | ((bord[x - 1][y] == 0) || | 1172 | ((bord[x - 1][y] == 0) || |
1173 | ((bord[x - 1][y] == -1) && | 1173 | ((bord[x - 1][y] == -1) && |
1174 | (gList[groupIDs[x - 1][y]].libC == 1)))) | 1174 | (gList[groupIDs[x - 1][y]].libC == 1)))) |
1175 | protPoints[x][y] = 1; | 1175 | protPoints[x][y] = 1; |
1176 | else if ((x < maxPoint) && | 1176 | else if ((x < maxPoint) && |
1177 | ((bord[x + 1][y] == 0) || | 1177 | ((bord[x + 1][y] == 0) || |
1178 | ((bord[x + 1][y] == -1) && | 1178 | ((bord[x + 1][y] == -1) && |
1179 | (gList[groupIDs[x + 1][y]].libC == 1)))) | 1179 | (gList[groupIDs[x + 1][y]].libC == 1)))) |
1180 | protPoints[x][y] = 1; | 1180 | protPoints[x][y] = 1; |
1181 | else if ((y > 0) && | 1181 | else if ((y > 0) && |
1182 | ((bord[x][y - 1] == 0) || | 1182 | ((bord[x][y - 1] == 0) || |
1183 | ((bord[x][y - 1] == -1) && | 1183 | ((bord[x][y - 1] == -1) && |
1184 | (gList[groupIDs[x][y - 1]].libC == 1)))) | 1184 | (gList[groupIDs[x][y - 1]].libC == 1)))) |
1185 | protPoints[x][y] = 1; | 1185 | protPoints[x][y] = 1; |
1186 | else if ((y < maxPoint) && | 1186 | else if ((y < maxPoint) && |
1187 | ((bord[x][y + 1] == 0) || | 1187 | ((bord[x][y + 1] == 0) || |
1188 | ((bord[x][y + 1] == -1) && | 1188 | ((bord[x][y + 1] == -1) && |
1189 | (gList[groupIDs[x][y + 1]].libC == 1)))) | 1189 | (gList[groupIDs[x][y + 1]].libC == 1)))) |
1190 | protPoints[x][y] = 1; | 1190 | protPoints[x][y] = 1; |
1191 | } | 1191 | } |
1192 | } | 1192 | } |
1193 | for (x = 0; x <= maxPoint; x++) | 1193 | for (x = 0; x <= maxPoint; x++) |
1194 | for (y = 0; y <= maxPoint; y++) | 1194 | for (y = 0; y <= maxPoint; y++) |
1195 | if (bord[x][y] != 0) | 1195 | if (bord[x][y] != 0) |
1196 | { | 1196 | { |
1197 | connectMap[x][y] = 0; | 1197 | connectMap[x][y] = 0; |
1198 | protPoints[x][y] = 0; | 1198 | protPoints[x][y] = 0; |
1199 | } | 1199 | } |
1200 | } /* genConnects */ | 1200 | } /* genConnects */ |
1201 | 1201 | ||
1202 | /* | 1202 | /* |
1203 | generates the whole state of the game. | 1203 | generates the whole state of the game. |
1204 | */ | 1204 | */ |
1205 | genState() | 1205 | genState() |
1206 | { /* genState */ | 1206 | { /* genState */ |
1207 | #ifdef DEBUG | 1207 | #ifdef DEBUG |
1208 | printf( "genState\n" ); | 1208 | printf( "genState\n" ); |
1209 | #endif | 1209 | #endif |
1210 | inGenState = TRUE; | 1210 | inGenState = TRUE; |
1211 | respreicen(); | 1211 | respreicen(); |
1212 | markDead(); | 1212 | markDead(); |
1213 | markLive(); | 1213 | markLive(); |
1214 | spread(); | 1214 | spread(); |
1215 | genConnects(); | 1215 | genConnects(); |
1216 | #ifdef DEBUG | 1216 | #ifdef DEBUG |
1217 | /* printBoard( claim, "claim" ); */ | 1217 | /* printBoard( claim, "claim" ); */ |
1218 | /* printBoard( bord, "bord" ); */ | 1218 | /* printBoard( bord, "bord" ); */ |
1219 | /* printBoard( ndbord, "ndbord" ); | 1219 | /* printBoard( ndbord, "ndbord" ); |
1220 | printBoard( sGroups, "sGroups" ); | 1220 | printBoard( sGroups, "sGroups" ); |
1221 | printBoard( groupIDs, "groupIDs" ); | 1221 | printBoard( groupIDs, "groupIDs" ); |
1222 | printBoard( connectMap, "connectMap" ); | 1222 | printBoard( connectMap, "connectMap" ); |
1223 | printBoard( protPoints, "protPoints" ); */ | 1223 | printBoard( protPoints, "protPoints" ); */ |
1224 | #endif | 1224 | #endif |
1225 | inGenState = FALSE; | 1225 | inGenState = FALSE; |
1226 | } /* genState */ | 1226 | } /* genState */ |
1227 | 1227 | ||
1228 | /* | 1228 | /* |
1229 | generates a value for the [x, y] location that appears to get larger | 1229 | generates a value for the [x, y] location that appears to get larger |
1230 | for points that are saddle points in the influence graph (klein) | 1230 | for points that are saddle points in the influence graph (klein) |
1231 | */ | 1231 | */ |
1232 | short tencen(x, y) | 1232 | short tencen(x, y) |
1233 | short x, y; | 1233 | short x, y; |
1234 | { /* tencen */ | 1234 | { /* tencen */ |
1235 | short a, b, c, d, w, z; | 1235 | short a, b, c, d, w, z; |
1236 | #ifdef DEBUG | 1236 | #ifdef DEBUG |
1237 | printf( "tencen\n" ); | 1237 | printf( "tencen\n" ); |
1238 | #endif | 1238 | #endif |
1239 | if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */ | 1239 | if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */ |
1240 | { | 1240 | { |
1241 | return 50; | 1241 | return 50; |
1242 | } | 1242 | } |
1243 | w = claim[x][y]; /* w <= -1 */ | 1243 | w = claim[x][y]; /* w <= -1 */ |
1244 | a = iNil; | 1244 | a = iNil; |
1245 | if (x > 0) | 1245 | if (x > 0) |
1246 | if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */ | 1246 | if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */ |
1247 | a = claim[x - 1][y] - w; /* score is sum of his influence on central */ | 1247 | a = claim[x - 1][y] - w; /* score is sum of his influence on central */ |
1248 | b = iNil; /* point and my influence on this neighbor */ | 1248 | b = iNil; /* point and my influence on this neighbor */ |
1249 | if (y > 0) | 1249 | if (y > 0) |
1250 | if (claim[x][y - 1] > -1) | 1250 | if (claim[x][y - 1] > -1) |
1251 | b = claim[x][y - 1] - w; | 1251 | b = claim[x][y - 1] - w; |
1252 | c = iNil; | 1252 | c = iNil; |
1253 | if (x < maxPoint) | 1253 | if (x < maxPoint) |
1254 | if (claim[x + 1][y] > -1) | 1254 | if (claim[x + 1][y] > -1) |
1255 | c = claim[x + 1][y] - w; | 1255 | c = claim[x + 1][y] - w; |
1256 | d = iNil; | 1256 | d = iNil; |
1257 | if (y < maxPoint) | 1257 | if (y < maxPoint) |
1258 | if (claim[x][y + 1] > -1) | 1258 | if (claim[x][y + 1] > -1) |
1259 | d = claim[x][y + 1] - w; | 1259 | d = claim[x][y + 1] - w; |
1260 | z = a; /* z = max(a, b, c, d) */ | 1260 | z = a; /* z = max(a, b, c, d) */ |
1261 | if (z != iNil) | 1261 | if (z != iNil) |
1262 | { | 1262 | { |
1263 | if ((b != iNil) && | 1263 | if ((b != iNil) && |
1264 | (b > z)) | 1264 | (b > z)) |
1265 | z = b; | 1265 | z = b; |
1266 | } | 1266 | } |
1267 | else | 1267 | else |
1268 | z = b; | 1268 | z = b; |
1269 | if (z != iNil) | 1269 | if (z != iNil) |
1270 | { | 1270 | { |
1271 | if ((c != iNil) && | 1271 | if ((c != iNil) && |
1272 | (c > z)) | 1272 | (c > z)) |
1273 | z = c; | 1273 | z = c; |
1274 | } | 1274 | } |
1275 | else | 1275 | else |
1276 | z = c; | 1276 | z = c; |
1277 | if (z != iNil) | 1277 | if (z != iNil) |
1278 | { | 1278 | { |
1279 | if ((d != iNil) && | 1279 | if ((d != iNil) && |
1280 | (d > z)) | 1280 | (d > z)) |
1281 | z = d; | 1281 | z = d; |
1282 | } | 1282 | } |
1283 | else | 1283 | else |
1284 | z = d; | 1284 | z = d; |
1285 | if ((z != iNil) && | 1285 | if ((z != iNil) && |
1286 | ((x == 0) || | 1286 | ((x == 0) || |
1287 | (y == 0) || | 1287 | (y == 0) || |
1288 | (x == maxPoint) || | 1288 | (x == maxPoint) || |
1289 | (y == maxPoint))) | 1289 | (y == maxPoint))) |
1290 | z = z * 2; /* double z if (on the edge of the board ?? */ | 1290 | z = z * 2; /* double z if (on the edge of the board ?? */ |
1291 | if (z != iNil) | 1291 | if (z != iNil) |
1292 | return z; | 1292 | return z; |
1293 | else | 1293 | else |
1294 | return 50; | 1294 | return 50; |
1295 | } /* tencen */ | 1295 | } /* tencen */ |
1296 | 1296 | ||
1297 | initGPUtils() | 1297 | initGPUtils() |
1298 | { /* initGPUtils */ | 1298 | { /* initGPUtils */ |
1299 | #ifdef DEBUG | 1299 | #ifdef DEBUG |
1300 | printf( "initGPUtils\n" ); | 1300 | printf( "initGPUtils\n" ); |
1301 | #endif | 1301 | #endif |
1302 | initArray(markBoard); | 1302 | initArray(markBoard); |
1303 | initState(); | 1303 | initState(); |
diff --git a/noncore/games/go/killable.c b/noncore/games/go/killable.c index 3ed2d2e..23a133d 100644 --- a/noncore/games/go/killable.c +++ b/noncore/games/go/killable.c | |||
@@ -1,373 +1,373 @@ | |||
1 | /* By Stoney Ballard */ | 1 | /* By Stoney Ballard */ |
2 | /* Ported from Pascal to C by Todd R. Johnson */ | 2 | /* Ported from Pascal to C by Todd R. Johnson */ |
3 | 3 | ||
4 | #include "go.h" | 4 | #include "go.h" |
5 | #include "goplayutils.h" | 5 | #include "goplayutils.h" |
6 | #include "amigo.h" | 6 | #include "amigo.h" |
7 | 7 | ||
8 | extern intBoard bord, groupIDs; | 8 | extern intBoard bord, groupIDs; |
9 | extern boolBoard legal; | 9 | extern boolBoard legal; |
10 | extern groupRec gList[maxGroup]; | 10 | extern groupRec gList[maxGroup]; |
11 | extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim, | 11 | extern short gMap[maxGroup], adjInAtari, adj2Libs, playMark, treeLibLim, |
12 | utilPlayLevel, killFlag, depthLimit, dbStop, showTrees; | 12 | utilPlayLevel, killFlag, depthLimit, dbStop, showTrees; |
13 | extern pointList plist2; | 13 | extern pointList plist2; |
14 | 14 | ||
15 | /* | 15 | /* |
16 | returns true if the group (at x, y) is killable. | 16 | returns true if the group (at x, y) is killable. |
17 | if so, returns the point to play at in killx, killy. | 17 | if so, returns the point to play at in killx, killy. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | short me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2; | 20 | short me, him, depth, i, j, tryCount, tl, topMark, tkMark, mark2; |
21 | char sChar; | 21 | char sChar; |
22 | sPointList lList, dList; | 22 | sPointList lList, dList; |
23 | point tp; | 23 | point tp; |
24 | short libList[maxSPoint+1]; | 24 | short libList[maxSPoint+1]; |
25 | short esc; | 25 | short esc; |
26 | 26 | ||
27 | short mtNbrs(x, y) | 27 | short mtNbrs(x, y) |
28 | short x, y; | 28 | short x, y; |
29 | { /* mtNbrs */ | 29 | { /* mtNbrs */ |
30 | short n = 0; | 30 | short n = 0; |
31 | if ((x > 0) && (bord[x - 1][y] == 0)) | 31 | if ((x > 0) && (bord[x - 1][y] == 0)) |
32 | n = n + 1; | 32 | n = n + 1; |
33 | if ((x < maxPoint) && (bord[x + 1][y] == 0)) | 33 | if ((x < maxPoint) && (bord[x + 1][y] == 0)) |
34 | n = n + 1; | 34 | n = n + 1; |
35 | if ((y > 0) && (bord[x][y - 1] == 0)) | 35 | if ((y > 0) && (bord[x][y - 1] == 0)) |
36 | n = n + 1; | 36 | n = n + 1; |
37 | if ((y < maxPoint) && (bord[x][y + 1] == 0)) | 37 | if ((y < maxPoint) && (bord[x][y + 1] == 0)) |
38 | n = n + 1; | 38 | n = n + 1; |
39 | return n; | 39 | return n; |
40 | } /* mtNbrs */ | 40 | } /* mtNbrs */ |
41 | 41 | ||
42 | short killTree(tx, ty, gx, gy, escape, tkMark) | 42 | short killTree(tx, ty, gx, gy, escape, tkMark) |
43 | short tx, ty, gx, gy, *escape, tkMark; | 43 | short tx, ty, gx, gy, *escape, tkMark; |
44 | { /* killTree */ | 44 | { /* killTree */ |
45 | short curMark, mark2, mark3, i, j, k, tl, dStart, result; | 45 | short curMark, mark2, mark3, i, j, k, tl, dStart, result; |
46 | sPointList lList1, lList2; | 46 | sPointList lList1, lList2; |
47 | short libList[maxSPoint+1]; | 47 | short libList[maxSPoint+1]; |
48 | point tp; | 48 | point tp; |
49 | short esc = FALSE; | 49 | short esc = FALSE; |
50 | tryCount = tryCount + 1; | 50 | tryCount = tryCount + 1; |
51 | if (tryCount > tryLimit) | 51 | if (tryCount > tryLimit) |
52 | { | 52 | { |
53 | undoTo(tkMark); | 53 | undoTo(tkMark); |
54 | /* for (i = 1; i <= depth - 1; i++) | 54 | /* for (i = 1; i <= depth - 1; i++) |
55 | { | 55 | { |
56 | sClearChar(sChar, rXor); | 56 | sClearChar(sChar, rXor); |
57 | } */ | 57 | } */ |
58 | depth = 1; | 58 | depth = 1; |
59 | return FALSE; | 59 | return FALSE; |
60 | } | 60 | } |
61 | /* write(sChar); */ | 61 | /* write(sChar); */ |
62 | depth = depth + 1; | 62 | depth = depth + 1; |
63 | curMark = playMark; | 63 | curMark = playMark; |
64 | tryPlay(tx, ty, me); /* try my move */ | 64 | tryPlay(tx, ty, me); /* try my move */ |
65 | pause(); | 65 | // pause(); |
66 | if (gList[gMap[groupIDs[tx][ty]]].libC == 0) /* I'm dead */ | 66 | if (gList[gMap[groupIDs[tx][ty]]].libC == 0) /* I'm dead */ |
67 | { | 67 | { |
68 | result = FALSE; | 68 | result = FALSE; |
69 | goto one; | 69 | goto one; |
70 | } | 70 | } |
71 | else if (killFlag) /* I killed something of his */ | 71 | else if (killFlag) /* I killed something of his */ |
72 | { | 72 | { |
73 | result = TRUE; | 73 | result = TRUE; |
74 | goto one; | 74 | goto one; |
75 | } | 75 | } |
76 | else if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) /* safe */ | 76 | else if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) /* safe */ |
77 | { | 77 | { |
78 | result = FALSE; | 78 | result = FALSE; |
79 | goto one; | 79 | goto one; |
80 | } | 80 | } |
81 | else | 81 | else |
82 | { | 82 | { |
83 | sSpanGroup(gx, gy, &lList1); /* find his liberties */ | 83 | sSpanGroup(gx, gy, &lList1); /* find his liberties */ |
84 | if (gList[gMap[groupIDs[tx][ty]]].libC == 1) /* he can kill me */ | 84 | if (gList[gMap[groupIDs[tx][ty]]].libC == 1) /* he can kill me */ |
85 | { | 85 | { |
86 | if (lList1.indx < maxSPoint) /* add that option to his list */ | 86 | if (lList1.indx < maxSPoint) /* add that option to his list */ |
87 | { | 87 | { |
88 | lList1.indx = lList1.indx + 1; | 88 | lList1.indx = lList1.indx + 1; |
89 | spanGroup(tx, ty, &plist2); /* find my liberty */ | 89 | spanGroup(tx, ty, &plist2); /* find my liberty */ |
90 | lList1.p[lList1.indx].px = plist2.p[1].px; | 90 | lList1.p[lList1.indx].px = plist2.p[1].px; |
91 | lList1.p[lList1.indx].py = plist2.p[1].py; | 91 | lList1.p[lList1.indx].py = plist2.p[1].py; |
92 | } | 92 | } |
93 | else | 93 | else |
94 | { | 94 | { |
95 | result = FALSE; | 95 | result = FALSE; |
96 | goto one; | 96 | goto one; |
97 | } | 97 | } |
98 | } | 98 | } |
99 | for (i = 1; i <= maxSPoint; i++) /* init liblist so diags can be marked */ | 99 | for (i = 1; i <= maxSPoint; i++) /* init liblist so diags can be marked */ |
100 | libList[i] = -1; | 100 | libList[i] = -1; |
101 | if ((utilPlayLevel > 4) && | 101 | if ((utilPlayLevel > 4) && |
102 | (lList1.indx > 1) && | 102 | (lList1.indx > 1) && |
103 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* try diags */ | 103 | (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* try diags */ |
104 | { | 104 | { |
105 | listDiags(gx, gy, &dList); | 105 | listDiags(gx, gy, &dList); |
106 | j = 0; | 106 | j = 0; |
107 | i = lList1.indx; | 107 | i = lList1.indx; |
108 | while ((j < dList.indx) && | 108 | while ((j < dList.indx) && |
109 | (i < maxSPoint)) | 109 | (i < maxSPoint)) |
110 | { | 110 | { |
111 | j = j + 1; | 111 | j = j + 1; |
112 | i = i + 1; | 112 | i = i + 1; |
113 | libList[i] = 0; /* mark this as a diag */ | 113 | libList[i] = 0; /* mark this as a diag */ |
114 | lList1.p[i].px = dList.p[j].px; | 114 | lList1.p[i].px = dList.p[j].px; |
115 | lList1.p[i].py = dList.p[j].py; | 115 | lList1.p[i].py = dList.p[j].py; |
116 | } | 116 | } |
117 | lList1.indx = i; | 117 | lList1.indx = i; |
118 | } | 118 | } |
119 | if (lList1.indx > 1) /* sort by decreasing lib count */ | 119 | if (lList1.indx > 1) /* sort by decreasing lib count */ |
120 | { | 120 | { |
121 | for (i = 1; i <= lList1.indx; i++) | 121 | for (i = 1; i <= lList1.indx; i++) |
122 | if (libList[i] != 0) /* diags are tried last */ | 122 | if (libList[i] != 0) /* diags are tried last */ |
123 | { | 123 | { |
124 | mark2 = playMark; | 124 | mark2 = playMark; |
125 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); | 125 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); |
126 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | 126 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; |
127 | if ((libList[i] > treeLibLim) || | 127 | if ((libList[i] > treeLibLim) || |
128 | ((libList[i] > (depthLimit - depth)) && | 128 | ((libList[i] > (depthLimit - depth)) && |
129 | (libList[i] > 2))) | 129 | (libList[i] > 2))) |
130 | { | 130 | { |
131 | *escape = TRUE; | 131 | *escape = TRUE; |
132 | result = FALSE; | 132 | result = FALSE; |
133 | goto one; | 133 | goto one; |
134 | } | 134 | } |
135 | undoTo(mark2); | 135 | undoTo(mark2); |
136 | } | 136 | } |
137 | for (i = 1; i <= lList1.indx - 1; i++) | 137 | for (i = 1; i <= lList1.indx - 1; i++) |
138 | for (j = i + 1; j <= lList1.indx; j++) | 138 | for (j = i + 1; j <= lList1.indx; j++) |
139 | if (libList[i] < libList[j]) | 139 | if (libList[i] < libList[j]) |
140 | { | 140 | { |
141 | tl = libList[i]; | 141 | tl = libList[i]; |
142 | libList[i] = libList[j]; | 142 | libList[i] = libList[j]; |
143 | libList[j] = tl; | 143 | libList[j] = tl; |
144 | tp = lList1.p[i]; | 144 | tp = lList1.p[i]; |
145 | lList1.p[i] = lList1.p[j]; | 145 | lList1.p[i] = lList1.p[j]; |
146 | lList1.p[j] = tp; | 146 | lList1.p[j] = tp; |
147 | } | 147 | } |
148 | } | 148 | } |
149 | for (i = 1; i <= lList1.indx + 1; i++) /* try his responses */ | 149 | for (i = 1; i <= lList1.indx + 1; i++) /* try his responses */ |
150 | { | 150 | { |
151 | mark2 = playMark; | 151 | mark2 = playMark; |
152 | if (i <= lList1.indx) /* try his move */ | 152 | if (i <= lList1.indx) /* try his move */ |
153 | { | 153 | { |
154 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); /* play his response */ | 154 | tryPlay(lList1.p[i].px, lList1.p[i].py, him); /* play his response */ |
155 | pause(); | 155 | // pause(); |
156 | if (gList[gMap[groupIDs[lList1.p[i].px] | 156 | if (gList[gMap[groupIDs[lList1.p[i].px] |
157 | [lList1.p[i].py]]].libC < 2) | 157 | [lList1.p[i].py]]].libC < 2) |
158 | goto two; /* a bogus move */ | 158 | goto two; /* a bogus move */ |
159 | } | 159 | } |
160 | else if (gList[gMap[groupIDs[gx][gy]]].libC <= 1) | 160 | else if (gList[gMap[groupIDs[gx][gy]]].libC <= 1) |
161 | { | 161 | { |
162 | result = TRUE; | 162 | result = TRUE; |
163 | goto one; | 163 | goto one; |
164 | } | 164 | } |
165 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) | 165 | if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim) |
166 | { | 166 | { |
167 | *escape = TRUE; | 167 | *escape = TRUE; |
168 | result = FALSE; | 168 | result = FALSE; |
169 | goto one; | 169 | goto one; |
170 | } | 170 | } |
171 | if (gList[gMap[groupIDs[gx][gy]]].libC > 1) | 171 | if (gList[gMap[groupIDs[gx][gy]]].libC > 1) |
172 | { /* look at my responses */ | 172 | { /* look at my responses */ |
173 | sSpanGroup(gx, gy, &lList2); /* list his liberties */ | 173 | sSpanGroup(gx, gy, &lList2); /* list his liberties */ |
174 | dStart = lList2.indx + 1; | 174 | dStart = lList2.indx + 1; |
175 | if (adjInAtari) /* he wins */ | 175 | if (adjInAtari) /* he wins */ |
176 | { | 176 | { |
177 | result = FALSE; | 177 | result = FALSE; |
178 | goto one; | 178 | goto one; |
179 | } | 179 | } |
180 | if ((lList2.indx > 2) && adj2Libs) /* he wins */ | 180 | if ((lList2.indx > 2) && adj2Libs) /* he wins */ |
181 | { | 181 | { |
182 | result = FALSE; | 182 | result = FALSE; |
183 | goto one; | 183 | goto one; |
184 | } | 184 | } |
185 | for (k = 1; k <= maxSPoint; k++) | 185 | for (k = 1; k <= maxSPoint; k++) |
186 | libList[k] = -1; | 186 | libList[k] = -1; |
187 | if (utilPlayLevel > 4) /* account for diagonal moves */ | 187 | if (utilPlayLevel > 4) /* account for diagonal moves */ |
188 | { | 188 | { |
189 | listDiags(gx, gy, &dList); | 189 | listDiags(gx, gy, &dList); |
190 | j = 0; | 190 | j = 0; |
191 | k = lList2.indx; | 191 | k = lList2.indx; |
192 | while ((j < dList.indx) && | 192 | while ((j < dList.indx) && |
193 | (k < maxSPoint)) | 193 | (k < maxSPoint)) |
194 | { | 194 | { |
195 | j = j + 1; | 195 | j = j + 1; |
196 | k = k + 1; | 196 | k = k + 1; |
197 | libList[k] = 100; | 197 | libList[k] = 100; |
198 | lList2.p[k].px = dList.p[j].px; | 198 | lList2.p[k].px = dList.p[j].px; |
199 | lList2.p[k].py = dList.p[j].py; | 199 | lList2.p[k].py = dList.p[j].py; |
200 | } | 200 | } |
201 | lList2.indx = k; | 201 | lList2.indx = k; |
202 | } | 202 | } |
203 | if (lList2.indx > 1) /* sort by increasing lib count */ | 203 | if (lList2.indx > 1) /* sort by increasing lib count */ |
204 | { | 204 | { |
205 | for (k = 1; k <= lList2.indx; k++) | 205 | for (k = 1; k <= lList2.indx; k++) |
206 | if (libList[k] != 100) /* diags go last */ | 206 | if (libList[k] != 100) /* diags go last */ |
207 | { | 207 | { |
208 | mark3 = playMark; | 208 | mark3 = playMark; |
209 | tryPlay(lList2.p[k].px, lList2.p[k].py, me); | 209 | tryPlay(lList2.p[k].px, lList2.p[k].py, me); |
210 | libList[k] = gList[gMap[groupIDs[gx][gy]]].libC; | 210 | libList[k] = gList[gMap[groupIDs[gx][gy]]].libC; |
211 | undoTo(mark3); | 211 | undoTo(mark3); |
212 | } | 212 | } |
213 | for (k = 1; k <= lList2.indx - 1; k++) | 213 | for (k = 1; k <= lList2.indx - 1; k++) |
214 | for (j = k + 1; j <= lList2.indx; j++) | 214 | for (j = k + 1; j <= lList2.indx; j++) |
215 | if (libList[k] > libList[j]) | 215 | if (libList[k] > libList[j]) |
216 | { | 216 | { |
217 | tl = libList[k]; | 217 | tl = libList[k]; |
218 | libList[k] = libList[j]; | 218 | libList[k] = libList[j]; |
219 | libList[j] = tl; | 219 | libList[j] = tl; |
220 | tp = lList2.p[k]; | 220 | tp = lList2.p[k]; |
221 | lList2.p[k] = lList2.p[j]; | 221 | lList2.p[k] = lList2.p[j]; |
222 | lList2.p[j] = tp; | 222 | lList2.p[j] = tp; |
223 | } | 223 | } |
224 | else if ((libList[k] == libList[j]) && | 224 | else if ((libList[k] == libList[j]) && |
225 | (libList[k] == 1)) | 225 | (libList[k] == 1)) |
226 | if (mtNbrs(lList2.p[k].px, lList2.p[k].py) < | 226 | if (mtNbrs(lList2.p[k].px, lList2.p[k].py) < |
227 | mtNbrs(lList2.p[j].px, lList2.p[j].py)) | 227 | mtNbrs(lList2.p[j].px, lList2.p[j].py)) |
228 | { | 228 | { |
229 | tl = libList[k]; | 229 | tl = libList[k]; |
230 | libList[k] = libList[j]; | 230 | libList[k] = libList[j]; |
231 | libList[j] = tl; | 231 | libList[j] = tl; |
232 | tp = lList2.p[k]; | 232 | tp = lList2.p[k]; |
233 | lList2.p[k] = lList2.p[j]; | 233 | lList2.p[k] = lList2.p[j]; |
234 | lList2.p[j] = tp; | 234 | lList2.p[j] = tp; |
235 | } | 235 | } |
236 | } | 236 | } |
237 | for (j = 1; j <= lList2.indx; j++) | 237 | for (j = 1; j <= lList2.indx; j++) |
238 | { | 238 | { |
239 | if (killTree(lList2.p[j].px, lList2.p[j].py, gx, | 239 | if (killTree(lList2.p[j].px, lList2.p[j].py, gx, |
240 | gy, &esc, tkMark)) | 240 | gy, &esc, tkMark)) |
241 | goto two; /* this kills him */ | 241 | goto two; /* this kills him */ |
242 | if (esc && (j >= dStart)) | 242 | if (esc && (j >= dStart)) |
243 | { | 243 | { |
244 | result = FALSE; | 244 | result = FALSE; |
245 | goto one; /* don't bother with more diags if escapes */ | 245 | goto one; /* don't bother with more diags if escapes */ |
246 | } | 246 | } |
247 | } | 247 | } |
248 | result = FALSE; /* none of my responses kills him */ | 248 | result = FALSE; /* none of my responses kills him */ |
249 | goto one; | 249 | goto one; |
250 | } | 250 | } |
251 | two: | 251 | two: |
252 | undoTo(mark2); | 252 | undoTo(mark2); |
253 | } | 253 | } |
254 | result = TRUE; /* none of his responses saves him */ | 254 | result = TRUE; /* none of his responses saves him */ |
255 | } | 255 | } |
256 | one: | 256 | one: |
257 | undoTo(curMark); | 257 | undoTo(curMark); |
258 | /* sClearChar(sChar, rXor); */ | 258 | /* sClearChar(sChar, rXor); */ |
259 | depth = depth - 1; | 259 | depth = depth - 1; |
260 | return result; | 260 | return result; |
261 | } /* killTree */ | 261 | } /* killTree */ |
262 | 262 | ||
263 | short tKillTree(tx, ty, gx, gy) | 263 | short tKillTree(tx, ty, gx, gy) |
264 | short tx, ty, gx, gy; | 264 | short tx, ty, gx, gy; |
265 | { /* tKillTree */ | 265 | { /* tKillTree */ |
266 | short tkMark, escape; | 266 | short tkMark, escape; |
267 | tryCount = 0; | 267 | tryCount = 0; |
268 | tkMark = playMark; | 268 | tkMark = playMark; |
269 | return killTree(tx, ty, gx, gy, &escape, tkMark); | 269 | return killTree(tx, ty, gx, gy, &escape, tkMark); |
270 | } /* tKillTree */ | 270 | } /* tKillTree */ |
271 | 271 | ||
272 | short killable(gx, gy, killx, killy) | 272 | short killable(gx, gy, killx, killy) |
273 | short gx, gy, *killx, *killy; | 273 | short gx, gy, *killx, *killy; |
274 | { /* killable */ | 274 | { /* killable */ |
275 | #ifdef DEBUG | 275 | #ifdef DEBUG |
276 | printf( "killable\n" ); | 276 | printf( "killable\n" ); |
277 | showTrees = TRUE; | 277 | showTrees = TRUE; |
278 | #endif | 278 | #endif |
279 | dbStop = TRUE; | 279 | dbStop = TRUE; |
280 | him = bord[gx][gy]; /* find out who I am */ | 280 | him = bord[gx][gy]; /* find out who I am */ |
281 | me = -him; | 281 | me = -him; |
282 | /* if (me == 1) | 282 | /* if (me == 1) |
283 | sChar = '>'; | 283 | sChar = '>'; |
284 | else | 284 | else |
285 | sChar = '|'; */ | 285 | sChar = '|'; */ |
286 | /* write(sChar); */ | 286 | /* write(sChar); */ |
287 | depth = 1; | 287 | depth = 1; |
288 | topMark = playMark; | 288 | topMark = playMark; |
289 | sSpanGroup(gx, gy, &lList); /* find his liberties */ | 289 | sSpanGroup(gx, gy, &lList); /* find his liberties */ |
290 | if (lList.indx == 1) | 290 | if (lList.indx == 1) |
291 | { | 291 | { |
292 | *killx = lList.p[1].px; | 292 | *killx = lList.p[1].px; |
293 | *killy = lList.p[1].py; | 293 | *killy = lList.p[1].py; |
294 | return TRUE; | 294 | return TRUE; |
295 | } | 295 | } |
296 | else if (lList.indx > treeLibLim) | 296 | else if (lList.indx > treeLibLim) |
297 | return FALSE; | 297 | return FALSE; |
298 | else if (adjInAtari) | 298 | else if (adjInAtari) |
299 | return FALSE; | 299 | return FALSE; |
300 | else if ((lList.indx > 2) && adj2Libs) | 300 | else if ((lList.indx > 2) && adj2Libs) |
301 | return FALSE; | 301 | return FALSE; |
302 | else | 302 | else |
303 | { | 303 | { |
304 | for (i = 1; i <= maxSPoint; i++) | 304 | for (i = 1; i <= maxSPoint; i++) |
305 | libList[i] = -1; | 305 | libList[i] = -1; |
306 | if (utilPlayLevel > 4) /* account for diagonal moves */ | 306 | if (utilPlayLevel > 4) /* account for diagonal moves */ |
307 | { | 307 | { |
308 | listDiags(gx, gy, &dList); | 308 | listDiags(gx, gy, &dList); |
309 | j = 0; | 309 | j = 0; |
310 | i = lList.indx; | 310 | i = lList.indx; |
311 | while ((j < dList.indx) && | 311 | while ((j < dList.indx) && |
312 | (i < maxSPoint)) | 312 | (i < maxSPoint)) |
313 | { | 313 | { |
314 | j = j + 1; | 314 | j = j + 1; |
315 | i = i + 1; | 315 | i = i + 1; |
316 | libList[i] = 100; | 316 | libList[i] = 100; |
317 | lList.p[i].px = dList.p[j].px; | 317 | lList.p[i].px = dList.p[j].px; |
318 | lList.p[i].py = dList.p[j].py; | 318 | lList.p[i].py = dList.p[j].py; |
319 | } | 319 | } |
320 | lList.indx = i; | 320 | lList.indx = i; |
321 | } | 321 | } |
322 | if (lList.indx > 1) /* sort by increasing lib count */ | 322 | if (lList.indx > 1) /* sort by increasing lib count */ |
323 | { | 323 | { |
324 | for (i = 1; i <= lList.indx; i++) | 324 | for (i = 1; i <= lList.indx; i++) |
325 | if (libList[i] != 100) /* diags go last */ | 325 | if (libList[i] != 100) /* diags go last */ |
326 | { | 326 | { |
327 | mark2 = playMark; | 327 | mark2 = playMark; |
328 | tryPlay(lList.p[i].px, lList.p[i].py, me); | 328 | tryPlay(lList.p[i].px, lList.p[i].py, me); |
329 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; | 329 | libList[i] = gList[gMap[groupIDs[gx][gy]]].libC; |
330 | undoTo(mark2); | 330 | undoTo(mark2); |
331 | } | 331 | } |
332 | for (i = 1; i <= lList.indx - 1; i++) | 332 | for (i = 1; i <= lList.indx - 1; i++) |
333 | for (j = i + 1; j <= lList.indx; j++) | 333 | for (j = i + 1; j <= lList.indx; j++) |
334 | if (libList[i] > libList[j]) | 334 | if (libList[i] > libList[j]) |
335 | { | 335 | { |
336 | tl = libList[i]; | 336 | tl = libList[i]; |
337 | libList[i] = libList[j]; | 337 | libList[i] = libList[j]; |
338 | libList[j] = tl; | 338 | libList[j] = tl; |
339 | tp = lList.p[i]; | 339 | tp = lList.p[i]; |
340 | lList.p[i] = lList.p[j]; | 340 | lList.p[i] = lList.p[j]; |
341 | lList.p[j] = tp; | 341 | lList.p[j] = tp; |
342 | } | 342 | } |
343 | else if ((libList[i] == libList[j]) && | 343 | else if ((libList[i] == libList[j]) && |
344 | (libList[i] == 1)) | 344 | (libList[i] == 1)) |
345 | if (mtNbrs(lList.p[i].px, lList.p[i].py) < | 345 | if (mtNbrs(lList.p[i].px, lList.p[i].py) < |
346 | mtNbrs(lList.p[j].px, lList.p[j].py)) | 346 | mtNbrs(lList.p[j].px, lList.p[j].py)) |
347 | { | 347 | { |
348 | tl = libList[i]; | 348 | tl = libList[i]; |
349 | libList[i] = libList[j]; | 349 | libList[i] = libList[j]; |
350 | libList[j] = tl; | 350 | libList[j] = tl; |
351 | tp = lList.p[i]; | 351 | tp = lList.p[i]; |
352 | lList.p[i] = lList.p[j]; | 352 | lList.p[i] = lList.p[j]; |
353 | lList.p[j] = tp; | 353 | lList.p[j] = tp; |
354 | } | 354 | } |
355 | } | 355 | } |
356 | for (i = 1; i <= lList.indx; i++) | 356 | for (i = 1; i <= lList.indx; i++) |
357 | { | 357 | { |
358 | if (legal[lList.p[i].px][lList.p[i].py]) | 358 | if (legal[lList.p[i].px][lList.p[i].py]) |
359 | { | 359 | { |
360 | *killx = lList.p[i].px; | 360 | *killx = lList.p[i].px; |
361 | *killy = lList.p[i].py; | 361 | *killy = lList.p[i].py; |
362 | if (tKillTree(*killx, *killy, gx, gy)) | 362 | if (tKillTree(*killx, *killy, gx, gy)) |
363 | { | 363 | { |
364 | /* sClearChar(sChar, rXor); */ | 364 | /* sClearChar(sChar, rXor); */ |
365 | return TRUE; | 365 | return TRUE; |
366 | } | 366 | } |
367 | } | 367 | } |
368 | } | 368 | } |
369 | return FALSE; | 369 | return FALSE; |
370 | } | 370 | } |
371 | /* sClearChar(sChar, rXor); */ | 371 | /* sClearChar(sChar, rXor); */ |
372 | } /* killable */ | 372 | } /* killable */ |
373 | 373 | ||