The anatomy of melancholy

Knowledge is power.

Francis Bacon.

... in much wisdom is much grief;
and he that increaseth knowledge, increaseth sorrow.

The Book Of Ecclesiastes.

Games live their lives. They come out of nowhere, develop, and produce new games that are forgotten by all and, at times, return from oblivion. In the history of many examples of games defeated in the process of natural selection. These are a variety of options Segi, surviving only thanks to the reverent attitude of the Japanese people of their cultural heritage. Party in a game like Taikyoku shogi, could take months (if not years). But these chess dinosaurs era Haan are the brightest representatives of the "fossil" in the world of Board games.

I want to tell you about a truly amazing game. Threats it is not obvious, and goals are not trivial. You can win in a variety of ways, but the game is not easy. It can be attributed neither to the family nor Checkers to the chess family. Its origin is uncertain. For the average layman, this game is about as exciting as it is compiling magic squares. It fully justifies one of its names — you can play it can only philosophers.

For the first time, Rithmomachia, also known as the "Battle of numbers" or "Game philosophers" have been described, approximately, in the year 1030 a monk named Asilo. Authorship, apparently wrongly, attributed Plato, and the rules of the game based on the arithmetical theory of Boethius. Subsequently, the rules were slightly modified by another monk, named Hermannus Contractus, and added notes on the theory of music. A long time Rithmomachia was used as a learning tool in teaching students mathematics. Intellectuals of the time played in Rithmomachia for fun (at one time it was even more popular than Chess), Robert Burton mentioned it in "The anatomy of melancholy" and Thomas Moore think this game is good leisure for the inhabitants of its "Utopia". Then, suddenly, it was all over. Interests mathematics and Rithmomachia dispersed and the game was forgotten. Of course, this does not mean that we can't remember.

game Rules


In Rithmomachia played by two players on a rectangular Board 8x16 cells. The moves are made alternately. Each turn, moves one piece. As a result of stroke, can be taken (removed from the Board), one or more of the opponent's pieces. Define the following types of shapes:

the

    Circle the

  • theTriangle
  • Square

    Pyramid




Not paying attention to numerical markings on the figures (of which I will say below), you notice that allowed two types of moves. In the first case, the figure moves in a straight line and can be stopped by any other figure (yours or enemy) in the path. Thus the Circle moves (one square diagonally), and Triangle (strictly two cells in ortogonali) and Square (strictly three cells in ortogonali). Another possibility is the "jump" shape to the target cell, like the Knight in Chess. So can move a Triangle or Square. Any move should only be performed on an empty cell.
The unique shape is a Pyramid. Actually it is not a figure and set of figures. Each figure in the set (Circle, Triangle or Square) allows the Pyramid to perform the correct type of stroke. The figure above shows the possible moves of the Pyramid in the "maximum configuration". As you can guess, by the end of the game, "completeness" can be strongly disturbed (by the way, the Pyramid of Rithmomachia is the only figure that can "kill").

I will concentrate on ways of "killing". In Rithmomachia four of them:

the

    Capture by Siege

    Capture by Equality

    Capture by Ambush

    Capture by Eruption




The most radical is taking shape "in a siege". The figure will be charged, if after the next turn it will be blocked for all diagonal or orthogonal directions. If the figure is located at the edge of the Board or in the corner block will have fewer directions. This is the simplest (but not only) way to get the Pyramid all at once — entirely. Taking the "siege" is the only method that does not use the numerical values of the shapes.

Another way is to take the figures with the same numeric value. If, after performing a stroke on the field, where following its course could move the figure (if that field was empty, of course) is the figure of the enemy, with the same numeric value, it will be taken. It should be noted that this method of combat can be unbalanced. So (in the image above), after white move, a Circle with a numeric value of 16, can take black Triangle with the same value, but a Triangle on your course, can not do this, because it goes to other cells. At the same time, white and black triangles with numerical values 25 beat each other symmetrically (that is what the figure will be withdrawn — is determined by the next move).

An improved version of the previous one is the following method. This time, the "ambush" attack the two figures. If the sum, difference, product or quotient of their numerical values coincide with the numerical value in the figure of the enemy — the figure is removed. This is the most common combat ability of the players in the game, but to see all these threats in a less difficult position, may not be quite simple.

