Next: Move Valuation, Previous: Examining the Position, Up: Overview
Once we have found out all about the position it is time to generate the best move. Moves are proposed by a number of different modules called move generators. The move generators themselves do not set the values of the moves, but enumerate justifications for them, called move reasons. The valuation of the moves comes last, after all moves and their reasons have been generated.
For a list and explanation of move reasons used in GNU Go, and how they are evaluated, see See Move Generation.
There are a couple of move generators that only extract data found in the previous phase, examining the position:
worm_reasons()
Moves that have been found to capture or defend a worm are proposed as candidates.
owl_reasons()
The status of every dragon, as it has been determined by the owl code (see The Owl Code) in the previous phase, is reviewed. If the status is critical, the killing or defending move gets a corresponding move reason.
semeai_move_reasons()
Similarly as owl_reasons
, this function proposes moves relevant
for semeais.
break_in_move_reasons()
This suggests moves that have been found to break into opponent's territory by the break-in module.
The following move generators do additional work:
fuseki()
Generate a move in the early fuseki, either in an empty corner of from the fuseki database.
shapes()
This is probably the most important move generator. It finds patterns from patterns/patterns.db, patterns/patterns2.db, patterns/fuseki.db, and the joseki files in the current position. Each pattern is matched in each of the 8 possible orientations obtainable by rotation and reflection. If the pattern matches, a so called "constraint" may be tested which makes use of reading to determine if the pattern should be used in the current situation. Such constraints can make demands on number of liberties of strings, life and death status, and reading out ladders, etc. The patterns may call helper functions, which may be hand coded (in patterns/helpers.c) or autogenerated.The patterns can be of a number of different classes with different goals. There are e.g. patterns which try to attack or defend groups, patterns which try to connect or cut groups, and patterns which simply try to make good shape. (In addition to the large pattern database called by
shapes()
, pattern matching is used by other modules for different tasks throughout the program. See Patterns, for a complete documentation of patterns.)
combinations()
See if there are any combination threats or atari sequences and either propose them or defend against them.
revise_thrashing_dragon()
This module does not directly propose move: If we are clearly ahead, and the last move played by the opponent is part of a dead dragon, we want to attack that dragon again to be on the safe side. This is done be setting the status of this thrashing dragon to unkown and repeating the shape move generation and move valution.
endgame_shapes()
If no move is found with a value greater than 6.0, this module matches a set of extra patterns which are designed for the endgame. The endgame patterns can be found in patterns/endgame.db.
revise_semeai()
If no move is found, this module changes the status of opponent groups involved in a semeai fromDEAD
toUNKNOWN
. After this, genmove runsshapes
andendgame_shapes
again to see if a new move turns up.
fill_liberty()
Fill a common liberty. This is only used at the end of the game. If necessary a backfilling or backcapturing move is generated.