Help
Interface
The interface of Glop is mainly constituted of the following components:
- Computations: a list of possible kind of computations (normal, misere...) at the top of the interface
- Parameters: choose the game and set the parameters for this game
- Computing branch: display the point of the game tree currently computed
- Search tree: display more information about the game tree, like the complete list of children
- Children: compute the list of children of a position, and display the known data about each child
- Information: information about Glop
The buttons inside the tabs for the different kind of computations represent the databases of positions. It indicates the number of positions stored in the base. You can click on any of these buttons (except during a computation) to save a given base, load a base previously saved, or purge the base.
Computation
First, you need to choose what you want to compute:
- The game: Sprouts or Cram
- The parameters of the game: mainly, the starting position.
- The kind of computation: normal outcome, misere outcome, nimber, canonical tree, reduced canonical tree...
Then, you can click on the Start/Stop/Pause buttons to perform the following actions:
- Start button: start the computation.
- Stop computation: stop the computation. A confirmation dialog appears.
- Pause computation: freeze the computation at its current point until you click on Restart.
The point reached by the computation is regularly refreshed in the "computing branch" tab, as a vertical list of levels. What we call a "level" is just the list of children of a given position. When you try to compute the state of a position (win/loss or nimber), you basically need to compute the state of its children. For this reason, all the computations are recursive on the "children". At a given time, the computation can be represented as the list of each child currently computed in a given level. Since it is a branch in the game tree, we call this list the "computing branch" and that’s exactly what we display in the interface. Each position displayed in this computing branch is a child of the position on the above line.
Databases
During a computation, the program stores the positions and their associated result in a database. There are several databases, for the different kind of data. The number of stored positions is displayed on a button that represent the database.
You can click on the button representing a database to save it in a file. It is possible to close Glop, then later reload the database, for example to resume an unfinished computation. When you do so, be careful to choose the same parameters in the parameters tab. You can also load several databases to merge them and the program will check that the results are consistent (an error message is displayed if any position has a different result in two databases).
The default extension for the files associated with Glop is ".spr", in reference to the game of Sprouts, the first game implemented in Glop.
Check computation
Once a computation succeeds, you may want to check the result. If you tick off the "check" box in the parameters of a computation, Glop will use an already computed database to guide itself in the game tree and compute again the same result, i.e "check" it.
The algorithm tries to minimize the number of positions needed to check this result, and stores these positions in the check database. So, using "check computation", you can reduce the number of positions. This is useful to save memory, and also if you want to do hand-checked proofs for little positions.
A base of checked positions can be saved and loaded from a file, like any other base, by clicking on the button displaying the number of positions.
Manual interaction in real-time: zapping
First of all we need to understand the underlying game theory. To compute the outcome (win or loss) of a position, we need to find one losing child (so the position is winning; only one losing child is needed), or to prove that all children are winning (so the position is losing).
As only one losing child is needed to show that a position is winning, there are several ways to complete a computation. Some of them are much easier than others, so the choice of the first child to compute is very important in regard to the computing time. Glop already implement the best default choices that we have found so far for the different games, but nevertheless manual interaction in real-time, particularly at the top of the game tree can sometimes greatly accelerate the computation (for instance, it’s easy to be 50 times faster on the computation of the 12-spot Sprouts game!).
Here are the features of the program that help you to choose the right children:
- Choose a child: you can change the currently computed child of any given level just by clicking on a cell in this level. Click on the first-column cell ("Index", "Alive", "Lives") to reach the next child, and on the second-column cell ("Nimber") to reach the previous one.
- Display all children: click on the "Position" cell to display a list of all children in a given level.
Notice that positions are displayed on the right side of the interface, so you can choose the positions that seem to be easier to compute (like those that tend to separate into independent components).
We also use a system of colors to guide user choices in the interface.
- Green color means that a given level has between 5 and 10 remaining children in an unknown state.
- Yellow means 3 or 4 children left.
- Orange means 2 children left.
- Red means only 1 child left.
When you see a red level, it indicates that the position on the above level is probably a losing one.
The ideal situation is a succession of the following kind: any color/no color/any color/no color...
Children Tab
In the "Children" tab, you can compute the children of a given position and display the known data about the children.
Make sure to use a correct syntax and to choose the right game in the parameters tab. Glop will always assume that you are computing the children of a position for the game currently selected in the parameters tab. For each child, the known data is printed at the end of the line.
This tab can be used to know the winning strategy of a position. For example, suppose that you want to play a 12-spot game perfectly. First of all, compute the win/loss of the 12-spot game with the program, or load a database already computed. Then, you enter the starting position, i.e 0*12, in the Children Tab, and you click on "compute children". No special data is displayed about the children, which means that they are all winning. Suppose that you play your first move, for example to 0*8.AB|0*3.AB. Then, you just have to double-click on this child. He becomes the new parent position and its children are displayed. And you will find in the displayed data that the nimber of 0*4.A|0*4.A+0*3 is 0, i.e. it is losing. So you play this (in order to place your opponent in a losing situation) and just double-click on this child. Then, if your opponent plays 0*4.A|0*4.A+0*2.AB|AB, you double-click on that position, and you will find that the nimber of 0*4.A|0*4.A+0.1a2a is 0, etc...
This children tab is just a very useful way to access to the content of the computed databases. You can use it for all the different kind of computations (nimber, misere outcome, reduced canonical trees ...)
Sprouts parameters
It is possible to compute the outcome of a Sprouts position with p initial spots on any compact surface. The topology of the surface can be indicated with the "topology" parameter, which is the genus of the surface (in the classification of closed surfaces):
- 0 means the plane (or the sphere, it is equivalent)
- 1 means the torus
- a positive number n means a torus with n holes
- -1 means the projective plane
- -2 means the Klein Bottle
- a negative number n means a sum of n projective planes
You can choose to guide the computing with the extended conjecture. This extended conjecture states that a position keeps the same nimber if you add 6 unused points in a given region. This conjecture is false, since there are a lot of counter-examples, but fortunately it is true for 90% of the positions, and usually helps to guide the computing in the following way: when activated, we give priority to positions that seems to be losing under the extended conjecture.
It is also possible to compute arbitrary Sprouts positions, and the next section explains how Sprouts positions are represented in Glop.
Representation of Sprouts positions
Is is possible to compute in Glop the outcome or the nimber of any Sprouts position. If you have only a figure of the position you want to compute, you need first to determine its string representation. We have simplified the representation rules in Glop 2.0, by avoiding some redundancy and allowing the use of compact notations for unused spots. The details are explained on the following example:
First of all, notice that this position determines 5 regions in the plane, one of them isn’t bounded. The two regions on the left are isolated from the 3 others, so we’ll divide this position into 2 separate components (called lands): the character to separate lands is +, so the representation will be something like: "land1+land2". The character to separate regions is |, so we’ll have "R1|R2+R3|R4|R5".
The gray vertices have no life left, so they won’t be displayed in the representation. The green vertices have 3 lives left, and a vertex degree of 0: they’ll be
displayed as "0". The yellow vertices have two lives left, and a degree of 1: they’ll be displayed as "1". There are two sorts of vertices with 1 life left (the
red ones), those that are in two regions (upper-case letters), and those that are in only one region (lower-case letters).
To write the representation of a region, we enumerate the boundaries. The character to separate boundaries is ".", and we must pay attention to orientation: in a given region, we turn counterclockwise around the outer boundary, and clockwise around the others. So, the representation will be: "1aa.AB|AB+0.aaABC|0.1ab1bcDca.ACB|D"
It is impossible to play in the region "D", so we delete this region, and then we replace the letter "D" - that appears only once in the representation - with the generic number "2". When a lower case vertex occurs twice in a row, as in "1aa", we also replace these two letters with "2". The representation we give to the program is:
"12.AB|AB+0.2ABC|0.1ab1bc2ca.ACB".
When inside a region, there are 3 lives or less, it is useless to separate boundaries; so, we can delete any "." in the representation of this region. Instead of "2.AB|AB", an equivalent representation of the above position is "2AB|AB".
It is also possible to use a short notation for positions with a lot of zeros. You can write "0*x" with x equals to any number in place of "0.0...0" where "0" appears x times. For example, the initial starting positions with 5 spots can be represented equivalently by "0*5" or by "0.0.0.0.0". In the program interface, we use the short notation for positions with more than 2 zeros. Note that program internals mostly use the complete notation for sake of simplicity of the code.
Cram parameters
You can choose the size of the board that you want to compute. Since Cram boards are equivalent in regard to horizontal or vertical symmetries, the role of rows and columns are exchangeable. For example a 4x7 board is equivalent to a 7x4 board.
It is also possible to choose an arbitrary board. Cram boards are represented with an initial "B" letter and a terminal "E" letter, followed by a sequence of "0" (empty cell) and "G" (gray cell, which means occupied cell). We simply enumerate the state of the cells of the board, beginning by the first row, then the second row, and so on. The size of the board is remembered by placing a "*" mark at the end of the first row.
For example a 3x4 board, with only one domino placed horizontally at the end of the second row will be represented by: "B000*0GG000000E". If there is also a vertical domino placed vertically at the bottom of the last column, it becomes: "B000*0GG00G00GE". Unfortunately, our current representation is not very practical for human processors.