RCS file: /sources/gnugo/gnugo/engine/value_moves.c,v
retrieving revision 1.170
diff -u -r1.170 value_moves.c
|
|
|
|
| 146 | 146 | TRACE("\nLooking for additional attack and defense moves. Trying moves ...\n"); |
| 147 | 147 | |
| 148 | 148 | /* Identify the unstable worms and store them in a list. */ |
| 149 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) { |
| | 149 | scan_board(ii, |
| 150 | 150 | if (IS_STONE(board[ii]) |
| 151 | 151 | && worm[ii].origin == ii |
| 152 | 152 | && worm[ii].attack_codes[0] != 0 |
| … |
… |
|
| 154 | 154 | unstable_worms[N] = ii; |
| 155 | 155 | N++; |
| 156 | 156 | } |
| 157 | | } |
| | 157 | ) |
| 158 | 158 | |
| 159 | 159 | /* To avoid horizon effects, we temporarily increase the depth values. */ |
| 160 | 160 | increase_depth_values(); |
| 161 | 161 | |
| 162 | | for (ii = BOARDMIN; ii < BOARDMAX; ii++) { |
| 163 | | if (!ON_BOARD(ii)) |
| 164 | | continue; |
| | 162 | scan_board(ii, |
| 165 | 163 | |
| 166 | 164 | /* Don't consider send-two-return-one moves here. */ |
| 167 | 165 | if (send_two_return_one(ii, color)) |
| … |
… |
|
| 278 | 276 | } |
| 279 | 277 | popgo(); |
| 280 | 278 | } |
| 281 | | } |
| | 279 | ) |
| 282 | 280 | |
| 283 | 281 | TRACE("\n"); |
| 284 | 282 | decrease_depth_values(); |
| … |
… |
|
| 577 | 575 | if (verbose) |
| 578 | 576 | gprintf("\nTrying to upgrade strategical attack and defense moves.\n"); |
| 579 | 577 | |
| 580 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 581 | | if (!ON_BOARD(pos)) |
| 582 | | continue; |
| | 578 | scan_board(pos, |
| 583 | 579 | |
| 584 | 580 | for (k = 0; k < MAX_REASONS; k++) { |
| 585 | 581 | int r = move[pos].reason[k]; |
| … |
… |
|
| 590 | 586 | move_reasons[r].type, |
| 591 | 587 | move_reasons[r].what); |
| 592 | 588 | } |
| 593 | | } |
| | 589 | ) |
| 594 | 590 | |
| 595 | 591 | if (verbose) |
| 596 | 592 | gprintf("\nTrying vital eye moves as owl attacks.\n"); |
| … |
… |
|
| 607 | 603 | your_vital_points = white_vital_points; |
| 608 | 604 | } |
| 609 | 605 | |
| 610 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 611 | | if (!ON_BOARD(pos)) |
| 612 | | continue; |
| | 606 | scan_board(pos, |
| 613 | 607 | if (our_eyes[pos].origin == pos |
| 614 | 608 | && our_vital_points[pos].defense_points[0] != NO_MOVE) { |
| 615 | | int k, dr; |
| | 609 | int k; |
| | 610 | int dr; |
| 616 | 611 | find_eye_dragons(pos, our_eyes, color, &dr, 1); |
| 617 | 612 | for (k = 0; k < MAX_EYE_ATTACKS; k++) { |
| 618 | 613 | int move = our_vital_points[pos].defense_points[k]; |
| … |
… |
|
| 624 | 619 | } |
| 625 | 620 | if (your_eyes[pos].origin == pos |
| 626 | 621 | && your_vital_points[pos].attack_points[0] != NO_MOVE) { |
| 627 | | int k, dr; |
| | 622 | int k; |
| | 623 | int dr; |
| 628 | 624 | find_eye_dragons(pos, your_eyes, OTHER_COLOR(color), &dr, 1); |
| 629 | 625 | for (k = 0; k < MAX_EYE_ATTACKS; k++) { |
| 630 | 626 | int move = your_vital_points[pos].attack_points[k]; |
| … |
… |
|
| 634 | 630 | VITAL_EYE_MOVE, dr); |
| 635 | 631 | } |
| 636 | 632 | } |
| 637 | | } |
| | 633 | ) |
| 638 | 634 | |
| 639 | 635 | save_verbose = verbose; |
| 640 | 636 | if (verbose > 0) |
| … |
… |
|
| 643 | 639 | /* If two critical dragons are adjacent, test whether a move to owl |
| 644 | 640 | * attack or defend one also is effective on the other. |
| 645 | 641 | */ |
| 646 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 642 | scan_board(pos, |
| 647 | 643 | if (IS_STONE(board[pos]) |
| 648 | 644 | && dragon[pos].origin == pos |
| 649 | 645 | && DRAGON2(pos).owl_status == CRITICAL) { |
| 650 | | for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) { |
| | 646 | scan_board(pos2, |
| 651 | 647 | if (board[pos2] != EMPTY) |
| 652 | 648 | continue; |
| 653 | 649 | worth_trying = 0; |
| … |
… |
|
| 701 | 697 | } |
| 702 | 698 | } |
| 703 | 699 | } |
| 704 | | } |
| 705 | | } |
| 706 | | } |
| | 700 | ) |
| | 701 | } |
| | 702 | ) |
| 707 | 703 | |
| 708 | 704 | verbose = save_verbose; |
| 709 | 705 | } |
| … |
… |
|
| 760 | 756 | if (verbose > 0) |
| 761 | 757 | verbose--; |
| 762 | 758 | |
| 763 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 764 | | int k, r; |
| | 759 | scan_board(pos, |
| | 760 | int k; |
| | 761 | int r; |
| 765 | 762 | int potential_semeai_move_found = 0; |
| 766 | 763 | int other_move_reason_found = 0; |
| 767 | 764 | |
| 768 | | if (!ON_BOARD1(pos)) |
| 769 | | continue; |
| 770 | 765 | for (k = 0; k < MAX_REASONS; k++) { |
| 771 | 766 | r = move[pos].reason[k]; |
| 772 | 767 | if (r < 0) |
| … |
… |
|
| 794 | 789 | || move_reasons[r].type == POTENTIAL_SEMEAI_DEFENSE) |
| 795 | 790 | try_potential_semeai_move(pos, color, &(move_reasons[r])); |
| 796 | 791 | } |
| 797 | | } |
| | 792 | ) |
| 798 | 793 | verbose = save_verbose; |
| 799 | 794 | } |
| 800 | 795 | |
| … |
… |
|
| 827 | 822 | int i, j; |
| 828 | 823 | int aa; |
| 829 | 824 | |
| 830 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 831 | | if (!ON_BOARD(pos)) |
| 832 | | continue; |
| | 825 | scan_board(pos, |
| 833 | 826 | |
| 834 | 827 | for (k = 0; k < MAX_REASONS; k++) { |
| 835 | 828 | int r = move[pos].reason[k]; |
| … |
… |
|
| 841 | 834 | || move_reasons[r].type == DEFEND_MOVE) { |
| 842 | 835 | int attack_move; |
| 843 | 836 | int color_to_move; |
| 844 | | int num_adj, adjs[MAXCHAIN]; |
| | 837 | int num_adj; |
| | 838 | int adjs[MAXCHAIN]; |
| 845 | 839 | |
| 846 | 840 | aa = move_reasons[r].what; |
| 847 | 841 | |
| … |
… |
|
| 1009 | 1003 | int worm1 = conn_worm1[move_reasons[r].what]; |
| 1010 | 1004 | int worm2 = conn_worm2[move_reasons[r].what]; |
| 1011 | 1005 | int pos2; |
| 1012 | | for (pos2 = BOARDMIN; pos2 < BOARDMAX; pos2++) { |
| 1013 | | if (ON_BOARD(pos2) && board[pos2] == EMPTY |
| | 1006 | scan_board(pos2, |
| | 1007 | if (board[pos2] == EMPTY |
| 1014 | 1008 | && cut_possible(pos2, OTHER_COLOR(color)) |
| 1015 | 1009 | && square_dist(pos, pos2) <= 5) { |
| 1016 | 1010 | for (j = 0; j < 8; j++) { |
| … |
… |
|
| 1043 | 1037 | } |
| 1044 | 1038 | } |
| 1045 | 1039 | } |
| 1046 | | } |
| | 1040 | ) |
| 1047 | 1041 | } |
| 1048 | 1042 | } |
| 1049 | | } |
| | 1043 | ) |
| 1050 | 1044 | } |
| 1051 | 1045 | |
| 1052 | 1046 | |
| … |
… |
|
| 1063 | 1057 | int k; |
| 1064 | 1058 | |
| 1065 | 1059 | start_timer(3); |
| 1066 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 1060 | scan_board(pos, |
| 1067 | 1061 | int safety = 0; |
| 1068 | 1062 | int tactical_safety = 0; |
| 1069 | | if (!ON_BOARD(pos)) |
| 1070 | | continue; |
| 1071 | 1063 | |
| 1072 | 1064 | for (k = 0; k < MAX_REASONS; k++) { |
| 1073 | 1065 | int r = move[pos].reason[k]; |
| … |
… |
|
| 1170 | 1162 | * below if we were certain that the capturable string |
| 1171 | 1163 | * had not been amalgamated with a living dragon. |
| 1172 | 1164 | */ |
| 1173 | | int num_adj, adjs[MAXCHAIN]; |
| | 1165 | int num_adj; |
| | 1166 | int adjs[MAXCHAIN]; |
| 1174 | 1167 | |
| 1175 | 1168 | num_adj = chainlinks(aa, adjs); |
| 1176 | 1169 | for (m = 0; m < num_adj; m++) { |
| … |
… |
|
| 1322 | 1315 | move[pos].move_safety = 0; |
| 1323 | 1316 | |
| 1324 | 1317 | time_report(3, " examine_move_safety: ", pos, 1.0); |
| 1325 | | } |
| | 1318 | ) |
| 1326 | 1319 | } |
| 1327 | 1320 | |
| 1328 | 1321 | |
| … |
… |
|
| 2933 | 2926 | } |
| 2934 | 2927 | } |
| 2935 | 2928 | |
| 2936 | | for (aa = BOARDMIN; aa < BOARDMAX; aa++) { |
| | 2929 | scan_board(aa, |
| 2937 | 2930 | if (dragon_value[aa] == 0.0) |
| 2938 | 2931 | continue; |
| 2939 | 2932 | |
| … |
… |
|
| 2996 | 2989 | TRACE(" %1m: %f - strategic effect on %1m\n", |
| 2997 | 2990 | pos, dragon_value[aa], aa); |
| 2998 | 2991 | tot_value += dragon_value[aa]; |
| 2999 | | } |
| | 2992 | ) |
| 3000 | 2993 | |
| 3001 | 2994 | /* Finally, subtract penalty for invasion type moves. */ |
| 3002 | 2995 | this_value = strategic_penalty(pos, color); |
| … |
… |
|
| 3332 | 3325 | { |
| 3333 | 3326 | int pos; |
| 3334 | 3327 | |
| 3335 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 3336 | | if (!ON_BOARD(pos) || move[pos].final_value <= 0.0) |
| | 3328 | scan_board(pos, |
| | 3329 | if (move[pos].final_value <= 0.0) |
| 3337 | 3330 | continue; |
| 3338 | 3331 | |
| 3339 | 3332 | gfprintf(output, "%1M %f\n", pos, move[pos].final_value); |
| 3340 | | } |
| | 3333 | ) |
| 3341 | 3334 | } |
| 3342 | 3335 | |
| 3343 | 3336 | /* Search through all board positions for the 10 highest valued |
| … |
… |
|
| 3355 | 3348 | best_moves[k] = NO_MOVE; |
| 3356 | 3349 | best_move_values[k] = 0.0; |
| 3357 | 3350 | } |
| 3358 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| 3359 | | if (!ON_BOARD(pos) || move[pos].final_value <= 0.0) |
| | 3351 | scan_board(pos, |
| | 3352 | if (move[pos].final_value <= 0.0) |
| 3360 | 3353 | continue; |
| 3361 | 3354 | |
| 3362 | 3355 | tval = move[pos].final_value; |
| 3363 | 3356 | record_top_move(pos, tval); |
| 3364 | | } |
| | 3357 | ) |
| 3365 | 3358 | |
| 3366 | 3359 | if (verbose > 0 || (debug & DEBUG_TOP_MOVES)) { |
| 3367 | 3360 | gprintf("\nTop moves:\n"); |
| … |
… |
|
| 3442 | 3435 | } |
| 3443 | 3436 | |
| 3444 | 3437 | TRACE("Reevaluating ko threats.\n"); |
| 3445 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 3438 | scan_board(pos, |
| 3446 | 3439 | int threat_quality = 0; |
| 3447 | 3440 | |
| 3448 | | if (!ON_BOARD(pos) || pos == ko_move) |
| | 3441 | if (pos == ko_move) |
| 3449 | 3442 | continue; |
| 3450 | 3443 | if (move[pos].additional_ko_value <= 0.0) |
| 3451 | 3444 | continue; |
| … |
… |
|
| 3601 | 3594 | DEBUG(DEBUG_MOVE_REASONS, |
| 3602 | 3595 | "%1m: no additional ko value (threat does not work as ko threat)\n", pos); |
| 3603 | 3596 | } |
| 3604 | | } |
| | 3597 | ) |
| 3605 | 3598 | |
| 3606 | 3599 | for (k = 0; k < num_good_threats; k++) { |
| 3607 | 3600 | pos = good_threats[k]; |
| … |
… |
|
| 3635 | 3628 | int source; |
| 3636 | 3629 | int target; |
| 3637 | 3630 | |
| 3638 | | for (target = BOARDMIN; target < BOARDMAX; target++) |
| 3639 | | if (ON_BOARD(target)) |
| 3640 | | move[target].final_value = move[target].value; |
| | 3631 | scan_board(target, |
| | 3632 | move[target].final_value = move[target].value; |
| | 3633 | ) |
| 3641 | 3634 | |
| 3642 | | for (source = BOARDMIN; source < BOARDMAX; source++) { |
| 3643 | | if (!ON_BOARD(source)) |
| 3644 | | continue; |
| | 3635 | scan_board(source, |
| 3645 | 3636 | target = replacement_map[source]; |
| 3646 | 3637 | if (target == NO_MOVE) |
| 3647 | 3638 | continue; |
| … |
… |
|
| 3653 | 3644 | } |
| 3654 | 3645 | TRACE("%1m is now valued 0.\n", source); |
| 3655 | 3646 | move[source].final_value = 0.0; |
| 3656 | | } |
| | 3647 | ) |
| 3657 | 3648 | } |
| 3658 | 3649 | |
| 3659 | 3650 | /* This selects the best move available according to their valuations. |
| … |
… |
|
| 3678 | 3669 | best_move = NO_MOVE; |
| 3679 | 3670 | |
| 3680 | 3671 | /* Search through all board positions for the highest valued move. */ |
| 3681 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 3672 | scan_board(pos, |
| 3682 | 3673 | float this_value = move[pos].final_value; |
| 3683 | 3674 | if (allowed_moves && !allowed_moves[pos]) |
| 3684 | 3675 | continue; |
| 3685 | | if (!ON_BOARD(pos) || move[pos].final_value == 0.0) |
| | 3676 | if (move[pos].final_value == 0.0) |
| 3686 | 3677 | continue; |
| 3687 | 3678 | |
| 3688 | 3679 | if (this_value > best_value) { |
| … |
… |
|
| 3697 | 3688 | move[pos].final_value = 0.0; |
| 3698 | 3689 | } |
| 3699 | 3690 | } |
| 3700 | | } |
| | 3691 | ) |
| 3701 | 3692 | |
| 3702 | 3693 | /* If the best move is an illegal ko capture, reevaluate ko |
| 3703 | 3694 | * threats and search again. |
| … |
… |
|
| 3945 | 3936 | double common_lower_limit = 0.0; |
| 3946 | 3937 | |
| 3947 | 3938 | /* Find all moves with positive values. */ |
| 3948 | | for (pos = BOARDMIN; pos < BOARDMAX; pos++) { |
| | 3939 | scan_board(pos, |
| 3949 | 3940 | probabilities[pos] = 0.0; |
| 3950 | 3941 | |
| 3951 | | if (ON_BOARD(pos)) { |
| 3952 | 3942 | /* FIXME: what about point redistribution? */ |
| 3953 | 3943 | if (move[pos].final_value > 0.0) { |
| 3954 | 3944 | double scale = 0.01 * (double) move[pos].randomness_scaling; |
| … |
… |
|
| 3964 | 3954 | |
| 3965 | 3955 | num_moves++; |
| 3966 | 3956 | } |
| 3967 | | } |
| 3968 | | } |
| | 3957 | ) |
| 3969 | 3958 | |
| 3970 | 3959 | /* Compute probability of each move. */ |
| 3971 | 3960 | for (k = 0; k < num_moves; k++) { |