Index: engine/gnugo.h =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/gnugo.h,v retrieving revision 1.83 diff -u -r1.83 gnugo.h --- engine/gnugo.h 21 Dec 2002 18:25:51 -0000 1.83 +++ engine/gnugo.h 22 Dec 2002 22:25:14 -0000 @@ -476,6 +476,11 @@ void prepare_pattern_profiling(void); void report_pattern_profiling(void); +/* owl tuning helpers */ +void load_owl_pattern_values(char *filename); +void owl_tune_pattern(const char *patname, int result); +void dump_owl_values(char *filename); + /* sgffile.c */ void sgffile_add_debuginfo(SGFNode *node, int value); void sgffile_output(SGFTree *tree); Index: engine/matchpat.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/matchpat.c,v retrieving revision 1.44 diff -u -r1.44 matchpat.c --- engine/matchpat.c 9 Dec 2002 23:04:16 -0000 1.44 +++ engine/matchpat.c 22 Dec 2002 22:25:19 -0000 @@ -136,6 +136,142 @@ +void +load_owl_pattern_values(char *filename) +{ +#if OWL_TUNING_HELPER + struct pattern *pats; + FILE *f = fopen(filename, "r"); + + pats = owl_attackpat_db.patterns; + while(pats->patn) { + pats->hit_good = 0; + pats->hit_bad = 0; + pats++; + } + pats = owl_defendpat_db.patterns; + while(pats->patn) { + pats->hit_good = 0; + pats->hit_bad = 0; + pats++; + } + pats = owl_vital_apat_db.patterns; + while(pats->patn) { + pats->hit_good = 0; + pats->hit_bad = 0; + pats++; + } + + if (f == NULL) + return; + + do { + char line[200]; + if (fgets(line, sizeof(line), f)) { + char db; + int patno; + float value; + char patname[20]; + int good, bad; + + if (sscanf(line, "%s\t%f\t%u\t%u", patname, &value, &good, &bad)!=4) + continue; + if (patname[0] == 'A') + pats = owl_attackpat_db.patterns; + else if (patname[0] == 'D') + pats = owl_defendpat_db.patterns; + else if (patname[0] == 'V' && patname[1] == 'A') + pats = owl_vital_apat_db.patterns; + else + continue; + while(pats->patn) { + if (strcmp(patname, pats->name) == 0) { + pats->value = value; + pats->hit_good = good; + pats->hit_bad = bad; + break; + } + pats++; + } + } + } while(!feof(f)); + + fclose(f); +#endif +} + +void +dump_owl_values(char *filename) +{ +#if OWL_TUNING_HELPER + struct pattern *pats; + FILE *f = fopen(filename, "w"); + if (f == NULL) + return; + + pats = owl_vital_apat_db.patterns; + while(pats->patn) { + fprintf(f, "%s\t%f\t%u\t%u\r\n", pats->name, pats->value, + pats->hit_good, pats->hit_bad); + pats++; + } + pats = owl_attackpat_db.patterns; + while(pats->patn) { + fprintf(f, "%s\t%f\t%u\t%u\r\n", pats->name, pats->value, + pats->hit_good, pats->hit_bad); + pats++; + } + pats = owl_defendpat_db.patterns; + while(pats->patn) { + fprintf(f, "%s\t%f\t%u\t%u\r\n", pats->name, pats->value, + pats->hit_good, pats->hit_bad); + pats++; + } + + fclose(f); +#endif +} + +unsigned int global_owl_hits = 0; + +void +owl_tune_pattern(const char *patname, int result) +{ +#if OWL_TUNING_HELPER + struct pattern *pats; + int total; + float value; + + if (patname[0] == 'A') + pats = owl_attackpat_db.patterns; + else if (patname[0] == 'D') + pats = owl_defendpat_db.patterns; + else if (patname[0] == 'V' && patname[1] == 'A') + pats = owl_vital_apat_db.patterns; + else + return; + + while(pats->patn) { + if (strcmp(patname, pats->name) == 0) + break; + pats++; + } + if (!pats->patn) + return; + + if (result) + pats->hit_good++; + else + pats->hit_bad++; + + global_owl_hits++; + if (global_owl_hits % 5000 == 0) + dump_owl_values("owl-tuning"); +#endif +} + + + /**************************************************************************/ /* Standard matcher: */ /**************************************************************************/ Index: engine/owl.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v retrieving revision 1.130 diff -u -r1.130 owl.c --- engine/owl.c 21 Dec 2002 18:25:52 -0000 1.130 +++ engine/owl.c 22 Dec 2002 22:25:25 -0000 @@ -1555,7 +1555,18 @@ else dcode = do_owl_defend(origin, NULL, &wid, owl, new_komaster, new_kom_pos, escape); - +#if OWL_TUNING_HELPER + if (pass == 1) { + int i; + for (i = 0; i < shape_patterns.counter; i++) + if (shape_patterns.pattern_list[i].move == mpos) + owl_tune_pattern(shape_patterns.pattern_list[i].pattern->name, + dcode != WIN? 1 : 0); + } + else if (pass == 0 || pass == 2) { + owl_tune_pattern(moves[k].name, dcode != WIN? 1 : 0); + } +#endif if (!ko_move) { if (dcode == 0) { pop_owl(&owl); @@ -2119,6 +2130,15 @@ if (!ko_move) { int acode = do_owl_attack(str, NULL, &wid, owl, new_komaster, new_kom_pos, new_escape); +#if OWL_TUNING_HELPER + if (pass == 1) { + int i; + for (i = 0; i < shape_patterns.counter; i++) + if (shape_patterns.pattern_list[i].move == mpos) + owl_tune_pattern(shape_patterns.pattern_list[i].pattern->name, + acode != WIN? 1 : 0); + } +#endif if (!acode) { pop_owl(&owl); popgo(); @@ -2136,8 +2156,18 @@ UPDATE_SAVED_KO_RESULT(savecode, savemove, acode, mpos); } else { - if (do_owl_attack(str, NULL, NULL, owl, - new_komaster, new_kom_pos, new_escape) != WIN) { + int acode = do_owl_attack(str, NULL, NULL, owl, + new_komaster, new_kom_pos, new_escape); +#if OWL_TUNING_HELPER + if (pass == 1) { + int i; + for (i = 0; i < shape_patterns.counter; i++) + if (shape_patterns.pattern_list[i].move == mpos) + owl_tune_pattern(shape_patterns.pattern_list[i].pattern->name, + acode != WIN? 1 : 0); + } +#endif + if (acode != WIN) { savemove = mpos; savecode = KO_B; } @@ -2688,9 +2718,6 @@ value -= 10; if (value < 21 && countstones(owl->lunch[lunch]) == 1) { - /* FIXME: consistent with previous implementation, but - * is this necessary ? if I'm not mistaken, here - * e is 0000, so remove this shouldn't hurt ... */ num_lunch++; eyevalue_list[num_eyes++] = e; continue; @@ -3057,6 +3084,12 @@ matched_patterns->list_size * sizeof(matched_patterns->pattern_list[0])); } +#if OWL_TUNING_HELPER + if (!check_pattern_hard( + AFFINE_TRANSFORM(pattern->move_offset, ll, anchor), + color, pattern, ll)) + return; +#endif next_pattern = &matched_patterns->pattern_list[matched_patterns->counter]; next_pattern->move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor); next_pattern->pattern = pattern; Index: interface/main.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/interface/main.c,v retrieving revision 1.59 diff -u -r1.59 main.c --- interface/main.c 16 Nov 2002 00:30:25 -0000 1.59 +++ interface/main.c 22 Dec 2002 22:25:30 -0000 @@ -894,6 +894,7 @@ /* Initialize the GNU Go engine. */ init_gnugo(memory); + load_owl_pattern_values("owl-tuning"); /* Read the infile if there is one. Also play up the position. */ if (infilename) { @@ -1263,6 +1264,8 @@ break; } + dump_owl_values("owl-tuning"); + if (profile_patterns) report_pattern_profiling(); Index: patterns/patterns.h =================================================================== RCS file: /cvsroot/gnugo/gnugo/patterns/patterns.h,v retrieving revision 1.45 diff -u -r1.45 patterns.h --- patterns/patterns.h 20 Dec 2002 02:06:59 -0000 1.45 +++ patterns/patterns.h 22 Dec 2002 22:25:42 -0000 @@ -63,6 +63,8 @@ */ #define PROFILE_PATTERNS 0 +#define OWL_TUNING_HELPER 1 + /* this trick forces a compile error if ints are not at least 32-bit */ struct _unused_patterns_h { int unused[sizeof(unsigned int) >= 4 ? 1 : -1]; @@ -239,6 +241,12 @@ int dfa_hits; int reading_nodes; #endif + +#if OWL_TUNING_HELPER + unsigned int hit_good; + unsigned int hit_bad; +#endif + };