The latter method allows you to beat the figure in the far distance. If the result works or private numeric values of the shape and distance of the opponent's pieces (orthogonal) coincides with the numerical value of the opponent's pieces — the figure is removed. Other shapes are located in the direction of the battle, don't let the threat. When calculating the distance, takes into account the start and end positions. It is a symmetrical way of the fight (since it does not depends on the rules of moving the pieces). The next move determines which of the shapes will be removed.

It remains to tell how these rules apply to the Pyramids. This simple — in any calculations to capture the shapes, the Pyramid can act either as a separate figure (its numerical value equals the sum of the numeric values of all its components), or as any of its parts. Similarly, the Pyramid can be taken as a whole (its total value) and parts (vulnerable each of its components separately). Subject to the rules of displacement of the Pyramid, which I mentioned above, this makes the Pyramid the strongest (and most vulnerable) figure.



The initial arrangement of the figures tied to another important feature of the game. Although the set of shapes are the same, the numerical values differ. Also, various "equipment" pyramids (shown to the side of the Board, for each of the players). This makes the game asymmetric. Tactics and strategy for the black player are not suitable for white (and Vice versa). It makes the game more interesting.

a Glorious victory


The rules described above is sufficient to start playing Rithmomachia, but if the aim of the game was a simple capture all enemy pieces, the game would not be so interesting. Yes, you can win and thus, but it is not the only (or best) way to win! I really like the game, the purpose of which is not straightforward "murder" the opponent's pieces. So in Chess, to win, not necessarily "there" all the pieces, it is enough to checkmate the King! In some embodiments, the Hasami Shogi Shogi, the aim of the game is even more unexpected (to win you must build a line of 5 chips "in a row"). Rithmomachia does not disappoint in this regard. Here is a list of ways to win in this game (in ascending order of their "slavnosti"):

the

    De Corpore ("by body"): Take a given (or larger) number of the opponent's pieces (usually 15)

    De Bonis ("by goods"): Take the opponent's pieces with the set (or more) of the total value (usually 1315 984 for white and for black)

    De Lite ("by lawsuit"): Take the opponent's pieces with a given (or larger) with a total value, provided that the number of digits of the captured pieces do not exceed specified

    Honore De ("by honour"): Take the opponent's pieces with a given (or larger) with a total value, provided that the number of captured pieces do not exceed specified

    De Honore Liteque ("by honour and lawsuit"): Take the opponent's pieces with a given (or larger) with a total value, provided that the number of captured pieces and does not exceed the specified number of digits of the captured pieces do not exceed specified

    Victoria Magna ("great victory"): Place three shapes (in enemy territory) in an arithmetic progression

    Victoria Major ("greater victory"): to Arrange the four shapes (in enemy territory) so that they had two (but no more) groups of three figures, placed in different types of progression (arithmetic, geometric or harmonic)

    Victoria Excellentissima ("most excellent victory"): to Arrange (in enemy territory) four pieces so that there were all three types of progression


Here one can distinguish two fundamentally different kinds of goals of the game. Common Victories associated with the capture of the opponent's pieces (with the possible limitation of the number of captured pieces, to protect from aggressive play). Proper Victories are considered more worthy end and connected to the re-establishment of a certain "harmony" in enemy territory (which does not exclude the possibility of the battle of the opponent's pieces).



The examples above illustrate that "harmony" can (and should) engage the opponent's pieces. In the first case, constructed an arithmetic progression (16, 36, 56). The second example combines geometric (4, 12, 36) and harmonic (4, 6, 12) progression. In the third case, there are all three types of progression (you can find them). In case there are difficulties with the oral account, in the table all Rithmomachia reseni (however, people who have problems with oral account, Rithmomachia unlikely to be interested).

Possible options


In its heyday, Rithmomachia already has undergone many changes. The subsequent reconstruction has not improved the situation. There are many discrepancies in the descriptions of the rules of this game. Some sources give alternate options for initial placement of the pieces (I even come across the option that describes the game on Board 8 x 14):



There are options with simplified rules of moving the pieces. According to these rules, the pieces move in a straight line (orthogonally and diagonals) for the specified number of cells. Any piece that is on the way, stops moving. Jumping, like the Knight in Chess, are missing. The pyramid, as usual, combines the moves present in its set of figures.


