Ticket #148: cleanup2.patch

File cleanup2.patch, 63.4 KB (added by draqo, 5 years ago)

big cleanup

  • config.vcin

    diff -N -r -u -X .ignore gnugo-copy/config.vcin gnugo/config.vcin
    old new  
    3030/* GAIN/LOSS codes. Disabled by default. */ 
    3131#define EXPERIMENTAL_OWL_EXT 0 
    3232 
     33/* Disable unneeded things. 0 standard. */ 
     34#define FINAL_RELEASE 0 
     35 
    3336/* Define as 1 to use the grid optimisation, or 2 to run it in self-test mode 
    3437   */ 
    3538#define GRID_OPT 1 
  • doc/dfa.texi

    diff -N -r -u -X .ignore gnugo-copy/doc/dfa.texi gnugo/doc/dfa.texi
    old new  
    11In this chapter, we describe the principles of the GNU Go DFA 
    22pattern matcher.  The aim of this system is to permit a fast 
    3 pattern matching when it becomes time critical like in owl 
    4 module (@ref{The Owl Code}). Since GNU Go 3.2, this is enabled 
     3pattern matching. Since GNU Go 3.2, this is enabled 
    54by default. You can still get back the traditional pattern matcher 
    65by running @command{configure --disable-dfa} and then recompiling 
    76GNU Go.  
  • doc/dragon.texi

    diff -N -r -u -X .ignore gnugo-copy/doc/dragon.texi gnugo/doc/dragon.texi
    old new  
    1717Later routines called by @code{genmove()} will then have access to this 
    1818information. This document attempts to explain the philosophy and 
    1919algorithms of this preliminary analysis, which is carried out by the 
    20 two routines @code{make_worm()} and @code{make_dragon()} in  
    21 @file{dragon.c}. 
     20two routines @code{make_worms()} (in @file{worm.c}) and 
     21@code{make_dragons()} (in @file{dragon.c}). 
    2222 
    2323@cindex dragon 
    2424@cindex worm 
     
    8383  int unconditional_status; 
    8484  int attack_points[MAX_TACTICAL_POINTS]; 
    8585  int attack_codes[MAX_TACTICAL_POINTS]; 
     86  int discarded_attacks[MAX_TACTICAL_POINTS]; 
    8687  int defense_points[MAX_TACTICAL_POINTS]; 
    8788  int defend_codes[MAX_TACTICAL_POINTS]; 
     89  int discarded_defenses[MAX_TACTICAL_POINTS]; 
    8890  int attack_threat_points[MAX_TACTICAL_POINTS]; 
    89   int attack_threat_codes[MAX_TACTICAL_POINTS];  
     91  int attack_threat_codes[MAX_TACTICAL_POINTS]; 
     92  int discarded_att_threats[MAX_TACTICAL_POINTS]; 
    9093  int defense_threat_points[MAX_TACTICAL_POINTS]; 
    9194  int defense_threat_codes[MAX_TACTICAL_POINTS]; 
     95  int discarded_def_threats[MAX_TACTICAL_POINTS]; 
    9296@}; 
    9397@end example 
    9498 
     
    109113other worm. Intersections that are shared are counted with equal 
    110114fractional values for each worm. This measures the direct territorial 
    111115value of capturing a worm. @dfn{effective_size} is a floating point number. 
    112 Only intersections at a distance of 4 or less are counted. 
     116Only intersections at a distance (empty vertices between a worm and an 
     117intersection) of 5 or less are counted. 
    113118@end quotation 
    114119@item @code{origin} 
    115120@quotation 
     
    220225@end quotation 
    221226@item @code{cutstone2}  
    222227@quotation 
    223 Cutting points are identified by the patterns in the connections 
    224 database. Proper cuts are handled by the fact that attacking and 
     228Number of potential cuts involving the worm. Cutting points are 
     229identified by the patterns in the connections database. Proper 
     230cuts are handled by the fact that attacking and 
    225231defending moves also count as moves cutting or connecting the 
    226232surrounding dragons.  The @code{cutstone2} field is set during  
    227233@code{find_cuts()}, called from @code{make_domains()}. 
     
    248254opposite color can be killed. More precisely an 
    249255@dfn{inessential string} is a string S of genus zero, 
    250256not adjacent to any opponent string which can be easily 
    251 captured, and which has no edge liberties or second 
     257captured, which is not cutstone, and which has up to 
     2582 edge liberties and no second 
    252259order liberties, and which satisfies the following 
    253260further property: If the string is removed from the 
    254261board, then the remaining cavity only borders worms of the 
     
    266273even if the opponent is allowed an arbitrary number of consecutive 
    267274moves. 
    268275@end quotation 
    269 @item unconditional_status 
     276@item @code{unconditional_status} 
    270277@quotation 
    271278Unconditional status is also set by the function 
    272279@code{unconditional_life}. This is set @code{ALIVE} for stones which are 
     
    285292transformed into an invincible group by some number of consecutive 
    286293moves. Well, this is not entirely true because there is a rare class of 
    287294seki groups not satisfying this condition. Exactly which these are is 
    288 left as an exercise for the reader. Currently @code{unconditional_life}, 
    289 which strictly follows the definitions above, calls such seki groups 
    290 unconditionally dead, which of course is a misfeature. It is possible to 
    291 avoid this problem by making the algorithm slightly more complex, but 
    292 this is left for a later revision. 
     295shown in a comment in @file{unconditional.c}. 
    293296@end quotation 
    294 @item @code{int attack_points[MAX_TACTICAL_POINTS]} 
    295 @item @code{attack_codes[MAX_TACTICAL_POINTS]} 
     297@item @code{int attack_points[MAX_TACTICAL_POINTS];} 
     298@item @code{int attack_codes[MAX_TACTICAL_POINTS];} 
    296299@item @code{int defense_points[MAX_TACTICAL_POINTS];} 
    297300@item @code{int defend_codes[MAX_TACTICAL_POINTS];} 
    298301@quotation 
     
    310313@quotation 
    311314These are points that threaten to attack or defend a worm. 
    312315@end quotation 
     316@item @code{int discarded_attacks[MAX_TACTICAL_POINTS];} 
     317@item @code{int discarded_defenses[MAX_TACTICAL_POINTS];} 
     318@item @code{int discarded_att_threats[MAX_TACTICAL_POINTS];} 
     319@item @code{int discarded_def_threats[MAX_TACTICAL_POINTS];} 
     320@quotation 
     321These are checked points that haven't led to any positive result. 
     322Used to not check the same point more than once. 
     323@end quotation 
    313324@end itemize 
    314325 
    315326The function @code{makeworms()} will generate data for all worms. 
     
    343354XXX...        
    344355 
    345356@end example 
    346 @findex dragon_eye 
    347  
    348 The code for this type of amalgamation is in the routine 
    349 @code{dragon_eye()}, discussed further in EYES. 
    350357 
    351358Next, we amalgamate strings which seem uncuttable. We amalgamate dragons 
    352359which either share two or more common liberties, or share one liberty 
     
    367374@section Connection 
    368375@cindex connections 
    369376 
    370 The fields @code{black_eye.cut} and @code{white_eye.cut} are set where the 
     377The fields in @code{cutting_points} are set where the 
    371378opponent can cut, and this is done by the B (break) class patterns in 
    372 @file{conn.db}.  There are two important uses for this field, which can be 
     379@file{conn.db}.  There are two important uses for this table, which can be 
    373380accessed by the autohelper functions @code{xcut()} and @code{ocut()}. The 
    374381first use is to stop amalgamation in positions like 
    375382 
     
    534541  int safety; 
    535542  float weakness; 
    536543  float weakness_pre_owl; 
     544  float strategic_size; 
    537545  int escape_route; 
    538546  struct eyevalue genus; 
    539547  int heye; 
     
    541549  int surround_status; 
    542550  int surround_size; 
    543551  int semeais; 
    544   int semeai_margin_of_safety; 
     552  int semeai_defense_code; 
    545553  int semeai_defense_point; 
    546   int semeai_defense_certain;   
     554  int semeai_defense_certain; 
     555  int semeai_defense_target; 
     556  int semeai_attack_code; 
    547557  int semeai_attack_point; 
    548558  int semeai_attack_certain; 
     559  int semeai_attack_target; 
    549560  int owl_threat_status; 
    550561  int owl_status; 
    551562  int owl_attack_point; 
    552563  int owl_attack_code; 
    553564  int owl_attack_certain; 
     565  int owl_attack_node_count; 
    554566  int owl_second_attack_point; 
    555567  int owl_defense_point; 
    556568  int owl_defense_code; 
     
    607619@quotation 
    608620The dragon number, used as a key into the @code{dragon2} array. 
    609621@end quotation 
    610 @item origin 
     622@item @code{origin} 
    611623@cindex dragon origin 
    612624@quotation 
    613625The origin of the dragon is a unique particular vertex 
     
    616628copied to the dragon origins. Amalgamation of two dragons 
    617629amounts to changing the origin of one. 
    618630@end quotation 
    619 @item size 
     631@item @code{size} 
    620632@cindex dragon size 
    621633@quotation 
    622634The number of stones in the dragon. 
    623635@end quotation 
    624 @item effective size 
     636@item @code{effective size} 
    625637@cindex effective size 
    626638@quotation 
    627639The sum of the effective sizes of the constituent worms. 
     
    630642cardinality of the dragon plus the number of empty vertices which are 
    631643nearer this dragon than any other. 
    632644@end quotation 
    633 @item crude_status 
     645@item @code{crude_status} 
    634646@quotation 
    635647(ALIVE, DEAD, UNKNOWN, CRITICAL). An early measure of the life 
    636648potential of the dragon. It is computed before the owl code is 
    637649run and is superceded by the status as soon as that becomes 
    638650available. 
    639651@end quotation 
    640 @item status 
     652@item @code{status} 
    641653@cindex dragon status 
    642654@quotation 
    643655The dragon status is the best measure of the dragon's health. 
     
    649661Here are definitions of the fields in the @code{dragon2} array. 
    650662 
    651663@itemize @bullet 
    652 @item origin 
     664@item @code{origin} 
    653665@quotation 
    654666The origin field is duplicated here. 
    655667@end quotation 
    656 @item adjacent 
    657668@item @code{adjacent[MAX_NEIGHBOR_DRAGONS]} 
    658 @cindex neighbor dragons 
    659 @cindex adjacent dragons 
    660 @findex find_neighbor_dragons 
    661 @quotation 
    662 Dragons of either color near the given one are called @dfn{neighbors}. 
    663 They are computed by the function @code{find_neighbor_dragons()}. 
    664 The @code{dragon2.adjacent} array gives the dragon numbers of 
    665 these dragons. 
    666 @end quotation 
    667669@item @code{neighbors} 
    668670@cindex neighbor dragons 
    669671@cindex adjacent dragons 
     
    671673@quotation 
    672674Dragons of either color near the given one are called @dfn{neighbors}. 
    673675They are computed by the function @code{find_neighbor_dragons()}. 
    674 The @code{dragon2.adjacent} array gives the dragon numbers of 
    675 these dragons. 
     676The @code{adjacent} array gives the dragon numbers of 
     677these dragons and @code{neighbors} gives the number of them. 
    676678@end quotation 
    677 @item neighbors 
    678 @quotation 
    679 The number of neighbor dragons. 
    680 @end quotation 
    681 @item hostile_neighbors 
     679@item @code{hostile_neighbors} 
    682680@quotation 
    683681The number of neighbor dragons of the opposite color. 
    684682@end quotation 
    685 @item moyo_size 
    686 @item float moyo_territorial_value 
     683@item @code{moyo_size} 
     684@item @code{moyo_territorial_value} 
    687685@findex compute_surrounding_moyo_sizes 
    688686@quotation 
    689687The function @code{compute_surrounding_moyo_sizes()} assigns 
     
    691689each dragon (@pxref{Territory and Moyo}). This is the  
    692690moyo size. They are recorded in these fields. 
    693691@end quotation 
    694 @item safety 
     692@item @code{safety} 
    695693@cindex dragon safety 
    696694@quotation 
    697695The dragon safety can take on one of the values 
     
    707705@item INESSENTIAL - the dragon is unimportant (e.g. nakade stones) and dead 
    708706@end itemize 
    709707@end quotation 
    710 @item weakness 
    711 @item weakness_pre_owl 
     708@item @code{weakness} 
     709@item @code{weakness_pre_owl} 
    712710@cindex dragon weakness 
    713711@cindex weakness 
    714712@quotation 
     
    717715dragons in greater need of safety. The field @code{weakness_pre_owl} 
    718716is a preliminary computation before the owl code is run. 
    719717@end quotation 
    720 @item escape_route 
     718@item @code{strategic_size} 
     719@cindex strategic_size 
     720@quotation 
     721An effective size including weakness of neighbors. 
     722@end quotation 
     723@item @code{escape_route} 
    721724@cindex dragon escape_route 
    722725@cindex escape_route 
    723726@findex compute_escape 
     
    726729in case it cannot make two eyes locally. Documentation 
    727730may be found in @ref{Escape}. 
    728731@end quotation 
    729 @item struct eyevalue genus 
     732@item @code{genus} 
    730733@cindex dragon genus 
    731734@cindex genus 
    732735@quotation 
     
    744747 
    745748@end example 
    746749@end quotation 
    747 @item heye 
     750@item @code{heye} 
    748751@quotation 
    749752Location of a half eye attached to the dragon. 
    750753@end quotation 
    751 @item lunch 
     754@item @code{lunch} 
    752755@cindex dragon lunch 
    753756@cindex lunch 
    754757@quotation 
     
    756759can be captured. In contrast with worm lunches, a dragon 
    757760lunch must be able to defend itself. 
    758761@end quotation 
    759 @item surround_status 
    760 @item surround_size 
     762@item @code{surround_status} 
     763@item @code{surround_size} 
    761764@cindex surround_status 
    762765@cindex surround_size 
    763766@cindex surround 
     
    766769it is @dfn{surrounded}. See @ref{Surrounded Dragons} and 
    767770the comments in @file{surround.c} for more information about the 
    768771algorithm.  Used in computing the escape_route, and also callable 
    769 from patterns (currently used by CB258) 
     772from patterns 
    770773@end quotation 
    771 @item semeais 
    772 @item semeai_defense_point 
    773 @item semeai_defense_certain 
    774 @item semeai_attack_point 
    775 @item semeai_attack_certain 
    776 @cindex semeai 
     774@item @code{semeais} 
     775@item @code{semeai_defense_code} 
     776@item @code{semeai_defense_point} 
     777@item @code{semeai_defense_certain} 
     778@item @code{semeai_defense_target} 
     779@item @code{semeai_attack_code} 
     780@item @code{semeai_attack_point} 
     781@item @code{semeai_attack_certain} 
     782@item @code{semeai_attack_target} 
     783@cindex semeais 
     784@cindex semeai_defense_code 
    777785@cindex semeai_defense_point 
    778786@cindex semeai_defense_certain 
     787@cindex semeai_defense_target 
     788@cindex semeai_attack_code 
    779789@cindex semeai_attack_point 
    780790@cindex semeai_attack_certain 
     791@cindex semeai_attack_target 
    781792@quotation 
    782793If two dragons of opposite color both have the status CRITICAL 
    783794or DEAD they are in a @dfn{semeai} (capturing race), and their 
     
    785796@code{owl_analyze_semeai()} in @file{owl.c}, which attempts to 
    786797determine which is alive, which dead, or if the result is 
    787798seki, and whether it is important who moves first. The 
    788 function @file{new_semeai()} in @file{semeai.c} attempts 
     799function @code{semeai()} in @file{semeai.c} attempts 
    789800to revise the statuses and to generate move reasons based 
    790801on these results. The field @code{dragon2.semeais} is nonzero 
    791802if the dragon is an element of a semeai, and equals the 
    792803number of semeais (seldom more than one). The semeai defense 
    793804and attack points are locations the defender or attacker 
    794 must move to win the semeai. The field @code{semeai_margin_of_safety} 
    795 is intended to indicate whether the semeai is close or not 
    796 but currently this field is not maintained. The fields 
     805must move to win the semeai and the result code of these moves is 
     806also stored. In @code{semeai_defense_target} and 
     807@code{semeai_attack_target} an origin of an opponent dragon in 
     808semeai, on which the move has impact, is stored. The fields 
    797809@code{semeai_defense_certain} and @code{semeai_attack_certain} 
    798810indicate that the semeai code was able to finish analysis 
    799811without running out of nodes. 
    800812@end quotation 
    801 @item owl_status 
     813@item @code{owl_threat_status} 
     814@quotation 
     815Informs, whether the dragon has any defense or attack threats 
     816(@code{CAN_THREATEN_ATTACK} or @code{CAN_THREATEN_DEFENSE}). 
     817@end quotation 
     818@item @code{owl_status} 
    802819@quotation 
    803820This is a classification similar to @code{dragon.crude_status}, but 
    804821based on the life and death reading in @file{owl.c}. 
     
    810827@code{owl_defend()} is run, and if it can be defended it 
    811828is classified as @code{CRITICAL}, and if not, as @code{DEAD}. 
    812829@end quotation 
    813 @item owl_attack_point 
     830@item @code{owl_attack_point} 
    814831@cindex owl_attack_point 
    815832@quotation 
    816833If the dragon can be attacked this is the point to attack the dragon. 
    817834@end quotation 
    818 @item owl_attack_code 
     835@item @code{owl_attack_code} 
    819836@cindex owl_attack_code 
    820837@quotation 
    821 The owl attack code, It can be WIN, KO_A, KO_B or 0 (@pxref{Return Codes}). 
     838The owl attack code, It can be WIN, KO_A, GAIN, LOSS, 
     839KO_B or 0 (@pxref{Return Codes}). 
    822840@end quotation 
    823 @item owl_attack_certain 
     841@item @code{owl_attack_certain} 
    824842@cindex owl_attack_certain 
    825843@quotation 
    826844The owl reading is able to finish analyzing the attack 
    827845without running out of nodes. 
    828846@end quotation 
    829 @item owl_second_attack_point 
     847@item @code{owl_attack_node_count} 
     848@cindex owl_attack_node_count 
     849@quotation 
     850Number of nodes used during analyze of attack move. 
     851@end quotation 
     852@item @code{owl_second_attack_point} 
    830853@cindex owl_second_attack_point 
    831854@quotation 
    832855A second attack point. 
    833856@end quotation 
    834 @item owl_defense_point 
     857@item @code{owl_defense_point} 
    835858@cindex owl_defense_point 
    836859@quotation 
    837860If the dragon can be defended, this is the place to play. 
    838861@end quotation 
    839 @item owl_defense_code 
     862@item @code{owl_defense_code} 
    840863@cindex owl_defense_code 
    841864@quotation 
    842 The owl defense code, It can be WIN, KO_A, KO_B or 0 (@pxref{Return Codes}). 
     865The owl defense code, It can be WIN, KO_A, GAIN, LOSS, 
     866KO_B or 0 (@pxref{Return Codes}). 
    843867@end quotation 
    844 @item owl_defense_certain 
     868@item @code{owl_defense_certain} 
    845869@cindex owl_defense_certain 
    846870@quotation 
    847871The owl code is able to finish analyzing the defense without 
    848872running out of nodes. 
    849873@end quotation 
    850 @item owl_second_defense_point 
     874@item @code{owl_second_defense_point} 
    851875@cindex owl_second_defense_point 
    852876@quotation 
    853877A second owl defense point. 
    854878@end quotation 
     879@item @code{owl_attack_kworm} 
     880@cindex owl_attack_kworm 
     881@quotation 
     882Position of a worm, which can be killed during attack on the dragon 
     883(@code{owl_attack_code} has to be @code{GAIN}). 
     884@end quotation 
     885@item @code{owl_defense_kworm} 
     886@cindex owl_defense_kworm 
     887@quotation 
     888Position of our worm (part of the dragon) abandoned during defense of 
     889the dragon (@code{owl_defend_code} has to be @code{LOSS}). 
     890@end quotation 
    855891@end itemize 
    856892 
    857893@node Dragons in Color 
  • doc/move_generation.texi

    diff -N -r -u -X .ignore gnugo-copy/doc/move_generation.texi gnugo/doc/move_generation.texi
    old new  
    214214the simultaneous attack of one worm and the defense of another. As for 
    215215attack and defense moves, it's important that all moves which win a 
    216216semeai are found, so an informed choice can be made between them. 
     217Semeai move reasons are set by the semeai module. 
     218 
     219One might also wish to list moves which increase the lead in a semeai 
     220race (removes ko threats) for use as secondary move reasons. Analogously, 
     221if we are behind in the race. However this has not been implemented yet. 
    217222 
    218 Semeai move reasons should be set by the semeai module. However this 
    219 has not been implemented yet. One might also wish to list moves 
    220 which increase the lead in a semeai race (removes ko threats) for use 
    221 as secondary move reasons. Analogously if we are behind in the race. 
    222223 
    223224@node  Making eyes 
    224225@subsection Making or destroying eyes 
     
    229230will be valued substantially higher if this is the case. As usual it's 
    230231important to find all moves that change the eye count. 
    231232 
    232 (This is part of what eye_finder was doing. Currently it only finds 
    233 one vital point for each unstable eye space.) 
     233The eye module (@file{optics.c}) is handling this. It uses eyes patterns 
     234database @file{patterns/eyes.db}. 
    234235 
    235236@node  Antisuji moves 
    236237@subsection Antisuji moves 
     
    247248territory move reason. That move reason is added by the @samp{e} 
    248249patterns in @file{patterns/patterns.db}. Similarly the @samp{E} patterns 
    249250attempt to generate or mitigate a moyo, which is a region of influence 
    250 not yet secure territory, yet valuable. Such a pattern sets the ``expand 
    251 moyo'' move reason. 
     251not yet secure territory, yet valuable. There are also other patterns for 
     252reducing territory, invasions and making bariers (to defend before 
     253invasions) - they are in @file{patterns/influence.db} and 
     254@file{patterns/barriers.db}. These patterns set the ``expand moyo'', 
     255``expand territory'' and ``invasion'' move reasons. They also have 
     256influence on a move territorial valuation. 
    252257 
    253258@node Owl attack and defense 
    254259@subsection Attacking and Defending Dragons 
     
    310315as explained for example in @emph{The Endgame} by Ogawa 
    311316and Davies. 
    312317 
    313 Moves are valued with respect to four different criteria. These are 
     318Moves are valued with respect to four different main criteria. These 
     319are 
    314320 
    315321@itemize @bullet 
    316322@item territorial value 
     
    362368* Minimum Value::                 Minimum value 
    363369* Secondary Value::               Other, more indirect, gains from a move 
    364370* Threats and Followup Value::    Valuation of attack and defense threats 
     371* Additional ko value::    Additional threat value for a ko fight 
    365372@end menu 
    366373 
    367374@node Territorial value 
     
    384391 
    385392@node Strategical value 
    386393@subsection Strategical Value 
     394@findex estimate_strategical_value 
    387395 
    388396Strategical defense or attack reasons are assigned to any move 
    389397which matches a pattern of type @samp{a} or @samp{d}. These are 
     
    394402to check its status or safety. This is done later, during 
    395403the valuation phase. 
    396404 
     405The whole algorithm is placed in @code{estimate_strategical_value}. 
     406 
    397407@node Shape factor 
    398408@subsection Shape Factor 
    399409 
     
    451461which we cannot legally take, then such a move becomes attractive as a ko 
    452462threat and the full followup value is taken into account. 
    453463 
     464@node Additional ko value 
     465@subsection Additional ko value 
     466 
     467Some moves give us additional threats and some give them to an opponent. 
     468In such situations we should give some bonus or penalty for creating ko 
     469threats. As for now only positive contribution is counted. 
     470 
    454471@node End Game 
    455472@section End Game 
    456473 
  • doc/patterns.texi

    diff -N -r -u -X .ignore gnugo-copy/doc/patterns.texi gnugo/doc/patterns.texi
    old new  
    8585Elements are not generated for @samp{?} markers, but they are not 
    8686completely ignored - see below. 
    8787         
    88 The line beginning @samp{:} describes various attributes of the pattern, such 
    89 as its symmetry and its class. Optionally, a function called a 
    90 ``helper'' can be provided to assist the matcher in deciding whether 
    91 to accept move. Most patterns do not require a helper, and this field 
    92 is filled with NULL. 
    93  
    9488@findex shapes_callback 
    9589The matcher in @file{matchpat.c} searches the board for places where this 
    9690layout appears on the board, and the callback function 
     
    10094After the pattern, there is some supplementary information in the format: 
    10195@example 
    10296 
    103   :trfno, classification, [values], helper_function 
     97  :trfno, attributes, [values], helper_function 
    10498 
    10599@end example 
    106100 
     
    110104represents the axis of symmetry. (E.g. @samp{|} means symmetrical about a 
    111105vertical axis.) 
    112106 
     107@code{helper_function} is a function that can be provided to assist the matcher 
     108in deciding whether to accept move. Most patterns do not require a helper, 
     109and this field is filled with NULL. 
     110 
    113111The above pattern could equally well be written on the left edge: 
    114112 
    115113@example 
     
    127125way, or for that matter, on the top or right edges, or in any 
    128126of the four corners. As a matter of convention all the edge patterns  
    129127in @file{patterns.db} are written on the bottom edge or in the lower left 
    130 corners. In the @file{patterns/} directory there is a program called 
    131 @code{transpat} which can rotate or otherwise transpose patterns. 
    132 This program is not built by default---if you think you need it, 
    133 @code{make transpat} in the @file{patterns/} directory and 
    134 consult the usage remarks at the beginning of @file{patterns/transpat.c}. 
     128corners. 
    135129 
    136130@node  Pattern Classification 
    137131@section Pattern Attributes 
     
    415409need to remove the stones we placed from the reading stack. This is done 
    416410with the function @code{popgo()}. 
    417411 
     412IMPORTANT: The macro @code{OFFSET} is not used anymore, because it has 
     413fixed coordinates and patterns can be now rotated randomly by DFA 
     414optimizer. All helpers that require usage of this macro have to be moved 
     415to autohelpers. 
     416 
    418417@node  Autohelpers and Constraints 
    419418@section Autohelpers and Constraints 
    420419 
     
    566565The autohelper functions are translated into C code by the program in 
    567566@file{mkpat.c}. To see exactly how the functions are implemented, 
    568567consult the autohelper function definitions in that file. Autohelper 
    569 functions can be used in both constraint and action lines. 
     568functions can be used in both constraint and action lines. Here is 
     569a partial list of them: 
    570570 
    571571@example 
    572572 
     
    10631063 
    10641064The patterns in @file{conn.db} are used for helping @code{make_dragons()} 
    10651065amalgamate worms into dragons and to some extent for modifying eye spaces. 
    1066 The patterns in this database use the classifications @samp{B},  
    1067 @samp{C}, and @samp{e}. @samp{B} patterns are used for finding cutting points, 
     1066The patterns in this database use the classifications @samp{B} and  
     1067@samp{C}. @samp{B} patterns are used for finding cutting points, 
    10681068where amalgamation should not be performed, @samp{C} patterns are used for 
    1069 finding existing connections, over which amalgamation is to be done, and  
    1070 @samp{e} patterns are used for modifying eye spaces and reevaluating lunches. 
     1069finding existing connections, over which amalgamation is to be done. 
    10711070There are also some patterns without classification, which use action lines to 
    10721071have an impact. These are matched together with the @samp{C} patterns. Further 
    10731072details and examples can be found in @xref{Worms and Dragons}. 
     
    11811180@findex find_connections 
    11821181@quotation  
    11831182Find explicit connection patterns and amalgamate the involved dragons. 
    1184 This goes through the connection database consulting patterns except those of 
    1185 type B, E or e. When such a function is found, the function 
     1183This goes through the connection database consulting only patterns of type C. 
     1184When such a function is found, the function 
    11861185@code{cut_connect_callback} is invoked. 
    11871186@end quotation 
    1188 @item void modify_eye_spaces1(void) 
    1189 @findex modify_eye_spaces1 
    1190 @quotation  
    1191 Find explicit connection patterns and amalgamate the involved dragons. 
    1192 This goes through the connection database consulting only patterns 
    1193 of type E (@pxref{Connections Database}). When such a function is found, the 
    1194 function @code{cut_connect_callback} is invoked.   
    1195 @end quotation 
    1196 @item void modify_eye_spaces1(void) 
    1197 @findex modify_eye_spaces1 
    1198 @quotation  
    1199 Find explicit connection patterns and amalgamate the involved dragons. 
    1200 This goes through the connection database consulting only patterns 
    1201 of type e (@pxref{Connections Database}). When such a function is found, the 
    1202 function @code{cut_connect_callback} is invoked.   
    1203 @end quotation 
    12041187@end itemize 
    12051188 
    12061189@node  Tuning 
  • doc/reading.texi

    diff -N -r -u -X .ignore gnugo-copy/doc/reading.texi gnugo/doc/reading.texi
    old new  
    6666 
    6767The function @code{do_attack} and @code{do_find_defense} are wrappers 
    6868themselves and call @code{attack1}, @code{attack2}, @code{attack3} or 
    69 @code{attack4} resp.  @code{defend1}, @code{defend1}, @code{defend1} 
    70 or @code{defend1} depending on the number of liberties. 
     69@code{attack4} resp.  @code{defend1}, @code{defend2}, @code{defend3} 
     70or @code{defend4} depending on the number of liberties. 
    7171 
    7272These are fine-tuned to generate and try out the moves in an efficient 
    7373order. They generate a few moves themselves (mostly direct liberties 
     
    1231233 liberties are considered, but branching is inhibited, so fewer 
    124124variations are considered. 
    125125 
    126 %@findex small_semeai 
    127 %Currently the reading code does not try to defend a string by 
    128 %attacking a boundary string with more than two liberties. Because 
    129 %of this restriction, it can make oversights. A symptom of this is 
    130 %two adjacent strings, each having three or four liberties, each 
    131 %classified as @code{DEAD}. To resolve such situations, a function 
    132 %@code{small_semeai()} (in @file{engine/semeai.c}) looks for such 
    133 %pairs of strings and corrects their classification. 
    134  
    135126The @code{backfill_depth} is a similar variable with a default 12. Below 
    136127this depth, GNU Go will try "backfilling" to capture stones. 
    137128For example in this situation: 
     
    173164be attacked, and if so, @code{*move} returns the attacking move, 
    174165unless @code{*movei} is a null pointer. (Use null pointers if 
    175166you are interested in the result of the attack but not the 
    176 attacking move itself.) Returns @code{WIN}, if the attack succeeds, 
    177 0 if it fails, and @code{KO_A} or @code{KO_B} if the result depends on ko 
    178 @ref{Return Codes}. 
     167attacking move itself.) Returns a result code of the move 
     168@xref{Return Codes}. 
    179169@end quotation 
    180170@findex find_defense 
    181171@item @code{find_defense(int str, int *move)} 
    182172@quotation  
    183 Attempts to find a move that will save the string at @code{str}. It 
    184 returns true if such a move is found, with @code{*move} the location 
     173Attempts to find a move that will save the string at @code{str}, and if 
     174so, @code{*move} returns the location 
    185175of the saving move (unless @code{*move} is a null pointer). It is not 
    186176checked that tenuki defends, so this may give an erroneous answer if 
    187 @code{!attack(str)}.  Returns @code{KO_A} or @code{KO_B} if the 
    188 result depends on ko @xref{Return Codes}.  
     177@code{!attack(str)}.  Returns a result code of the move 
     178@xref{Return Codes}.  
    189179@end quotation 
    190180@findex safe_move 
    191181@item @code{safe_move(int str, int color)} : 
    192182@quotation 
    193183The function @code{safe_move(str, color)} checks whether a move at 
    194184@code{str} is illegal or can immediately be captured. If @code{stackp==0} 
    195 the result is cached. If the move only can be captured by a ko, it's 
    196 considered safe. This may or may not be a good convention. 
     185the result is cached. Returns a result code of an attack on the placed 
     186stone. 
    197187@end quotation 
    198188@end itemize 
    199189 
     
    388378Some calculations can be safely saved from move to move. If the 
    389379opponent's move is not close to our worm or dragon, we do not have to 
    390380reconsider the life or death of that group on the next move. So 
    391 the result is saved in a persistent cache. Persistent caches are used for 
     381the result is saved in a persistent cache. Persistent caches 
    392382are used in the engine for several types of read results. 
    393383 
    394384@itemize @bullet 
  • engine/board.c

    diff -N -r -u -X .ignore gnugo-copy/engine/board.c gnugo/engine/board.c
    old new  
    222222 */ 
    223223 
    224224#define LIBERTY(pos) \ 
    225   (board[pos] == EMPTY) 
     225  (!board[pos]) 
    226226 
    227227#define UNMARKED_LIBERTY(pos) \ 
    228   (board[pos] == EMPTY && ml[pos] != liberty_mark) 
     228  (!board[pos] && ml[pos] != liberty_mark) 
    229229 
    230230#define MARK_LIBERTY(pos) \ 
    231231  ml[pos] = liberty_mark 
     
    683683  /* 1. The color must be BLACK or WHITE. */ 
    684684  gg_assert(color == BLACK || color == WHITE); 
    685685  
    686   if (pos != PASS_MOVE) { 
     686  if (pos) { 
    687687    /* 2. Unless pass, the move must be inside the board. */ 
    688688    ASSERT_ON_BOARD1(pos); 
    689689     
     
    691691    shadow[pos] = 1; 
    692692 
    693693    /* 3. The location must be empty. */ 
    694     if (board[pos] != EMPTY) 
     694    if (board[pos]) 
    695695      return 0; 
    696696     
    697697    /* 4. Test if the location is the ko point. */ 
     
    838838   * undone stones */ 
    839839  memcpy(&board_hash_stack[stackp], &board_hash, sizeof(board_hash)); 
    840840 
    841   if (board_ko_pos != NO_MOVE) 
     841  if (board_ko_pos) 
    842842    hashdata_invert_ko(&board_hash, board_ko_pos); 
    843843 
    844844  board_ko_pos = NO_MOVE; 
    845845   
    846846  stackp++; 
    847847 
    848   if (pos != PASS_MOVE) { 
     848  if (pos) { 
    849849    PUSH_VALUE(black_captured); 
    850850    PUSH_VALUE(white_captured); 
    851851    do_play_move(pos, color); 
     
    864864  /* 1. The color must be BLACK or WHITE. */ 
    865865  gg_assert(color == BLACK || color == WHITE); 
    866866  
    867   if (pos != PASS_MOVE) { 
     867  if (pos) { 
    868868    /* 2. Unless pass, the move must be inside the board. */ 
    869869    ASSERT_ON_BOARD1(pos); 
    870870     
     
    872872    shadow[pos] = 1; 
    873873 
    874874    /* 3. The location must be empty. */ 
    875     if (board[pos] != EMPTY) 
     875    if (board[pos]) 
    876876      return 0; 
    877877     
    878878    /* 4. The location must not be the ko point, unless ignore_ko == 1. */ 
     
    10491049{ 
    10501050  ASSERT1(stackp == 0, pos); 
    10511051  ASSERT_ON_BOARD1(pos); 
    1052   ASSERT1(board[pos] == EMPTY, pos); 
     1052  ASSERT1(!board[pos], pos); 
    10531053 
    10541054  board[pos] = color; 
    10551055  hashdata_invert_stone(&board_hash, pos, color); 
     
    10941094  gg_assert(hashdata_is_equal(oldkey, board_hash)); 
    10951095#endif 
    10961096 
    1097   if (board_ko_pos != NO_MOVE) 
     1097  if (board_ko_pos) 
    10981098    hashdata_invert_ko(&board_hash, board_ko_pos); 
    10991099  board_ko_pos = NO_MOVE; 
    11001100 
    11011101  /* If the move is a pass, we can skip some steps. */ 
    1102   if (pos != PASS_MOVE) { 
     1102  if (pos) { 
    11031103    ASSERT_ON_BOARD1(pos); 
    1104     ASSERT1(board[pos] == EMPTY, pos); 
     1104    ASSERT1(!board[pos], pos); 
    11051105 
    11061106    /* Do play the move. */ 
    11071107    if (!is_suicide(pos, color)) 
     
    11591159{ 
    11601160  ASSERT1(stackp == 0, pos); 
    11611161  ASSERT1(color == WHITE || color == BLACK, pos); 
    1162   ASSERT1(pos == PASS_MOVE || ON_BOARD1(pos), pos); 
    1163   ASSERT1(pos == PASS_MOVE || board[pos] == EMPTY, pos); 
    1164   ASSERT1(komaster == EMPTY && kom_pos == NO_MOVE, pos); 
     1162  ASSERT1(!pos || ON_BOARD1(pos), pos); 
     1163  ASSERT1(!pos || !board[pos], pos); 
     1164  ASSERT1(!komaster && !kom_pos, pos); 
    11651165 
    11661166  if (move_history_pointer >= MAX_MOVE_HISTORY) { 
    11671167    /* The move history is full. We resolve this by collapsing the 
     
    11991199  move_history_color[move_history_pointer] = color; 
    12001200  move_history_pos[move_history_pointer] = pos; 
    12011201  move_history_hash[move_history_pointer] = board_hash; 
    1202   if (board_ko_pos != NO_MOVE) 
     1202  if (board_ko_pos) 
    12031203    hashdata_invert_ko(&move_history_hash[move_history_pointer], board_ko_pos); 
    12041204  move_history_pointer++; 
    12051205   
     
    12511251int 
    12521252get_last_move() 
    12531253{ 
    1254   if (move_history_pointer == 0) 
     1254  if (!move_history_pointer) 
    12551255    return PASS_MOVE; 
    12561256 
    12571257  return move_history_pos[move_history_pointer - 1]; 
     
    12631263int 
    12641264get_last_player() 
    12651265{ 
    1266   if (move_history_pointer == 0) 
     1266  if (!move_history_pointer) 
    12671267    return EMPTY; 
    12681268 
    12691269  return move_history_color[move_history_pointer - 1]; 
     
    12821282int 
    12831283is_pass(int pos) 
    12841284{ 
    1285   return pos == PASS_MOVE; 
     1285  return !pos; 
    12861286} 
    12871287 
    12881288 
     
    13001300is_legal(int pos, int color) 
    13011301{ 
    13021302  /* 0. A pass move is always legal. */ 
    1303   if (pos == PASS_MOVE) 
     1303  if (!pos) 
    13041304    return 1; 
    13051305 
    13061306  /* 1. The move must be inside the board. */ 
    13071307  ASSERT_ON_BOARD1(pos); 
    13081308 
    13091309  /* 2. The location must be empty. */ 
    1310   if (board[pos] != EMPTY)  
     1310  if (board[pos])  
    13111311    return 0; 
    13121312 
    13131313  /* 3. The location must not be the ko point. */ 
     
    13571357  int checked_pos; 
    13581358  int stone; 
    13591359  ASSERT_ON_BOARD1(pos); 
    1360   ASSERT1(board[pos] == EMPTY, pos); 
     1360  ASSERT1(!board[pos], pos); 
    13611361 
    13621362  /* Check for suicide. */ 
    13631363  checked_pos = SOUTH(pos); 
    13641364  stone = board[checked_pos]; 
    1365   if (stone == EMPTY 
     1365  if (!stone 
    13661366      || (ON_BOARD(checked_pos) 
    13671367          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    13681368    return 0; 
    13691369 
    13701370  checked_pos = WEST(pos); 
    13711371  stone = board[checked_pos]; 
    1372   if (stone == EMPTY 
     1372  if (!stone 
    13731373      || (ON_BOARD(checked_pos) 
    13741374          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    13751375    return 0; 
    13761376 
    13771377  checked_pos = NORTH(pos); 
    13781378  stone = board[checked_pos]; 
    1379   if (stone == EMPTY 
     1379  if (!stone 
    13801380      || (ON_BOARD(checked_pos) 
    13811381          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    13821382    return 0; 
    13831383 
    13841384  checked_pos = EAST(pos); 
    13851385  stone = board[checked_pos]; 
    1386   if (stone == EMPTY 
     1386  if (!stone 
    13871387      || (ON_BOARD(checked_pos) 
    13881388          && ((stone == color) ^ (LIBERTIES(string_number[checked_pos]) == 1)))) 
    13891389    return 0; 
     
    14001400is_illegal_ko_capture(int pos, int color) 
    14011401{ 
    14021402  ASSERT_ON_BOARD1(pos); 
    1403   ASSERT1(board[pos] == EMPTY, pos); 
     1403  ASSERT1(!board[pos], pos); 
    14041404 
    14051405  return (pos == board_ko_pos 
    14061406    /*    The ko position is guaranteed to have all neighbors of the 
     
    14261426  gg_assert(stackp == 0); 
    14271427 
    14281428  /* 1. A pass move is always legal, no matter what. */ 
    1429   if (pos == PASS_MOVE) 
     1429  if (!pos) 
    14301430    return 1; 
    14311431 
    14321432  /* 2. The move must be inside the board. */ 
    14331433  ASSERT_ON_BOARD1(pos); 
    14341434 
    14351435  /* 3. The location must be empty. */ 
    1436   if (board[pos] != EMPTY)  
     1436  if (board[pos])  
    14371437    return 0; 
    14381438 
    14391439  /* 4. Simple ko repetition is only allowed if no ko rule is in use. 
     
    16121612    *is_conditional_ko = 1; 
    16131613 
    16141614    /* Conditional ko capture, set komaster parameters (1b and 5c). */ 
    1615     if (komaster == EMPTY || komaster == WEAK_KO) { 
     1615    if (!komaster || komaster == WEAK_KO) { 
    16161616      set_new_komaster(color); 
    16171617      set_new_kom_pos(kpos); 
    16181618      return 1; 
     
    16311631          || (komaster == GRAY_WHITE && color == WHITE) 
    16321632          || (komaster == GRAY_BLACK && color == BLACK)) 
    16331633         && (board[kom_pos] == color 
    1634              || (board[kom_pos] == EMPTY 
     1634             || (!board[kom_pos] 
    16351635                 && is_suicide(kom_pos, OTHER_COLOR(color))))) { 
    16361636      set_new_komaster(EMPTY); 
    16371637      set_new_kom_pos(NO_MOVE); 
     
    16601660    /* We can reach here when komaster is EMPTY or WEAK_KO. If previous 
    16611661     * move was also a ko capture, we now set komaster to WEAK_KO (1a and 5b). 
    16621662     */ 
    1663     if (previous_board_ko_pos != NO_MOVE) { 
     1663    if (previous_board_ko_pos) { 
    16641664      set_new_komaster(WEAK_KO); 
    16651665      set_new_kom_pos(previous_board_ko_pos); 
    16661666    } 
     
    17241724int 
    17251725are_neighbors(int pos1, int pos2) 
    17261726{ 
    1727   if (board[pos1] == EMPTY) { 
    1728     if (board[pos2] == EMPTY) 
     1727  if (!board[pos1]) { 
     1728    if (!board[pos2]) 
    17291729      return (gg_abs(pos1 - pos2) == NS || gg_abs(pos1 - pos2) == WE); 
    17301730    else 
    17311731      return neighbor_of_string(pos1, pos2); 
    17321732  } 
    17331733  else { 
    1734     if (board[pos2] == EMPTY) 
     1734    if (!board[pos2]) 
    17351735      return neighbor_of_string(pos2, pos1); 
    17361736    else 
    17371737      return adjacent_strings(pos1, pos2); 
     
    17681768  int str_nr; 
    17691769 
    17701770  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    1771   ASSERT1(libs != NULL, str_pos); 
     1771  ASSERT1(libs, str_pos); 
    17721772 
    17731773  /* We already have the list of liberties and only need to copy it to 
    17741774   * libs[]. 
     
    18631863  int checked_pos; 
    18641864  int str_nr; 
    18651865 
    1866   ASSERT1(board[pos] == EMPTY, pos); 
     1866  ASSERT1(!board[pos], pos); 
    18671867  ASSERT1(IS_STONE(color), pos); 
    18681868 
    18691869  /* Find neighboring strings of the same color. If there are more than two of 
     
    20452045 
    20462046  struct board_cache_entry *entry = &approxlib_cache[pos][color - WHITE]; 
    20472047 
    2048   ASSERT1(board[pos] == EMPTY, pos); 
     2048  ASSERT1(!board[pos], pos); 
    20492049  ASSERT1(IS_STONE(color), pos); 
    20502050 
    20512051  if (!libs) { 
     
    20862086 
    20872087#else /* not USE_BOARD_CACHES */ 
    20882088 
    2089   ASSERT1(board[pos] == EMPTY, pos); 
     2089  ASSERT1(!board[pos], pos); 
    20902090  ASSERT1(IS_STONE(color), pos); 
    20912091 
    20922092  if (!libs) { 
     
    21302130  MARK_LIBERTY(pos); 
    21312131 
    21322132  checked_pos = SOUTH(pos); 
    2133   if (board[checked_pos] == EMPTY) { 
     2133  if (!board[checked_pos]) { 
    21342134    if (ml[checked_pos] != liberty_mark) { 
    2135       if (libs != NULL) 
     2135      if (libs) 
    21362136        libs[liberties] = checked_pos; 
    21372137      liberties++; 
    21382138      /* Stop counting if we reach maxlib. */ 
     
    21472147    last_lib = cur_lib + string[str_nr].liberties; 
    21482148    for (; cur_lib < last_lib; cur_lib++) { 
    21492149      if (UNMARKED_LIBERTY(*cur_lib)) { 
    2150         if (libs != NULL) 
     2150        if (libs) 
    21512151          libs[liberties] = *cur_lib; 
    21522152        liberties++; 
    21532153        if (liberties >= maxlib) 
     
    21582158  } 
    21592159   
    21602160  checked_pos = WEST(pos); 
    2161   if (board[checked_pos] == EMPTY) { 
     2161  if (!board[checked_pos]) { 
    21622162    if (ml[checked_pos] != liberty_mark) { 
    2163       if (libs != NULL) 
     2163      if (libs) 
    21642164        libs[liberties] = checked_pos; 
    21652165      liberties++; 
    21662166      /* Stop counting if we reach maxlib. */ 
     
    21752175    last_lib = cur_lib + string[str_nr].liberties; 
    21762176    for (; cur_lib < last_lib; cur_lib++) { 
    21772177      if (UNMARKED_LIBERTY(*cur_lib)) { 
    2178         if (libs != NULL) 
     2178        if (libs) 
    21792179          libs[liberties] = *cur_lib; 
    21802180        liberties++; 
    21812181        if (liberties >= maxlib) 
     
    21862186  } 
    21872187   
    21882188  checked_pos = NORTH(pos); 
    2189   if (board[checked_pos] == EMPTY) { 
     2189  if (!board[checked_pos]) { 
    21902190    if (ml[checked_pos] != liberty_mark) { 
    2191       if (libs != NULL) 
     2191      if (libs) 
    21922192        libs[liberties] = checked_pos; 
    21932193      liberties++; 
    21942194      /* Stop counting if we reach maxlib. */ 
     
    22032203    last_lib = cur_lib + string[str_nr].liberties; 
    22042204    for (; cur_lib < last_lib; cur_lib++) { 
    22052205      if (UNMARKED_LIBERTY(*cur_lib)) { 
    2206         if (libs != NULL) 
     2206        if (libs) 
    22072207          libs[liberties] = *cur_lib; 
    22082208        liberties++; 
    22092209        if (liberties >= maxlib) 
     
    22142214  } 
    22152215 
    22162216  checked_pos = EAST(pos); 
    2217   if (board[checked_pos] == EMPTY) { 
     2217  if (!board[checked_pos]) { 
    22182218    if (ml[checked_pos] != liberty_mark) { 
    2219       if (libs != NULL) 
     2219      if (libs) 
    22202220        libs[liberties] = checked_pos; 
    22212221      liberties++; 
    22222222/* Unneeded since we're about to leave. */ 
     
    22332233    last_lib = cur_lib + string[str_nr].liberties; 
    22342234    for (; cur_lib < last_lib; cur_lib++) { 
    22352235      if (UNMARKED_LIBERTY(*cur_lib)) { 
    2236         if (libs != NULL) 
     2236        if (libs) 
    22372237          libs[liberties] = *cur_lib; 
    22382238        liberties++; 
    22392239        if (liberties >= maxlib) 
     
    22752275 
    22762276  for (delta_o = delta; delta_o < last_delta_4; delta_o++) { 
    22772277    checked_pos = pos + *delta_o; 
    2278     if (board[checked_pos] == EMPTY) { 
     2278    if (!board[checked_pos]) { 
    22792279      if (ml[checked_pos] != liberty_mark) { 
    22802280        if (libs) 
    22812281          libs[liberties] = checked_pos; 
     
    23592359 
    23602360  struct board_cache_entry *entry = &accuratelib_cache[pos][color - WHITE]; 
    23612361 
    2362   ASSERT1(board[pos] == EMPTY, pos); 
     2362  ASSERT1(!board[pos], pos); 
    23632363  ASSERT1(IS_STONE(color), pos); 
    23642364 
    23652365  if (!libs) { 
     
    23962396 
    23972397#else /* not USE_BOARD_CACHES */ 
    23982398 
    2399   ASSERT1(board[pos] == EMPTY, pos); 
     2399  ASSERT1(!board[pos], pos); 
    24002400  ASSERT1(IS_STONE(color), pos); 
    24012401 
    24022402  if (!libs) { 
     
    24342434 
    24352435  for (act_delta = delta; act_delta < last_delta_4; act_delta++) { 
    24362436    int checked_pos = pos + *act_delta; 
    2437     if (board[checked_pos] == EMPTY) { 
     2437    if (!board[checked_pos]) { 
    24382438      if (ml[checked_pos] != liberty_mark) { 
    24392439        /* A trivial liberty */ 
    24402440        if (libs) 
     
    26092609int 
    26102610count_common_libs(int str1_pos, int str2_pos) 
    26112611{ 
    2612   int all_libs1[MAXLIBS], *libs1; 
    2613   int *last_lib; 
     2612  static int all_libs1[MAXLIBS]; 
     2613  int *last_lib, *libs1; 
    26142614  int liberties1, liberties2; 
    26152615  int str1_nr, str2_nr; 
    26162616  int commonlibs = 0; 
     
    26832683int 
    26842684find_common_libs(int str1_pos, int str2_pos, int maxlib, int *libs) 
    26852685{ 
    2686   int all_libs1[MAXLIBS], *libs1; 
    2687   int *last_lib; 
     2686  static int all_libs1[MAXLIBS]; 
     2687  int *last_lib, *libs1; 
    26882688  int liberties1, liberties2; 
    26892689  int str1_nr, str2_nr; 
    26902690  int commonlibs = 0; 
     
    26942694  ASSERT_ON_BOARD1(str2_pos); 
    26952695  ASSERT1(IS_STONE(board[str1_pos]), str1_pos); 
    26962696  ASSERT1(IS_STONE(board[str2_pos]), str2_pos); 
    2697   ASSERT1(libs != NULL, str1_pos); 
     2697  ASSERT1(libs, str1_pos); 
    26982698 
    26992699  str1_nr = string_number[str1_pos]; 
    27002700  str2_nr = string_number[str2_pos]; 
     
    27592759int 
    27602760have_common_lib(int str1_pos, int str2_pos, int *lib) 
    27612761{ 
    2762   int all_libs1[MAXLIBS], *libs1; 
    2763   int *last_lib; 
     2762  static int all_libs1[MAXLIBS]; 
     2763  int *last_lib, *libs1; 
    27642764  int liberties1, liberties2; 
    27652765  int str1_nr, str2_nr; 
    27662766  int color; 
     
    29842984extended_chainlinks(int str_pos, int adj[MAXCHAIN], int both_colors) 
    29852985{ 
    29862986  int *cur_neighbor, *last_neigbor; 
    2987   int libs[MAXLIBS]; 
     2987  static int libs[MAXLIBS]; 
    29882988  int *cur_lib, *last_lib; 
    29892989  int checked_pos; 
    29902990  int color; 
     
    31043104  int liberties; 
    31053105   
    31063106  ASSERT_ON_BOARD1(pos); 
    3107   ASSERT1(board[pos] == EMPTY, pos); 
     3107  ASSERT1(!board[pos], pos); 
    31083108  ASSERT1(IS_STONE(color), pos); 
    31093109 
    31103110  /* 1. Try first to solve the problem without much work. */ 
     
    31123112   
    31133113  checked_pos = SOUTH(pos); 
    31143114  stone = board[checked_pos]; 
    3115   if (stone == EMPTY) 
     3115  if (!stone) 
    31163116    trivial_liberties++; 
    31173117  else if (stone == color) { 
    31183118    liberties = LIBERTIES(string_number[checked_pos]); 
     
    31313131 
    31323132  checked_pos = WEST(pos); 
    31333133  stone = board[checked_pos]; 
    3134   if (stone == EMPTY) 
     3134  if (!stone) 
    31353135    trivial_liberties++; 
    31363136  else if (stone == color) { 
    31373137    liberties = LIBERTIES(string_number[checked_pos]); 
     
    31503150 
    31513151  checked_pos = NORTH(pos); 
    31523152  stone = board[checked_pos]; 
    3153   if (stone == EMPTY) 
     3153  if (!stone) 
    31543154    trivial_liberties++; 
    31553155  else if (stone == color) { 
    31563156    liberties = LIBERTIES(string_number[checked_pos]); 
     
    31693169 
    31703170  checked_pos = EAST(pos); 
    31713171  stone = board[checked_pos]; 
    3172   if (stone == EMPTY) 
     3172  if (!stone) 
    31733173    trivial_liberties++; 
    31743174  else if (stone == color) { 
    31753175    liberties = LIBERTIES(string_number[checked_pos]); 
     
    31983198  if ((far_liberties > 0) + captures >= 2) 
    31993199    return 0; 
    32003200 
    3201   if (captures == 0 && far_liberties + trivial_liberties <= 1) 
     3201  if (!captures && far_liberties + trivial_liberties <= 1) 
    32023202    return 1; 
    32033203 
    32043204  /* 2. It was not so easy.  We use accuratelib() in this case. */ 
     
    32533253 
    32543254  ASSERT_ON_BOARD1(pos); 
    32553255  ASSERT_ON_BOARD1(str_pos); 
    3256   ASSERT1(board[pos] == EMPTY, pos); 
     3256  ASSERT1(!board[pos], pos); 
    32573257  ASSERT1(IS_STONE(board[str_pos]), str_pos); 
    32583258 
    32593259  color = board[str_pos]; 
    32603260  str_nr = string_number[str_pos]; 
    32613261 
    3262   if (board[SOUTH(pos)] == EMPTY 
     3262  if (!board[SOUTH(pos)] 
    32633263      && NEIGHBOR_OF_STRING(SOUTH(pos), str_nr, color)) 
    32643264    return 1; 
    32653265 
    3266   if (board[EAST(pos)] == EMPTY 
     3266  if (!board[EAST(pos)] 
    32673267      && NEIGHBOR_OF_STRING(EAST(pos), str_nr, color)) 
    32683268    return 1; 
    32693269 
    3270   if (board[NORTH(pos)] == EMPTY 
     3270  if (!board[NORTH(pos)] 
    32713271      && NEIGHBOR_OF_STRING(NORTH(pos), str_nr, color)) 
    32723272    return 1; 
    32733273 
    3274   if (board[WEST(pos)] == EMPTY 
     3274  if (!board[WEST(pos)] 
    32753275      && NEIGHBOR_OF_STRING(WEST(pos), str_nr, color)) 
    32763276    return 1; 
    32773277 
     
    34903490{ 
    34913491  ASSERT_ON_BOARD1(pos); 
    34923492 
    3493   if (board[pos] == EMPTY) { 
     3493  if (!board[pos]) { 
    34943494    int color; 
    34953495    if (ON_BOARD(SOUTH(pos))) 
    34963496      color = board[SOUTH(pos)]; 
     
    35333533 
    35343534  this_board_hash = board_hash; 
    35353535 
    3536   if (board_ko_pos != NO_MOVE) 
     3536  if (board_ko_pos) 
    35373537    hashdata_invert_ko(&this_board_hash, board_ko_pos); 
    35383538 
    35393539  really_do_trymove(pos, color); 
    35403540  new_board_hash = board_hash; 
    3541   if (board_ko_pos != NO_MOVE) 
     3541  if (board_ko_pos) 
    35423542    hashdata_invert_ko(&new_board_hash, board_ko_pos); 
    35433543  undo_trymove(); 
    35443544 
     
    35643564{ 
    35653565  int other = OTHER_COLOR(color); 
    35663566 
    3567   ASSERT1(board[pos] == EMPTY, pos); 
     3567  ASSERT1(!board[pos], pos); 
    35683568 
    35693569  if (board[SOUTH(pos)] == other && LIBERTIES(string_number[SOUTH(pos)]) == 1) 
    35703570    return 1; 
     
    37543754  for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    37553755    if (!ON_BOARD(pos)) 
    37563756      continue; 
    3757     if (board[pos] == EMPTY) 
     3757    if (!board[pos]) 
    37583758      fprintf(stderr, " . "); 
    37593759    else 
    37603760      fprintf(stderr, "%2d ", string_number[pos]); 
     
    37663766  } 
    37673767 
    37683768  for (s = 0; s < next_string; s++) { 
    3769     if (board[string[s].origin] == EMPTY) 
     3769    if (!board[string[s].origin]) 
    37703770      continue; 
    37713771     
    37723772    gprintf("%o%d %s %1m size %d, %d liberties, %d neighbors\n", s, 
     
    38583858     * already visited liberties and neighbors. 
    38593859     */ 
    38603860    checked_pos = SOUTH(pos); 
    3861     if (board[checked_pos] == EMPTY) { 
     3861    if (!board[checked_pos]) { 
    38623862      if (ml[checked_pos] != liberty_mark) { 
    38633863        ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    38643864      } 
     
    38723872    } 
    38733873     
    38743874    checked_pos = WEST(pos); 
    3875     if (board[checked_pos] == EMPTY) { 
     3875    if (!board[checked_pos]) { 
    38763876      if (ml[checked_pos] != liberty_mark) { 
    38773877        ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    38783878      } 
     
    38863886    } 
    38873887     
    38883888    checked_pos = NORTH(pos); 
    3889     if (board[checked_pos] == EMPTY) { 
     3889    if (!board[checked_pos]) { 
    38903890      if (ml[checked_pos] != liberty_mark) { 
    38913891        ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    38923892      } 
     
    39003900    } 
    39013901     
    39023902    checked_pos = EAST(pos); 
    3903     if (board[checked_pos] == EMPTY) { 
     3903    if (!board[checked_pos]) { 
    39043904      if (ml[checked_pos] != liberty_mark) { 
    39053905        ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    39063906      } 
     
    44814481   */ 
    44824482  checked_pos = SOUTH(pos); 
    44834483  stone = board[checked_pos]; 
    4484   if (stone == EMPTY) { 
     4484  if (!stone) { 
    44854485    if (ml[checked_pos] != liberty_mark) 
    44864486      ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    44874487  } 
     
    45014501 
    45024502  checked_pos = WEST(pos); 
    45034503  stone = board[checked_pos]; 
    4504   if (stone == EMPTY) { 
     4504  if (!stone) { 
    45054505    if (ml[checked_pos] != liberty_mark) 
    45064506      ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    45074507  } 
     
    45214521   
    45224522  checked_pos = NORTH(pos); 
    45234523  stone = board[checked_pos]; 
    4524   if (stone == EMPTY) { 
     4524  if (!stone) { 
    45254525    if (ml[checked_pos] != liberty_mark) 
    45264526      ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
    45274527  } 
     
    45414541   
    45424542  checked_pos = EAST(pos); 
    45434543  stone = board[checked_pos]; 
    4544   if (stone == EMPTY) { 
     4544  if (!stone) { 
    45454545    if (ml[checked_pos] != liberty_mark) 
    45464546#if 0 
    45474547      ADD_AND_MARK_LIBERTY(str_nr, checked_pos); 
     
    47094709  } 
    47104710 
    47114711  /* Choose strategy depending on the number of friendly neighbors. */ 
    4712   if (neighbor_allies == 0) 
     4712  if (!neighbor_allies) 
    47134713    create_new_string(pos, color); 
    47144714  else if (neighbor_allies == 1) { 
    47154715    gg_assert(extend_nr >= 0); 
     
    47324732  if (string[str_nr].liberties == 1 
    47334733      && captured_stones == 1) { 
    47344734    /* In case of a double ko: clear old ko position first. */ 
    4735     if (board_ko_pos != NO_MOVE) 
     4735    if (board_ko_pos) 
    47364736      hashdata_invert_ko(&board_hash, board_ko_pos); 
    47374737    board_ko_pos = string_libs[str_nr].list[0]; 
    47384738    hashdata_invert_ko(&board_hash, board_ko_pos); 
     
    47724772    pos = move + delta[k]; 
    47734773    if (!ON_BOARD(pos)) 
    47744774      (*number_edges)++; 
    4775     else if (board[pos] == EMPTY) 
     4775    else if (!board[pos]) 
    47764776      (*number_open)++; 
    47774777    else { 
    47784778      int s = string_number[pos]; 
     
    48084808#define code1(pos, stone) \ 
    48094809  if (stone == GRAY) \ 
    48104810    (*number_edges)++; \ 
    4811   else if (stone == EMPTY) \ 
     4811  else if (!stone) \ 
    48124812    (*number_open)++; \ 
    48134813  else { \ 
    48144814    int str_nr = string_number[pos]; \ 
  • engine/board.vcproj

    diff -N -r -u -X .ignore gnugo-copy/engine/board.vcproj gnugo/engine/board.vcproj
    old new  
    200200                                </FileConfiguration> 
    201201                        </File> 
    202202                        <File 
    203                                 RelativePath="board.h" 
    204                                 > 
    205                         </File> 
    206                         <File 
    207203                                RelativePath="boardlib.c" 
    208204                                > 
    209205                                <FileConfiguration 
     
    341337                        Name="Header Files" 
    342338                        Filter="h;hpp;hxx;hm;inl" 
    343339                        > 
     340                        <File 
     341                                RelativePath="board.h" 
     342                                > 
     343                        </File> 
     344                        <File 
     345                                RelativePath="..\config.h" 
     346                                > 
     347                        </File> 
    344348                </Filter> 
    345349        </Files> 
    346350        <Globals> 
  • engine/engine.vcproj

    diff -N -r -u -X .ignore gnugo-copy/engine/engine.vcproj gnugo/engine/engine.vcproj
    old new  
    986986                                > 
    987987                        </File> 
    988988                        <File 
     989                                RelativePath="..\config.h" 
     990                                > 
     991                        </File> 
     992                        <File 
    989993                                RelativePath="gnugo.h" 
    990994                                > 
    991995                        </File> 
  • engine/genmove.c

    diff -N -r -u -X .ignore gnugo-copy/engine/genmove.c gnugo/engine/genmove.c
    old new  
    167167    return; 
    168168  } 
    169169 
    170   if (stones_on_board(BLACK | WHITE) != 0) { 
    171     if (NEEDS_UPDATE(initial_influence_examined)) 
    172       compute_worm_influence(); 
     170  if (!stones_on_board(BLACK | WHITE)) { 
     171    initialize_dragon_data(); 
     172    compute_scores(chinese_rules || aftermath_play); 
    173173 
    174     if (how_much == EXAMINE_INITIAL_INFLUENCE) { 
     174#ifndef GG_TURN_OFF_TRACES 
     175    verbose = save_verbose; 
     176#endif 
     177 
     178    gg_assert(test_gray_border() < 0); 
    175179 
    176180#ifndef GG_TURN_OFF_TRACES 
    177       verbose = save_verbose; 
     181    if (printworms) 
     182      show_dragons(); 
    178183#endif 
    179184 
    180       gg_assert(test_gray_border() < 0); 
    181       return; 
    182     } 
     185    return; 
     186  } 
     187 
     188  if (NEEDS_UPDATE(initial_influence_examined)) 
     189    compute_worm_influence(); 
    183190 
    184     if (how_much == EXAMINE_DRAGONS_WITHOUT_OWL) { 
    185       if (NEEDS_UPDATE(dragons_examined_without_owl)) 
    186         make_dragons(1); 
     191  if (how_much == EXAMINE_INITIAL_INFLUENCE) { 
    187192 
    188193#ifndef GG_TURN_OFF_TRACES 
    189       verbose = save_verbose; 
     194    verbose = save_verbose; 
    190195#endif 
    191196 
    192       gg_assert(test_gray_border() < 0); 
    193       return; 
    194     } 
    195      
    196     if (NEEDS_UPDATE(dragons_examined)) { 
    197       make_dragons(0); 
    198       compute_scores(chinese_rules || aftermath_play); 
    199       /* We have automatically done a partial dragon analysis as well. */ 
    200       dragons_examined_without_owl = position_number; 
    201     } 
    202     if (how_much == EXAMINE_DRAGONS) { 
     197    gg_assert(test_gray_border() < 0); 
     198    return; 
     199  } 
     200 
     201  if (how_much == EXAMINE_DRAGONS_WITHOUT_OWL) { 
     202    if (NEEDS_UPDATE(dragons_examined_without_owl)) 
     203      make_dragons(1); 
    203204 
    204205#ifndef GG_TURN_OFF_TRACES 
    205       verbose = save_verbose; 
     206    verbose = save_verbose; 
    206207#endif 
    207208 
    208       gg_assert(test_gray_border() < 0); 
    209       return; 
    210     } 
     209    gg_assert(test_gray_border() < 0); 
     210    return; 
    211211  } 
    212   else if (how_much == EXAMINE_INITIAL_INFLUENCE 
    213            || how_much == EXAMINE_DRAGONS 
    214            || how_much == EXAMINE_ALL) { 
    215     initialize_dragon_data(); 
     212     
     213  if (NEEDS_UPDATE(dragons_examined)) { 
     214    make_dragons(0); 
    216215    compute_scores(chinese_rules || aftermath_play); 
     216    /* We have automatically done a partial dragon analysis as well. */ 
     217    dragons_examined_without_owl = position_number; 
     218  } 
     219 
     220  if (how_much == EXAMINE_DRAGONS) { 
    217221 
    218222#ifndef GG_TURN_OFF_TRACES 
    219223    verbose = save_verbose; 
  • engine/influence.c

    diff -N -r -u -X .ignore gnugo-copy/engine/influence.c gnugo/engine/influence.c
    old new  
    11521152 * the -m command line option). 
    11531153 * 
    11541154 * It is assumed that color is in turn to move. (This affects the 
    1155  * barrier patterns (class A, D) and intrusions (class B)). Color 
     1155 * barrier patterns (class A, D) and intrusions (class B)). 
    11561156 */ 
    11571157 
    11581158void 
  • engine/liberty.h

    diff -N -r -u -X .ignore gnugo-copy/engine/liberty.h gnugo/engine/liberty.h
    old new  
    832832 
    833833  /* The following arrays keeps track of up to MAX_TACTICAL_POINTS 
    834834   * different attack, defense, attack threat, and defense threat 
    835    * points with corresponding result codes. (0 = loss, 1 = bad ko, 2 
    836    * = good ko, 3 = win). The arrays are guaranteed to be sorted with 
    837    * respect to the codes so that the first element contains the best 
    838    * result. Checked and discarded moves are stored, too. 
     835   * points with corresponding result codes. The arrays are guaranteed to 
     836   * be sorted with respect to the codes so that the first element contains 
     837   * the best result. Checked and discarded moves are stored, too. 
    839838   */ 
    840839  int attack_points[MAX_TACTICAL_POINTS]; 
    841840  int attack_codes[MAX_TACTICAL_POINTS]; 
     
    924923  enum dragon_status owl_threat_status; /* CAN_THREATEN_ATTACK/DEFENSE       */ 
    925924  enum dragon_status owl_status; /* (ALIVE, DEAD, UNKNOWN, CRITICAL, UNCHECKED)    */ 
    926925  int owl_attack_point;    /* vital point for attack                         */ 
    927   int owl_attack_code;     /* ko result code                                 */ 
     926  int owl_attack_code;     /* result code                                    */ 
    928927  int owl_attack_certain;  /* 0 if owl reading node limit is reached         */ 
    929928  int owl_attack_node_count; 
    930929  int owl_second_attack_point;/* if attacker gets both attack points, wins   */ 
    931930  int owl_defense_point;   /* vital point for defense                        */ 
    932   int owl_defense_code;    /* ko result code                                 */ 
     931  int owl_defense_code;    /* result code                                    */ 
    933932  int owl_defense_certain; /* 0 if owl reading node limit is reached         */ 
    934933  int owl_second_defense_point;/* if defender gets both attack points, wins  */ 
    935934  int owl_attack_kworm;    /* only valid when owl_attack_code is GAIN        */ 
  • engine/worm.c

    diff -N -r -u -X .ignore gnugo-copy/engine/worm.c gnugo/engine/worm.c
    old new  
    3939static int find_lunch(int str, int *lunch); 
    4040static void propagate_worm2(int str); 
    4141static int genus(int str); 
    42 static void markcomponent(int str, int pos, int mg[BOARDMAX]); 
     42static void markcomponent(int pos, signed char mg[BOARDMAX]); 
    4343static int examine_cavity(int pos, int *edge); 
    4444static void cavity_recurse(int pos, int mx[BOARDMAX],  
    4545                           int *border_color, int *edge, int str); 
    4646static void ping_cave(int str, int *result1,  int *result2, 
    4747                      int *result3, int *result4); 
    4848static void ping_recurse(int pos, int *counter,  
    49                          int mx[BOARDMAX],  
    50                          int mr[BOARDMAX], int color); 
     49                         int mx[BOARDSIZE],  
     50                         int mr[BOARDSIZE], int color, int other); 
    5151static int touching(int pos, int color); 
    5252static void find_attack_patterns(void); 
    5353static void attack_callback(int anchor, int color, 
     
    434434   *  - the genus must be zero  
    435435   *  - there can be no second order liberties 
    436436   *  - it can't be a cutstone 
     437   *  - there is no neighboring attackable worm (lunch) 
    437438   *  - if it is removed from the board, the remaining cavity has 
    438439   *    border color the opposite color of the string  
    439440   *  - it contains at most two edge vertices. 
     
    12961297 * to the string by placing n stones of the same color on the board,  
    12971298 * but no fewer. The path of connection may pass through an intervening group 
    12981299 * of the same color. The stones placed at distance >1 may not touch a 
    1299  * group of the opposite color. At the edge, also diagonal neighbors 
    1300  * count as touching. The path may also not pass through a liberty at distance 
    1301  * 1 if that liberty is flanked by two stones of the opposing color. This 
    1302  * reflects the fact that the O stone is blocked from expansion to the 
    1303  * left by the two X stones in the following situation: 
     1300 * group of the opposite color. The path may also not pass through a liberty 
     1301 * at distance 1 if that liberty is flanked by two stones of the opposing 
     1302 * color. This reflects the fact that the O stone is blocked from expansion 
     1303 * to the left by the two X stones in the following situation: 
    13041304 *  
    13051305 *          X. 
    13061306 *          .O 
     
    13171317ping_cave(int str, int *lib1, int *lib2, int *lib3, int *lib4) 
    13181318{ 
    13191319  int pos; 
    1320   int k; 
    13211320  int libs[MAXLIBS]; 
    1322   int mrc[BOARDMAX]; 
    1323   int mse[BOARDMAX]; 
     1321  int *cur_lib, *last_lib; 
     1322  int mrc[BOARDSIZE]; 
     1323  int mse[BOARDSIZE]; 
    13241324  int color = board[str]; 
    13251325  int other = OTHER_COLOR(color); 
    13261326 
     
    13281328 
    13291329  /* Find and mark the first order liberties. */ 
    13301330  *lib1 = findlib(str, MAXLIBS, libs); 
    1331   for (k = 0; k < *lib1; k++) 
    1332     mse[libs[k]] = 1; 
     1331  cur_lib = libs; 
     1332  last_lib = libs + *lib1; 
     1333  for (; cur_lib < last_lib; cur_lib++) 
     1334    mse[*cur_lib] = 1; 
    13331335 
    13341336  /* Reset mse at liberties which are flanked by two stones of the 
    13351337   * opposite color, or one stone and the edge. 
    13361338   */ 
    13371339 
    13381340  for (pos = BOARDMIN; pos < BOARDMAX; pos++) 
    1339     if (ON_BOARD(pos) 
    1340         && mse[pos] 
     1341    if (mse[pos] 
    13411342        && (((      !ON_BOARD(SOUTH(pos)) || board[SOUTH(pos)] == other) 
    13421343             && (   !ON_BOARD(NORTH(pos)) || board[NORTH(pos)] == other)) 
    13431344            || ((   !ON_BOARD(WEST(pos))  || board[WEST(pos)]  == other) 
     
    13461347   
    13471348  *lib2 = 0; 
    13481349  memset(mrc, 0, sizeof(mrc)); 
    1349   ping_recurse(str, lib2, mse, mrc, color); 
     1350  ping_recurse(str, lib2, mse, mrc, color, other); 
    13501351 
    13511352  *lib3 = 0; 
    13521353  memset(mrc, 0, sizeof(mrc)); 
    1353   ping_recurse(str, lib3, mse, mrc, color); 
     1354  ping_recurse(str, lib3, mse, mrc, color, other); 
    13541355 
    13551356  *lib4 = 0; 
    13561357  memset(mrc, 0, sizeof(mrc)); 
    1357   ping_recurse(str, lib4, mse, mrc, color); 
     1358  ping_recurse(str, lib4, mse, mrc, color, other); 
    13581359} 
    13591360 
    13601361 
    1361 /* recursive function called by ping_cave */ 
     1362/* recursive function called by ping_cave 
     1363 * mx - marked liberties of any order 
     1364 * mr - marked checked positions */ 
    13621365 
    13631366static void  
    13641367ping_recurse(int pos, int *counter, 
    1365              int mx[BOARDMAX], int mr[BOARDMAX], 
    1366              int color) 
     1368             int mx[BOARDSIZE], int mr[BOARDSIZE], 
     1369             int color, int other) 
    13671370{ 
    1368   int k; 
     1371  int apos; 
     1372  const int *cur_delta; 
    13691373  mr[pos] = 1; 
    13701374 
    1371   for (k = 0; k < 4; k++) { 
    1372     int apos = pos + delta[k]; 
    1373     if (board[apos] == EMPTY 
    1374         && mx[apos] == 0 
    1375         && mr[apos] == 0 
    1376         && !touching(apos, OTHER_COLOR(color))) { 
     1375  for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) { 
     1376    apos = pos + *cur_delta; 
     1377    if (!board[apos] 
     1378        && !mr[apos] 
     1379        && !mx[apos] 
     1380        && !touching(apos, other)) { 
    13771381      (*counter)++; 
    13781382      mr[apos] = 1; 
    13791383      mx[apos] = 1; 
     
    13811385  } 
    13821386   
    13831387  if (!is_ko_point(pos)) { 
    1384     for (k = 0; k < 4; k++) { 
    1385       int apos = pos + delta[k]; 
    1386       if (ON_BOARD(apos) 
    1387           && mr[apos] == 0 
    1388           && (mx[apos] == 1 
     1388    for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) { 
     1389      apos = pos + *cur_delta; 
     1390      if (!mr[apos] 
     1391          && (mx[apos] 
    13891392              || board[apos] == color)) 
    1390         ping_recurse(apos, counter, mx, mr, color); 
     1393        ping_recurse(apos, counter, mx, mr, color, other); 
    13911394    } 
    13921395  } 
    13931396} 
     
    14161419genus(int str) 
    14171420{ 
    14181421  int pos; 
    1419   int mg[BOARDMAX]; 
     1422  signed char mg[BOARDMAX]; 
    14201423  int gen = -1; 
    14211424 
    14221425  memset(mg, 0, sizeof(mg)); 
     1426  mark_string(str, mg, 1); 
     1427 
    14231428  for (pos = BOARDMIN; pos < BOARDMAX; pos++) { 
    1424     if (ON_BOARD(pos) 
    1425         && !mg[pos] 
    1426         && (board[pos] == EMPTY || !is_same_worm(pos, str))) { 
    1427       markcomponent(str, pos, mg); 
     1429    if (!mg[pos] 
     1430        && ON_BOARD(pos)) { 
     1431      markcomponent(pos, mg); 
    14281432      gen++; 
    14291433    } 
    14301434  } 
     
    14341438 
    14351439 
    14361440/* This recursive function marks the component at (pos) of  
    1437  * the complement of the string with origin (str) 
     1441 * the complement of the string. 
    14381442 */ 
    14391443 
    14401444static void  
    1441 markcomponent(int str, int pos, int mg[BOARDMAX]) 
     1445markcomponent(int pos, signed char mg[BOARDMAX]) 
    14421446{ 
    1443   int k; 
     1447  const int *cur_delta; 
    14441448  mg[pos] = 1; 
    1445   for (k = 0; k < 4; k++) { 
    1446     int apos = pos + delta[k]; 
    1447     if (ON_BOARD(apos) 
    1448         && mg[apos] == 0 
    1449         && (board[apos] == EMPTY || !is_same_worm(apos, str))) 
    1450       markcomponent(str, apos, mg); 
     1449  for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) { 
     1450    int apos = pos + *cur_delta; 
     1451    if (!mg[apos] 
     1452        && ON_BOARD(apos)) 
     1453      markcomponent(apos, mg); 
    14511454  } 
    14521455} 
    14531456 
     
    14681471{ 
    14691472  int border_color = EMPTY; 
    14701473  int ml[BOARDMAX]; 
    1471   int origin = NO_MOVE; 
     1474  int origin; 
    14721475   
    14731476  ASSERT_ON_BOARD1(pos); 
    14741477  gg_assert(edge != NULL); 
     
    14791482 
    14801483  if (IS_STONE(board[pos])) 
    14811484    origin = find_origin(pos); 
     1485  else 
     1486    origin = NO_MOVE; 
    14821487   
    14831488  cavity_recurse(pos, ml, &border_color, edge, origin); 
    14841489 
    1485   if (border_color != EMPTY) 
     1490  if (border_color) 
    14861491    return border_color; 
    14871492 
    14881493  /* We should have returned now, unless the board is completely empty. 
     
    14911496   * Notice that the board appears completely empty if there's only a 
    14921497   * single string and pos points to it. 
    14931498   */ 
    1494   gg_assert(border_color == EMPTY 
    1495             && ((pos == NO_MOVE 
    1496                  && stones_on_board(BLACK | WHITE) == 0) 
    1497                 || (pos != NO_MOVE 
    1498                     && stones_on_board(BLACK | WHITE) == countstones(pos)))); 
     1499  gg_assert((origin == NO_MOVE 
     1500             && stones_on_board(BLACK | WHITE) == 0) 
     1501            || (origin != NO_MOVE 
     1502                && stones_on_board(BLACK | WHITE) == countstones(pos))); 
    14991503   
    15001504  return GRAY; 
    15011505} 
     
    15221526cavity_recurse(int pos, int mx[BOARDMAX],  
    15231527               int *border_color, int *edge, int str) 
    15241528{ 
    1525   int k; 
    1526   ASSERT1(mx[pos] == 0, pos); 
     1529  const int *cur_delta; 
     1530  ASSERT1(!mx[pos], pos); 
    15271531 
    15281532  mx[pos] = 1; 
    15291533 
    1530   if (is_edge_vertex(pos) && board[pos] == EMPTY)  
     1534  if (is_edge_vertex(pos) && !board[pos])  
    15311535    (*edge)++; 
    15321536 
    15331537  /* Loop over the four neighbors. */ 
    1534   for (k = 0; k < 4; k++) { 
    1535     int apos = pos + delta[k]; 
     1538  for (cur_delta = delta; cur_delta < last_delta_4; cur_delta++) { 
     1539    int apos = pos + *cur_delta; 
    15361540    if (ON_BOARD(apos) && !mx[apos]) { 
    1537       int neighbor_empty = 0; 
    1538        
    1539       if (board[apos] == EMPTY) 
    1540         neighbor_empty = 1; 
    1541       else { 
    1542         /* Count the neighbor as empty if it is part of the (ai, aj) string. */ 
    1543         if (str == find_origin(apos)) 
    1544           neighbor_empty = 1; 
    1545         else 
    1546           neighbor_empty = 0; 
    1547       } 
    1548        
    1549       if (!neighbor_empty) 
    1550         *border_color |= board[apos]; 
    1551       else 
     1541      /* Count the neighbor as empty if it is part of the (ai, aj) string. */ 
     1542      if (!board[apos] || str == find_origin(apos)) 
    15521543        cavity_recurse(apos, mx, border_color, edge, str); 
     1544      else 
     1545        *border_color |= board[apos]; 
    15531546    } 
    15541547  } 
    15551548} 
  • interface/gnugo.vcproj

    diff -N -r -u -X .ignore gnugo-copy/interface/gnugo.vcproj gnugo/interface/gnugo.vcproj
    old new  
    400400                        Filter="h;hpp;hxx;hm;inl" 
    401401                        > 
    402402                        <File 
     403                                RelativePath="..\config.h" 
     404                                > 
     405                        </File> 
     406                        <File 
    403407                                RelativePath=".\interface.h" 
    404408                                > 
    405409                        </File> 
  • makevcdist.pl

    diff -N -r -u -X .ignore gnugo-copy/makevcdist.pl gnugo/makevcdist.pl
    old new  
    1717   EXPERIMENTAL_SEMEAI => 1, 
    1818   EXPERIMENTAL_OWL_EXT => 0, 
    1919   EXPERIMENTAL_CONNECTIONS => 1, 
     20   FINAL_RELEASE => 0, 
    2021   LARGE_SCALE => 0, 
    2122   GRID_OPT => 1, 
    2223   OWL_THREATS => 0, 
  • patterns/patterns.vcproj

    diff -N -r -u -X .ignore gnugo-copy/patterns/patterns.vcproj gnugo/patterns/patterns.vcproj
    old new  
    623623                        Filter="h;hpp;hxx;hm;inl" 
    624624                        > 
    625625                        <File 
     626                                RelativePath="..\config.h" 
     627                                > 
     628                        </File> 
     629                        <File 
    626630                                RelativePath="dfa.h" 
    627631                                > 
    628632                        </File>