diff -ur gnugo/engine/cache.c gnugo-owlcache/engine/cache.c --- gnugo/engine/cache.c Thu Nov 13 23:48:40 2003 +++ gnugo-owlcache/engine/cache.c Thu Jan 15 20:32:43 2004 @@ -176,7 +176,7 @@ tt_get(Transposition_table *table, int komaster, int kom_pos, enum routine_id routine, int target, int remaining_depth, - int *result, int *move) + int *result1, int *result2, int *move) { Hash_data hashval; Hashentry_ng *entry; @@ -208,8 +208,10 @@ if (move) *move = hn_get_move(*node); if ((unsigned) remaining_depth <= hn_get_remaining_depth(*node)) { - if (result) - *result = hn_get_result1(*node); + if (result1) + *result1 = hn_get_result1(*node); + if (result2) + *result2 = hn_get_result2(*node); return 2; } @@ -223,7 +225,7 @@ void tt_update(Transposition_table *table, int komaster, int kom_pos, enum routine_id routine, int target, - int remaining_depth, int result, int move) + int remaining_depth, int result1, int result2, int move) { Hash_data hashval; Hashentry_ng *entry; @@ -233,7 +235,7 @@ /* Get the combined hash value. */ calculate_hashval_for_tt(komaster, kom_pos, routine, target, &hashval); - data = hn_create_data(remaining_depth, result, 0, move, 0); + data = hn_create_data(remaining_depth, result1, result2, move, 0); /* Get the entry and nodes. */ entry = &table->entries[hashdata_remainder(hashval, table->num_entries)]; diff -ur gnugo/engine/cache.h gnugo-owlcache/engine/cache.h --- gnugo/engine/cache.h Thu Nov 13 23:48:40 2003 +++ gnugo-owlcache/engine/cache.h Thu Jan 15 20:32:03 2004 @@ -101,11 +101,11 @@ int tt_get(Transposition_table *table, int komaster, int kom_pos, enum routine_id routine, int target, int remaining_depth, - int *result, int *move); + int *result1, int *result2, int *move); void tt_update(Transposition_table *table, int komaster, int kom_pos, enum routine_id routine, int target, int remaining_depth, - int result, int move); + int result1, int result2, int move); /* ================================================================ */ @@ -356,17 +356,24 @@ #define READ_RETURN0_NG(komaster, kom_pos, routine, str, remaining_depth) \ do { \ - tt_update(&ttable, komaster, kom_pos, routine, str, remaining_depth, 0, 0);\ + tt_update(&ttable, komaster, kom_pos, routine, str, remaining_depth, 0, 0, 0);\ return 0; \ } while (0) #define READ_RETURN_NG(komaster, kom_pos, routine, str, remaining_depth, point, move, value) \ do { \ - tt_update(&ttable, komaster, kom_pos, routine, str, remaining_depth, value, move);\ + tt_update(&ttable, komaster, kom_pos, routine, str, remaining_depth, value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ return (value); \ } while (0) +#define READ_RETURN2_NG(komaster, kom_pos, routine, str, remaining_depth, point, move, value1, value2) \ + do { \ + tt_update(&ttable, komaster, kom_pos, routine, str, remaining_depth, value1, value2, move);\ + if ((value1) != 0 && (point) != 0) *(point) = (move); \ + return (value1); \ + } while (0) + #define READ_RETURN0(read_result) \ do { \ if (read_result) { \ diff -ur gnugo/engine/gnugo.h gnugo-owlcache/engine/gnugo.h --- gnugo/engine/gnugo.h Mon Sep 8 01:02:45 2003 +++ gnugo-owlcache/engine/gnugo.h Thu Jan 15 21:12:18 2004 @@ -194,6 +194,9 @@ * Regarding HASH_DEFAULT: * Hashing all functions saves time, but wastes table space, which is * bad when the reading is complicated. HASH_DEFAULT is a compromise. + * + * FIXME: This is no longer true with the newer transposition table + * and its fancy replacement scheme. We can now hash everything. */ #define HASH_FIND_DEFENSE 0x0001 /* NOTE : can specify -d0x... */ diff -ur gnugo/engine/owl.c gnugo-owlcache/engine/owl.c --- gnugo/engine/owl.c Thu Jan 15 19:52:25 2004 +++ gnugo-owlcache/engine/owl.c Thu Jan 15 21:08:02 2004 @@ -1601,15 +1601,55 @@ struct eyevalue probable_eyes; /* Best guess of eyevalue. */ const char *live_reason; int move_cutoff; +#if USE_HASHTABLE_NG + int xpos; + int result1; + int result2; +#else Read_result *read_result = NULL; + int found_read_result; +#endif int this_variation_number = count_variations - 1; SETUP_TRACE_INFO("owl_attack", str); shape_patterns.initialized = 0; +#if USE_HASHTABLE_NG + if ((stackp <= owl_branch_depth) && (hashflags & HASH_OWL_ATTACK) + && tt_get(&ttable, komaster, kom_pos, OWL_ATTACK, str, + depth - stackp, + &result1, &result2, &xpos) == 2) { + if (result1 != 0) { + if (move) + *move = xpos; + } + + if (result1 == GAIN) { + if (wormid) { + if (goal_worms_computed) + *wormid = result2; + else + *wormid = MAX_GOAL_WORMS; + } + } + + if (result1 == WIN) + TRACE("%oVariation %d: DEAD (cached)\n", this_variation_number); + else + TRACE("%oVariation %d: ALIVE (cached)\n", this_variation_number); + + SGFTRACE(xpos, result1, "cached"); + + return result1; + } + +#else + if ((stackp <= owl_branch_depth) && (hashflags & HASH_OWL_ATTACK)) { - if (get_read_result(OWL_ATTACK, komaster, kom_pos, &str, &read_result)) { + found_read_result = get_read_result(OWL_ATTACK, komaster, kom_pos, + &str, &read_result); + if (found_read_result) { TRACE_CACHED_RESULT(*read_result); if (rr_get_result(*read_result) != 0) { if (move) @@ -1634,12 +1674,18 @@ return rr_get_result(*read_result); } } +#endif /* USE_HASHTABLE_NG */ /* If reading goes to deep or we run out of nodes, we assume life. */ if (reading_limit_reached(&live_reason, this_variation_number)) { SGFTRACE(0, 0, live_reason); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, 0, 0); +#else READ_RETURN(read_result, move, 0, 0); +#endif } memset(mw, 0, sizeof(mw)); @@ -1681,11 +1727,22 @@ SGFTRACE(0, acode, live_reason); TRACE("%oVariation %d: ALIVE (%s)\n", this_variation_number, live_reason); if (acode == 0) +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, 0, 0); +#else + /* FIXME: Why not READ_RETURN0? */ READ_RETURN(read_result, move, 0, 0); +#endif else { if (wormid) *wormid = saveworm; +#if USE_HASHTABLE_NG + READ_RETURN2_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, mpos, acode, saveworm); +#else READ_RETURN2(read_result, move, mpos, acode, saveworm); +#endif } } @@ -1775,7 +1832,12 @@ this_variation_number); SGFTRACE(0, WIN, "no defense"); close_pattern_list(other, &shape_patterns); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, 0, WIN); +#else READ_RETURN(read_result, move, 0, WIN); +#endif } else if (dpos != NO_MOVE) { /* The dragon could be defended by one more move. Try to @@ -1821,7 +1883,11 @@ TRACE("%oVariation %d: ALIVE (escaped)\n", this_variation_number); SGFTRACE(0, 0, "escaped"); close_pattern_list(other, &shape_patterns); +#if USE_HASHTABLE_NG + READ_RETURN0_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp); +#else READ_RETURN0(read_result); +#endif } #endif @@ -1931,7 +1997,12 @@ SGFTRACE(mpos, WIN, winstr); } close_pattern_list(other, &shape_patterns); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, mpos, WIN); +#else READ_RETURN(read_result, move, mpos, WIN); +#endif } else if (experimental_owl_ext && dcode == LOSS) { if (saveworm == MAX_GOAL_WORMS @@ -2010,11 +2081,21 @@ SGFTRACE(savemove, savecode, "attack effective (gain) - E"); if (wormid) *wormid = saveworm; +#if USE_HASHTABLE_NG + READ_RETURN2_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, savemove, savecode, saveworm); +#else READ_RETURN2(read_result, move, savemove, savecode, saveworm); +#endif } else { SGFTRACE(savemove, savecode, "attack effective (ko) - E"); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp, + move, savemove, savecode); +#else READ_RETURN(read_result, move, savemove, savecode); +#endif } } @@ -2024,7 +2105,11 @@ count_variations - this_variation_number); SGFTRACE(0, 0, winstr); } +#if USE_HASHTABLE_NG + READ_RETURN0_NG(komaster, kom_pos, OWL_ATTACK, str, depth - stackp); +#else READ_RETURN0(read_result); +#endif } @@ -2241,15 +2326,55 @@ int escape_route; const char *live_reason; int move_cutoff; +#if USE_HASHTABLE_NG + int xpos; + int result1; + int result2; +#else Read_result *read_result = NULL; + int found_read_result; +#endif int this_variation_number = count_variations - 1; SETUP_TRACE_INFO("owl_defend", str); shape_patterns.initialized = 0; +#if USE_HASHTABLE_NG + + if ((stackp <= owl_branch_depth) && (hashflags & HASH_OWL_DEFEND) + && tt_get(&ttable, komaster, kom_pos, OWL_DEFEND, str, + depth - stackp, + &result1, &result2, &xpos) == 2) { + if (result1 != 0) { + if (move) + *move = xpos; + } + if (result1 == LOSS) { + if (wormid) { + if (goal_worms_computed) + *wormid = result2; + else + *wormid = MAX_GOAL_WORMS; + } + } + + if (result1 == WIN || result1 == LOSS) + TRACE("%oVariation %d: ALIVE (cached)\n", this_variation_number); + else + TRACE("%oVariation %d: DEAD (cached)\n", this_variation_number); + + SGFTRACE(xpos, result1, "cached"); + + return result1; + } + +#else + if ((stackp <= owl_branch_depth) && (hashflags & HASH_OWL_DEFEND)) { - if (get_read_result(OWL_DEFEND, komaster, kom_pos, &str, &read_result)) { + found_read_result = get_read_result(OWL_DEFEND, komaster, kom_pos, + &str, &read_result); + if (found_read_result) { TRACE_CACHED_RESULT(*read_result); if (rr_get_result(*read_result) != 0) { if (move) @@ -2276,6 +2401,8 @@ } } +#endif /* USE_HASHTABLE_NG */ + /* In order to get a defense move even if we seem to already have * escaped and to reduce the impact of overestimated escape * possibilities, we don't declare escape victory on the first move. @@ -2291,13 +2418,23 @@ */ TRACE("%oVariation %d: ALIVE (escaped)\n", this_variation_number); SGFTRACE(0, WIN, "escaped"); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, 0, WIN); +#else READ_RETURN(read_result, move, 0, WIN); +#endif } /* If reading goes to deep or we run out of nodes, we assume life. */ if (reading_limit_reached(&live_reason, this_variation_number)) { SGFTRACE(0, WIN, live_reason); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, 0, WIN); +#else READ_RETURN(read_result, move, 0, WIN); +#endif } memset(mw, 0, sizeof(mw)); @@ -2307,14 +2444,19 @@ current_owl_data = owl; memset(owl->safe_move_cache, 0, sizeof(owl->safe_move_cache)); - /* First see whether we might already be alife. */ + /* First see whether we might already be alive. */ if (escape < MAX_ESCAPE) { if (owl_estimate_life(owl, NULL, vital_moves, &live_reason, komaster, 0, &probable_eyes, &eyemin, &eyemax)) { SGFTRACE(0, WIN, live_reason); TRACE("%oVariation %d: ALIVE (%s)\n", this_variation_number, live_reason); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, 0, WIN); +#else READ_RETURN(read_result, move, 0, WIN); +#endif } } else { @@ -2493,7 +2635,12 @@ SGFTRACE(mpos, WIN, winstr); } close_pattern_list(color, &shape_patterns); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, mpos, WIN); +#else READ_RETURN(read_result, move, mpos, WIN); +#endif } if (acode == GAIN) saveworm = wid; @@ -2520,17 +2667,32 @@ SGFTRACE(savemove, savecode, "defense effective (loss) - B"); if (wormid) *wormid = saveworm; +#if USE_HASHTABLE_NG + READ_RETURN2_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, savemove, savecode, saveworm); +#else READ_RETURN2(read_result, move, savemove, savecode, saveworm); +#endif } else { SGFTRACE(savemove, savecode, "defense effective (ko) - B"); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, savemove, savecode); +#else READ_RETURN(read_result, move, savemove, savecode); +#endif } } if (number_tried_moves == 0 && min_eyes(&probable_eyes) >= 2) { SGFTRACE(0, WIN, "genus probably >= 2"); +#if USE_HASHTABLE_NG + READ_RETURN_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp, + move, 0, WIN); +#else READ_RETURN(read_result, move, 0, WIN); +#endif } @@ -2542,7 +2704,11 @@ SGFTRACE(0, 0, winstr); } +#if USE_HASHTABLE_NG + READ_RETURN0_NG(komaster, kom_pos, OWL_DEFEND, str, depth - stackp); +#else READ_RETURN0(read_result); +#endif } diff -ur gnugo/engine/reading.c gnugo-owlcache/engine/reading.c --- gnugo/engine/reading.c Thu Jan 15 19:52:25 2004 +++ gnugo-owlcache/engine/reading.c Thu Jan 15 20:47:45 2004 @@ -1225,7 +1225,7 @@ if ((stackp <= depth) && (hashflags & HASH_FIND_DEFENSE) && tt_get(&ttable, komaster, kom_pos, FIND_DEFENSE, str, depth - stackp, - &retval, &xpos) == 2) { + &retval, &xpos, NULL) == 2) { /* Note that if return value is 1 (too small depth), the move will * still be used for move ordering. */ @@ -3018,7 +3018,7 @@ if ((stackp <= depth) && (hashflags & HASH_ATTACK) && tt_get(&ttable, komaster, kom_pos, ATTACK, str, depth - stackp, - &retval, &xpos) == 2) { + &retval, &xpos, NULL) == 2) { SGFTRACE(xpos, retval, "cached"); if (move) *move = xpos;