In addition, there is the option to normal rules of piece movement, which adds a special course of the Pyramid on 3 cells diagonally. Such a move is possible provided that it is not accepted by any one of the figures, originally part of the Pyramid. With the preservation of the initial set of shapes of a Pyramid is related another option. It is possible to use the total value of the Pyramid, only on the condition that none of its figures have not yet been "eaten". There are more simple variants, in which the Pyramid is removed completely if attacked by any of its components.

Part of the options related to changes in regulations taking shapes. Thus, in one embodiment, to capture the shape of "by Siege" (the siege), you must block all directions of its "natural" movement. While not necessary to place your shapes close to locked (the examples below illustrate the concept). It's a pretty interesting rule.



There is a variant in which the capture "by Sam" (ambush) is like the games "clamp" type (in this case, the rules for the movement of the shapes are ignored):



There are a large number of discrepancies in the definitions of "Glorious Victories". Often, conditions such victories included the preliminary destruction of the Pyramid of the enemy. Also, there is a condition for finishing the game limited to the taking of the Pyramid. Variations of this game a lot. Familiarization with the nuances of the rules, before the game, in any case, is not excessive.

details for the curious


Implementation of the game is naturally divided into several stages. The easiest way was to implement the movement of figures. With that I started. Here is the movement of the Squares:

move the Squares
: leap-n ( 'leap-dir 'shift-dir count ? -- )
IF
BEGIN
OVER EXECUTE IF
on-board? IF
1 - DUP 0> IF
FALSE
ELSE
2DROP TRUE TRUE
ENDIF
ELSE
2DROP FALSE TRUE
ENDIF
ELSE
2DROP FALSE TRUE
ENDIF
UNTIL
IF
EXECUTE IF
on-board? empty? AND IF
from
here the DUP last-position !
move
capture-all
add-move
ENDIF
ENDIF
ELSE
DROP
ENDIF
ELSE
2DROP DROP
ENDIF
;

: shift-n ( 'shift-dir count ? -- )
IF
BEGIN
OVER EXECUTE IF
on-board? empty? AND IF
1 - DUP 0> IF
FALSE
ELSE
2DROP TRUE TRUE
ENDIF
ELSE
2DROP FALSE TRUE
ENDIF
ELSE
2DROP FALSE TRUE
ENDIF
UNTIL
IF
from
here the DUP last-position !
move
capture-all
add-move
ENDIF
ELSE
2DROP
ENDIF
;

: s-move-n ( -- ) ['] North 3 TRUE shift-n ;
: s-move-s ( -- ) ['] South 3 TRUE shift-n ;
: s-move-w ( -- ) ['] West 3 TRUE shift-n ;
: s-move-e ( -- ) ['] East 3 TRUE shift-n ;

: s-move-nw ( -- ) ['] Northwest to ['] North 2 TRUE leap-n ;
: s-move-ne ( -- ) ['] Northeast ['] North 2 TRUE leap-n ;
: s-move-sw ( -- ) ['] Southwest ['] South 2 TRUE leap-n ;
: s-move-se ( -- ) ['] Southeast ['] South 2 TRUE leap-n ;
: s-move-wn ( -- ) ['] Northwest to ['] West 2 TRUE leap-n ;
: s-move-ws ( -- ) ['] Southwest ['] West 2 TRUE leap-n ;
: s-move-en ( -- ) ['] Northeast ['] East 2 TRUE leap-n ;
: s-move-es ( -- ) ['] Southeast ['] East 2 TRUE leap-n ;

{moves s-moves
{move} s-move-n
{move} s-move-s
{move} s-move-w
{move} s-move-e
{move} s-move-nw
{move} s-move-ne
{move} s-move-sw
{move} s-move-se
{move} s-move-wn
{move} s-move-ws
{move} s-move-en
{move} s-move-es
moves}


Some difficulty arose with the Pyramids, because their set of moves is determined by what figures are in them at the moment. Had to describe to them all the possible moves, and the move in progress, check the set the shape:

Moving Pyramids
: is-correct-type? ( piece-type -- ? )
not-empty? IF
piece-type PYRAMID > IF
here SWAP a1 to
BEGIN
friend-p IF
DUP is-piece-type? IF
DROP TRUE TRUE
ELSE
FALSE
ENDIF
ELSE
DROP FALSE TRUE
ENDIF
UNTIL
SWAP to
ELSE
DROP FALSE
ENDIF
ELSE
DROP FALSE
ENDIF
;

: pr-move-ne ( -- ) ['] Northeast ROUND is-correct-type? leap-0 ;
: pr-move-se ( -- ) ['] ROUND Southeast is-correct-type? leap-0 ;
: pr-move-nw ( -- ) ['] Northwest ROUND is-correct-type? leap-0 ;
: pr-move-sw ( -- ) ['] ROUND Southwest is-correct-type? leap-0 ;

{moves p-moves
{move} pr-move-ne
{move} pr-move-se
{move} pr-move-nw
{move} pr-move-sw
...
moves}


Implementation of the battle of the figures turned this "race to the bottom". Had to implement four completely different (and rather trivial) way of taking. At the same time, I wanted to limit the number of views fields to minimize the overhead of the calculations (the calculated outrageously long). As a result, I settled on the idea of pre-filling multiple arrays, performing follow-up inspections of combat figures:
Ways to combat
MAXV [] attacking-values[]
MAXS [] current-positions[]
MAXS [] current-values[]
MAXS [] eruption-values[]

: fill-current ( pos -- )
1 current-count !
DUP 0 current-positions[] !
DUP piece-type-at PYRAMID > IF
a1 to 0
BEGIN
enemy p IF
not-empty? IF
piece piece-value
current-count @ MAXS < IF
here current-count @ current-positions[] !
DUP current-count @ current-values[] !
current-count ++
ENDIF
+
ENDIF
FALSE
ELSE
TRUE
ENDIF
UNTIL
ELSE
DUP piece-at piece-value
ENDIF
0 current-values[] !
to
;

: get-eruption-values ( n -- )
0 sum-value !
PYRAMID is-piece-type? IF
here a1 to
BEGIN
friend-p IF
not-empty? eruption-count @ MAXE < AND IF
OVER piece piece-value 
DUP sum-value @ + sum-value !
*
eruption-count @ eruption-values[] !
eruption-count ++
ENDIF 
FALSE
ELSE
TRUE
ENDIF
UNTIL
to
sum-value @
ELSE
piece piece-value
ENDIF
eruption-count @ MAXE < IF
*
eruption-count @ eruption-values[] !
eruption-count ++
ELSE
2DROP
ENDIF
;

: get-attacking-values ( piece-type -- )
0 sum-value !
Sum of FALSE-flag !
PYRAMID is-piece-type? IF
here a1 to
BEGIN
friend-p IF
not-empty? attacking-count @ MAXV < AND IF
piece piece-value
sum-value @ + sum-value !
OVER is-piece-type? IF
TRUE sum-flag !
piece piece-value
attacking-count @ attacking-values[] !
attacking-count ++
ELSE
ENDIF
ENDIF 
FALSE
ELSE
TRUE
ENDIF
UNTIL
to DROP
sum-flag @ attacking-count @ MAXV < AND IF
sum-value @
attacking-count @ attacking-values[] !
attacking-count ++
ENDIF
ELSE
is-piece-type? attacking-count @ MAXV < AND IF
piece piece-value
attacking-count @ attacking-values[] !
attacking-count ++
ENDIF
ENDIF
;

check-siege-od ( 'dir -- )
EXECUTE IF
the predict-move
on-board? NOT friend? OR IF
siege-counter --
ENDIF
on-board? friend? AND IF
2 get-eruption-values
ENDIF
to
ELSE
siege-counter --
ENDIF
;

check-siege-dd ( 'dir -- )
EXECUTE IF
the predict-move
on-board? NOT friend? OR IF
siege-counter --
ENDIF
on-board? friend? AND IF
ROUND get-attacking-values
ROUND check-equality-piece
ENDIF
to
ELSE
siege-counter --
ENDIF
;

check-siege ( pos -- )
4 siege-counter !
To DUP ['] North check-siege-od
To DUP ['] South check-siege-od
To DUP ['] West check-siege-od
To DUP ['] East check-siege-od
siege-counter @ 0= IF
TRUE is-captured? !
ENDIF
4 siege-counter !
To DUP ['] Northeast check-siege-dd
To DUP ['] Southeast check-siege-dd
To DUP ['] Northwest check-siege-dd
To DUP ['] Southwest check-siege-dd
siege-counter @ 0= IF
TRUE is-captured? !
ENDIF
to
;

check-equality-dd ( 'second-dir count 'first-dir -- )
EXECUTE on-board? AND IF
BEGIN
1 - DUP 0< IF
TRUE 
ELSE
OVER EXECUTE on-board? AND IF
the predict-move
friend? IF
OVER count-to-piece-type
DUP get-attacking-values
check for equality-piece
ENDIF
to
FALSE
ELSE
TRUE
ENDIF
ENDIF
UNTIL
2DROP
ELSE
2DROP
ENDIF
;

check-equality-od ( 'second-dir count 'first-dir -- )
EXECUTE on-board? AND empty? AND IF
BEGIN
1 - DUP 0< IF
TRUE 
ELSE
OVER EXECUTE on-board? AND IF
the predict-move
friend? IF
OVER count-to-factor get-eruption-values
OVER count-to-piece-type
DUP get-attacking-values
check for equality-piece
TRUE
ELSE
not-empty?
ENDIF
SWAP to
ELSE
TRUE
ENDIF
ENDIF
UNTIL
2DROP
ELSE
2DROP
ENDIF
;

check-equality ( pos -- )
To DUP ['] North 2 ['] North check-equality-od
To DUP ['] North 2 ['] Northwest check-equality-dd
To DUP ['] North 2 ['] Northeast check-equality-dd
To DUP ['] South 2 ['] South check-equality-od
To DUP ['] South 2 ['] Southwest check-equality-dd
To DUP ['] South 2 ['] Southeast check-equality-dd
To DUP ['] West 2 ['] West check-equality-od
To DUP ['] West 2 ['] Northwest check-equality-dd
To DUP ['] West 2 ['] Southwest check-equality-dd
To DUP ['] East 2 ['] East check-equality-od
To DUP ['] East 2 ['] Northeast check-equality-dd
To DUP ['] East 2 ['] Southeast check-equality-dd
to
;

check-ambush-prod ( value -- ? )
value-1 @ value 2 @ * OVER = IF
DROP TRUE
ELSE
DUP value-1 @ * value-2 @ = IF
DROP TRUE
ELSE
value-2 @ * value-1 @ = IF
TRUE
ELSE
FALSE
ENDIF
ENDIF
ENDIF
;

check-build-cond ( value -- ? )
value-1 @ value 2 @ + OVER = IF
DROP TRUE
ELSE
DUP value-1 @ + value-2 @ = IF
DROP TRUE
ELSE
DUP value-2 @ + value-1 @ = IF
DROP TRUE
ELSE
check-ambush-prod
ENDIF
ENDIF
ENDIF
;

check-ambush-pair ( -- )
current-count @
BEGIN
1-
DUP current-positions[] @ 0 < NOT IF
DUP current-values[] @ check-ambush-cond IF
DUP 0> IF
DUP current-positions[] @ 
DUP enemy-at? IF
DUP ChangePieces
capture-at
ELSE
DROP
ENDIF
-1 OVER current-positions[] !
ELSE
TRUE is-captured? !
ENDIF
ENDIF
ENDIF
DUP 0> NOT
UNTIL
DROP
;

check-ambush ( -- )
attacking-count @
BEGIN
1-
attacking-count @
BEGIN
1-
2DUP < IF
2DUP 
attacking-values[] @ value 1 !
attacking-values[] @ value 2 !
check-ambush-pair
ENDIF
DUP 0> NOT
UNTIL
DROP
DUP 0> NOT
UNTIL
DROP
;

: fill-eruption-values ( 'dir pos n -- )
value-1 ! to 1
BEGIN
1+ OVER EXECUTE IF
the predict-move
OVER value-1 @ > on-board? friend? AND AND IF
OVER get-eruption-values
ENDIF
to
FALSE
ELSE
TRUE
ENDIF
UNTIL
2DROP
;

check-eruption-pair ( -- )
current-count @
BEGIN
1-
DUP current-positions[] @ 0 < NOT IF
DUP current-values[] @ value 1 @ = IF
DUP 0> IF
DUP current-positions[] @ 
DUP enemy-at? IF
DUP ChangePieces
capture-at
ELSE
DROP
ENDIF
-1 OVER current-positions[] !
ELSE
TRUE is-captured? !
ENDIF
ENDIF
ENDIF
DUP 0> NOT
UNTIL
DROP
;

check-eruption-values ( -- )
eruption-count @
BEGIN
1-
DUP eruption-values[] @ value 1 !
check-eruption-pair
DUP 0> NOT
UNTIL
DROP
;

check-eruption ( pos -- )
['] OVER 4 North fill-eruption-values
['] South OVER 4 fill-eruption-values
['] West OVER 4 fill-eruption-values
['] East OVER 4 fill-eruption-values
to
check-eruption-values
;

: capture-all ( -- )
here ROWS COLS *
BEGIN
1-
DUP on-board-at? OVER enemy-at? AND IF
0 attacking-count !
0 eruption-count !
FALSE is-captured? !
DUP fill-current
DUP check-siege
is-captured? @ NOT IF
DUP check-equality
ENDIF
is-captured? @ NOT IF
check-ambush
ENDIF
is-captured? @ NOT IF

ENDIF
is-captured? @ IF
capture-piece
ENDIF
ENDIF
DUP 0> NOT
UNTIL
DROP to
;


Taking the figures in the Pyramid, as the movement had to be processed in a special way:

Taking shapes
: capture-piece ( -- )
current-count @
BEGIN
1 - DUP 0> IF
DUP current-positions[] @
DUP 0 < NOT IF
DUP enemy-at? IF
DUP ChangePieces
capture-at
ELSE
DROP
ENDIF
ELSE
DROP
ENDIF
FALSE
ELSE
DUP current-positions[] @
DUP enemy-at? IF
DUP ChangePieces
capture-at
ELSE
DROP
ENDIF
TRUE
ENDIF
UNTIL
DROP
;


Already in the process of debugging, I realized that all checks are performed at the time to run the course. Had to write a little function that simulates the movement of a piece (not quite a full recalculation of the positions on the Board, but I managed to do a little blood):

Change position
: predict-move ( -- pos )
here 
From DUP = IF
last-position @ to
ELSE
DUP last-position @ = IF
from to
ENDIF
ENDIF
;


Amid all these horrors, the test conditions for the completion of the game seemed trivial. Not without a small amount of magic Axiom, but there's nothing I'd be afraid to show your parents:

Test complete
15 CONSTANT WINC
1315 CONSTANT WINW
984 CONSTANT WINB

: WhitePieces++ ( -- ) WhitePieces ++ ;
: BlackPieces++ ( -- ) BlackPieces ++ ;
: WhiteValues++ ( -- ) WhiteValues ++ ;
: BlackValues++ ( -- ) BlackValues ++ ;

: ChangePieces ( pos -- )
DUP piece-at piece-value SWAP
player at White = IF
COMPILE WhitePieces++
BEGIN
1-
COMPILE WhiteValues++
DUP 0> NOT
UNTIL
DROP
ELSE
COMPILE BlackPieces++
BEGIN
1-
COMPILE BlackValues++
DUP 0> NOT
UNTIL
DROP
ENDIF
;

: OnIsGameOver ( -- gameResult )
#UnknownScore
current-player White = IF
WhitePieces @ WINC >= IF
DROP
#LossScore
ENDIF
WhiteValues @ WINW >= IF
DROP
#LossScore
ENDIF
ENDIF
current-player Black = IF
BlackPieces @ WINC >= IF
DROP
#LossScore
ENDIF
BlackValues @ WINB >= IF
DROP
#LossScore
ENDIF
ENDIF
;


From this point, the program could already play (though doing it rather passively). The fact is that, in the absence of the evaluation function (and a custom implementation of AI), Axiom tries to perform an exhaustive search up to a terminal position. It is clear that the end of the party is far beyond the horizon of the possible depths of the bust, as a result, the found moves are not very meaningful. In General, it remains to add AI teeth:

Evaluation function
: OnEvaluate ( -- score )
current-player material-balance
;


Here we have used a very handy feature of material balance (Axiom) using weights defined shapes (the same values used for implementations of the rules of Rithmomachia):

Description of figures
{pieces
{piece} R0 {moves} r-moves 0 {value}
{piece} R1 {moves} r-moves 1 {value}
{piece} R2 {moves} r-2 moves {value}
{piece} R3 {moves} r-3 moves {value}
{piece} R4 {moves} r-moves 4 {value}
{piece} R5 {moves} r-moves 5 {value}
{piece} R6 {moves} r-moves 6 {value}
{piece} R7 {moves} r-7 moves {value}
{piece} R8 {moves} r-moves 8 {value}
{piece} R9 {moves} r-moves 9 {value}
{piece} R16 {moves} r-moves 16 {value}
{piece} R25 {moves} r-moves 25 {value}
{piece} R36 {moves} r-moves 36 {value}
{piece} R49 {moves} r-moves 49 {value}
{piece} R64 {moves} r-moves 64 {value}
{piece} R81 {moves} r-moves 81 {value}
{piece} T0 {moves} t-moves 0 {value}
{piece} T6 {moves} t-moves 6 {value}
{piece} T9 {moves} t-moves 9 {value}
{piece} T12 {moves} t-moves 12 {value}
{piece} T16 {moves} t-moves 16 {value}
{piece} T20 {moves} t-moves 20 {value}
{piece} T25 {moves} t-moves 25 {value}
{piece} T30 {moves} t-moves 30 {value}
{piece} T36 {moves} t-moves 36 {value}
{piece} T42 {moves} t-moves 42 {value}
{piece} T49 {moves} t-moves 49 {value}
{piece} T56 {moves} t-moves 56 {value}
{piece} T64 {moves} t-moves 64 {value}
{piece} T72 {moves} t-72 moves {value}
{piece} T81 {moves} t-moves 81 {value}
{piece} T90 {moves} t-90 moves {value}
{piece} T100 {moves} t-100 moves {value}
{piece} S0 {moves} s-moves 0 {value}
{piece} S15 {moves} s-moves 15 {value}
{piece} S25 {moves} s-moves 25 {value}
{piece} S28 {moves} s-moves 28 {value}
{piece} S36 {moves} s-moves 36 {value}
{piece} S45 {moves} s-moves 45 {value}
{piece} S49 {moves} s-moves 49 {value}
{piece} S64 {moves} s-moves 64 {value}
{piece} S66 {moves} s-moves 66 {value}
{piece} S81 {moves} s-moves 81 {value}
{piece} S120 {moves} s-moves 120 {value}
{piece} S121 {moves} s-moves 121 {value}
{piece} S153 {moves} s-moves 153 {value}
{piece} S169 {moves} s-moves 169 {value}
{piece} S225 {moves} s-moves 225 {value}
{piece} S289 {moves} s-moves 289 {value}
{piece} S361 {moves} s-moves 361 {value}
{piece} P0 {moves} p-moves 0 {value}
{piece} P91 {moves} p-moves 91 {value}
{piece} clearcoat p190 {moves} p-moves 190 {value}
pieces}


This implementation is missing many things (e.g. check the completion of the game by Glorious Victories). I will try to add the missing functionality in the future. The latest source can always be seen here.

What?


Rithmomachia interested me in the first place, its complexity. Of course, there was no thought put into ZRF. I had to learn Axiom for this! Currently, there is a simple realizacjathat do not support Glorious Victories. Also, there is no firm confidence that I found all the bugs in the code (1000 lines per ForthScript — this is serious). This is a beta version, but, overall, it works:



You may notice that the game ends very quickly. It is really so. If both players play aggressively, under the terms Common Victories (and without limitation on the number of selected figures), the average duration of the party is ~10 turns. In this case, the first player has a significant advantage:

the
Cumulative results the following game 13 of 100:
Player 1 "Eval", wins = 13.
Player 2 "Eval", wins = 0.
Draws = 0

It's funny that only aggressive if one of the players, the party is delayed up to more than 300 moves (aggressive player almost always wins).

the
Cumulative results the following game 22 of 100:
Player 1 "Rithmomachy", wins = 1.
Player 2 "Eval", wins = 21.
Draws = 0

The man with the computer to play hard. Even illuminated figures under the battle, it's sometimes hard to figure out what kind of figure should make a move to execute a capture (in this case, it is desirable also not to substitute its own figures). Nowadays, this game is unlikely to be popular, but she did not take. She's developing mental calculation skills.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Integration of PostgreSQL with MS SQL Server for those who want faster and deeper

Custom database queries in MODx Revolution

Google Web Mercator: a mixed coordinate system