Paul Shields W4701 – Artificial Intelligence

Assignment 3

Introduction

This assignment created an intelligent Italian Checker playing agent called Saltare.   Italian Checkers is played on the black squares of an 8 by 8 checkerboard. The board oriented so a black square is in the bottom right hand corner.  It is similar to American Checkers with the addition of a complicated hierarchy of capture precedence.  The assignment was to create an agent which correctly interpreted and played to the rules.  It was also to play in a way that would try and win.  In this regard Saltare was successful, playing at about a ‘B’ level based on the Chungkuo site evaluation (http://www.chungkuo.org/checkerprograms.html), ahead of many commercial programs.  Given the relatively short amount of time for the assignment there are many optimizations not implemented and I focused on ‘time to implement’ verses playing strength for the optimizations included.

This write-up is divided into 5 main sections as follows

Saltare is written using Delphi 7 which is based on the Pascal programming language.  Pascal already has high readability but this is enhanced by using indentation, long variable names and the frequent use of comments.  All source code is included in the attached files.   

The Checkerboard (www.fierz.ch/checkers.htm) interface was chosen as a front-end for Sattare.  This has the dual advantage of having an easy to use test-bed and the ability to test the software against other programs and people.  I also implemented another test-bed for testing a variety of the features rather than just playing a game.  

Email address for contact:  paul.shields@sportscoach.com.au

User Interface and Source Code

The Checkerboard interface was chosen as the main interaction with Saltare.  Checkerboard, written by Martin Fierz, is described by him as follows

 CheckerBoard is an interface to a checkers engine. CheckerBoard allows you to load and save games in the standard PDN format, to set up and search for positions in a PDN database, and to replay games. You can also save games as HTML to publish your favorite games on the internet. CheckerBoard itself cannot play checkers; for this it uses a so-called checkers engine. CheckerBoard communicates with the engine and tells it to think about a move.”

 The communication is via functions exported from a Dll’s.  These are defined (in C) as follows

Partial documentation can be found on Martin’s site (www.fierz.ch/checkers.htm).  The initial part of the assignment focused on interfacing the Delphi code to the C API ’s defined by checkerboard.  This is more than was required by the assignment (which only required outputting a move) however it enabled easy testing and increased the versatility of the finished program.

It also allowed automated testing of the program as Checkerboard includes an Italian Checkers game playing agent called ‘Dama’.   Dama is based on SimpleTech which is rated at ‘B’ level on the Chungkuo Site.  Saltare and Dama played many matches together with Dama having the most wins but Saltare also won many times.

The source code can be found in attached 5 files

Total lines of code is just over 2200 is about the same as SimpleTech which is written in C.  My move generation routines are coded more compactly than SimpleTech but the other aspects are slightly larger.

Move Generation

Generation of legal moves is a critical and complex part of a checkers program.  This section needs to be fast as it will be performed extensively in the dynamic search and also has to be correct.  This is made more difficult by the precedence hierarchy required of Italian Checkers.  Significant time was spent in this part of the assignment both optimizing the code and making sure the moves generated were both complete and correct.  

A set of four 32 bit integers was used as the board representation.  This enabled relatively fast shifting and logical comparison operators to be used in move generation rather than additions and multiplications for an array based approach.  The structure was defined in Delphi as follows:

  BoardBits = record

      whitemen : cardinal;           {bit array of 32 values 8x4 board  }

      blackmen : cardinal;           {bit array of 32 values 8x4 board  }

      whitekings : cardinal;

      blackkings : cardinal;

  end;  {Boardbits}

Within each of the integers a 1 indicated the presence of the piece.  The numbering scheme was the standard Italian checkers scheme with the least significant bit representing the 1 square in the bottom right hand corner of the black side as follows.

                           (White)

             32      31      30      29

                  28      27      26       25

             24      23      22      21

                  20      19      18       17

             16      15      14      13

                  12      11      10        9

             8         7        6        5

                   4        3        2         1

                           (Black)

It is possible to use more compact bit mapped representations.  For example a 3 integer representation could be as follows.  There would be an integer for black, an integer for white and an integer to represent the kings.  Access could be achieved using

     Empty := not (Black or White);

     Whiteman := White and not Kings

     Blackman := Black and not Kings

     Whiteking := White and Kings

     Blackking := Black and Kings

I elected to use the 4 integer representation as storage was less of an issue than speed and the piece access functions added some overhead.

A move was stored in a simple structure that was flexible enough to handle jump sequences and simple moves.  It was defined as follows:

//    Details for a jump

  jump = record

       two: Integer;               //  intermediate path coordinates of the moving piece

       delpiece : Integer;      //  what is deleted

       delpos : integer;         // squares whose pieces are deleted after the move

  end; {jump}

 

//      The Move record

  move = record

      two : integer;               //  where we move to

      from : integer;             //  where we come from

      jumplist : array[1..12] of jump;

      parts : integer;             // how many jumps are there in this move?  

      oldpiece : integer;       // what disappears on from

      newpiece : integer;     //what type of piece appears on to

  end;  {move }

Move Generation was divided into simple moves and jump moves.  Jump moves were checked first and if there were none then simple move checking continued.  Both simple moves and jumps had two main sections.  Firstly possible moves where created by shifting and bit matching operations and then these possible moves were expanded to create the full move if viable.  The full code is out lined in the Moves.pas file however here are brief descriptions of each process

Moves

The possible move section operated by checking to see if squares in front of a piece were free, and in the case of a king behind it as well.  Here is some sample code for white to give a flavour for this.

 

PotentialMoves4 := (not Occupied) and (OccupiedWhite shr 4);

PotentialMoves3 := (not Occupied) and ((OddRows and OccupiedWhite and not Edges) shr 3);

PotentialMoves5 := (not Occupied) and ((EvenRows and OccupiedWhite and not Edges) shr 5);

 

Here the potential moves for a piece that can move 3, 4, or 5 places ahead are checked. 

Once potential moves are developed each of these is expanded to full move and the move structure is filled in.

Jumps

This were created in a similar way to moves although the possible jumps were +-7 or +-9 away from a current piece.  The square in front was checked to ensure a piece of the opposite colour was present and the next square was vacant.  Example code (partial) for this is as follows:

InFront4 := (OccupiedWhite and (OccupiedBlack shl 4)) shr 4;

if InFront4 <> 0 then

InFront4AK := InFront4 and not ((Posn.whitekings and (TheBlackMen shl 4)) shr 4)

else InFront4AK := 0;

……..

PotentialMoves7 := (not Occupied) and (((InFront3AK or (InFront4AK and OddRows)) and not RightEdge) shl 7);

This code looks to see if the squares immediately in front have a piece of the opposite colour, then checks to make sure it is not a king (AK) if you are a man and finally looks to see if the next square out is vacant.

Once a jump is confirmed a move structure is created for it and a depth first search is initiated to see how long the jump sequence lasts.  If there are choices of pieces to jump then a duplicate move structure is created and both branches are explored until there are no more jumps.

Although all pieces on the board are passed to the search only the jump to expand is passed to the possible move generator.  This limits the time spent exploring non valid sequences. Also any man jump which lands on the far edge of the board is terminated and a king replaces the man.

Finally if there are multiple jumps the jump list is passed to the Italian Checkers jump validation routine.  This routine checks the following conditions in order of precedence.

  1. Check for the move with the most captures

  2. Capture with a king in preference

  3. Capture the most kings

  4. Capture any kings first

Jumps are quite a complex part of the Italian Checkers game so some time was spent making sure this was correct using an external test-bed.

The move generation routines are split and called only if required.  The ‘AnyMoves’ and ‘AnyJumps’ functions are used in quiescence checking and testing for a loss as well as in move generation.  Simple moves are only checked for if there are no jumps.

Saltare maintains a copy of the progress of the game internally via an array of board positions.  Checkerboard does this as well, however it is needed to test for a draw.  If a position is repeated three times then a draw is signaled.  A loss is signaled if no moves are available or there are no pieces of the playing colour.  Checkerboard has some problems with the handling of the win/loss and draw conditions so although these are detected and signaled correctly by Saltare checkerboard often keeps playing.

Dynamic Evaluation

This is where possible moves and counter moves are explored as far into the future as possible.  The NegMax (Knuth) variant of the alpha-beta MiniMax search algorithm is used for dynamic evaluation.  The code is based on the corrected version of the partial code provided in class.  The NegMax algorithm reverses the sign of the evaluation at each alternate depth.  It does this by multiplying it by -1.  It is sensitive to the initial start depth and the evaluation function is inverted for each odd start depth.

The NegMax variant provides quite compact fast code and so was chosen in preference the standard and/or minimization and maximization approach which must have separate code for each ply. It can be a little tricky to get the signs correct and on occasions, during testing, it was interesting to see Saltare choose the worst possible move!

Alpha Beta cutoffs are used to decrease the number of nodes searched.  This adaptation is sensitive to the order of node expansion but can potentially cutoff large sections of the search space. 

Optimizations can be divided into two broad classes.  Firstly ideas to increase the performance of the alpha-beta cutoffs and secondly to optimize the depth of the dynamic searching.  Looking at each of these groups in turn

Alpha-Beta Cutoff Performance

Ordering of the moves and initial setting of the of the alpha-beta window were the areas considered.  Three optimizations regarding move ordering were included

·       Ordering of move generation –Where it caused no degradation in speed moves were ordered to increase the likelihood of a selected move. In practice this meant that possible king moves were placed ahead of men.

·       Sorting of moves based on 1 ply evaluation – This operation is fairly costly in terms of time as board positions needs to be developed for each move and an evaluation made of the position.  This needs to be traded off against improvement in the alpha-beta cutoffs.  This optimization provide the most pruning of the search space but the cost of doing this meant that the total time was worse than no sorting (see data below). Based on test cases run it was found that using this where there were no Killer moves available was the best approach.

·       Killer moves – Moves are that have been shown to provide alpha-beta cutoffs in one part of the tree can be used first elsewhere.  It was decided to store only a single killer to speed its inclusion at the front of the move list.  Also full sorting was available so both ends of the spectrum were available.  Details of testing various combinations of 1-ply sorting and killers are as follows.  Each run was a full width 7 ply search.

·       Optimizations not used – Several optimizations were considered and not implemented primarily due to time constraints.  These included

Depth of Dynamic Searching

There are two components to this.  Firstly how deep will you broadly search everywhere and secondly are there any areas where you might search deeper.

·       Iterative Deepening – This provided several advantages.  It enabled a good move to be available when time was up at any stage of the search and in conjunction with the hash table, was not too costly in terms of duplicate node evaluation.  It also enabled cutoffs developed in early iterations to prune the search in deeper iterations.  The trick here was to store the cutoffs in reverse depth order so they are available at the beginning of each new iteration.

·       Quiescence Depth Extension – It is inappropriate sometimes to perform a static evaluation as there may be a situation which is volatile.  An example of this is when there are jumps available.  Another situation is when a king has been just crowned. The dynamic evaluation will increase the depth by 2-ply anytime it finds a volatile position (jumps and new king) and test for quiescence again. I also tested using a 1 ply increment which looked for simple combinations but 2-ply gave the best outcome.

·       Optimizations not used – Interesting move depth extension was one area I almost implemented.  This is where the search depth is extended if an interesting line of play is being followed.  I though this would be most useful in a won end-game to help avoid the horizon effect when chasing down opposition pieces.

Dynamic search performance is critical to the success of the program.  The optimizations implemented combined with the static evaluation approach resulted in nodes being searched at a rate of up to 1 million per second and depths of up to 30 ply(quiescence extensions) reached most times in a game with my 3gHz laptop.

Static Evaluation

Static evaluation is performed at the leaf nodes of the dynamic search.  It provides an indication of how good the position is.  This valuation is what is optimized by the search process.  The evaluation here is based on the sum of weighted position and piece features.  It is based around  Martin Fierz's Simple Tech evaluation function and has been enhanced to improve performance.  A hash table has also been added to improve evaluation performance.  The evaluation is mostly performed using bit operations to improve speed.  Even the bit counting routine avoids the use of loops and just uses five bit comparisons.  A discussion of the various components is as follows

Feature Vector

The feature vector is calculated by taking into account of the following items

·       Any Action – A quick check to see if there are any moves.  If there are none then it is a loss for the side.

·       Piece Calculation – Each of the men is weighted by 100 whilst each of the kings is weighted by 170.  Kings are doubled in value if they are around in the opening and mid-game.  If the program is ahead in pieces it will also aggressively seek exchanges adding a score if the material is weighted in its favour.

Ø     300*(WhiteScore-BlackScore)/(BlackScore+WhiteScore)

·       Positional Calculations

The actual weights for these were adjusted by hand to optimize performance.  The final values can be seen in the source code file (Eval.pas). See the learning section for learning optimizations considered.

Ø     Tempo Addition for your move – a couple of evaluation points are added if it is your turn to move

Ø     Back Rank Guard – Guarding the back rank squares is relatively important and a calculation is made to keep the men on key squares for as long as possible.  Holding on to squares 4 and 29 (one inside from the left edge) are the most important and so these men will come off last.

Ø     Intact Double Corner – Keeping your double corner (4 and 7 for white) intact is useful as it avoids an easy path for a king.  There is an addition for keeping pieces in these squares

Ø     Centre Control – Control of the centre gives you more flexibility and mobility. Men in the centre adds value but kings add more.

Ø     Edge Avoidance – Just as the centre is important, keeping your pieces off the edges is critical as well

Ø     Cramp – Cramps also limit a pieces movement. Cramps on squares 17 and 16 are tested for and the evaluation adjusted.

Ø     Tempo – This is a measure of how far forward your men are.  There is an adjustment for the opening, middle game and end game.  The near end game is not adjusted.  The game type is determined by the total number of pieces on the board

§       16 Opening

§       >=12 and <=15 Mid-Game

§       >=9 and <15 Near end-game

§       < 9 End-game

Ø     Safe Edges – Some edges are safer than others.  If you are outnumbered and only have a couple of kings or less then seek sanctuary on a safe edge.

·       The Move

Some thought was given to weighting actual move as well as positional and piece information.  Not enough time was available to fully explore this concept but it would try and put value on the move being considered as well.

Hash Table

A hash table is used to quickly evaluate previously seen positions.  This table must be able to locate the move quickly and if not available spend little time searching for it.  Several different hashing algorithms were considered and a couple of hash table access mechanisms were trialed.  The results of these trials were as follows:

·       Hashing Algorithm – Seven algorithms were tested.  The test looked at a sequence of typical board positions and determined average number of probes and the length of the longest probe.  The algorithms tested came from Arash Patow’s site ((http://www.partow.net) and were as follws

Ø     RS Hash Function - A simple hash function from Robert Sedgwicks Algorithms in C book.

Ø     JS Hash Function – A bitwise hash function written by Justin Sobel

Ø     PJW Hash Function - This hash algorithm is based on work by Peter J. Weinberger of AT&T Bell Labs.

Ø     ELF Hash Function - Similar to the PJW Hash function, but tweaked for 32-bit processors.

Ø     BKDR Hash Function -  This hash function comes from Brian Kernighan and Dennis Ritchie's book "The C Programming Language".

Ø     SDBM Hash Function – This is the algorithm of choice which is used in the open source SDBM project.

Ø     DJB Hash Function – An algorithm produced by Daniel J. Bernstein and shown first to the world on the comp.lang.c newsgroup.

Ø     AP Hash Function – An algorithm produced by Arash Partow. It is a hybrid rotative and additive hash function algorithm based around four primes 3,5,7 and 11.

·       Hash Table Access – Two techniques were trialed.  Firstly a pseudo random number generator was used to drive the position in the hash table after the hash function.  The random sequence was then followed for any additional probes.  Also a simple linear probe using the modulus of the hash table size as the entry point followed by single location incremental probes.  The linear probe ended up the fastest in practice and so ended up in the final implementation.

Learning and Future Steps

At the start of the project I planned to use a back propagation neural net to learn a set of optimum features from a set of board positions from a series of expert game players.  There was not enough time to implement this so the fallback position was to tune the feature vector weights based on games played against itself and others.  There was also not enough time for this.  As a final method I hand crafted the weights based on playing various implementations of the program against itself.  Although not the best approach it did produce credible performance in the time available for the project.

Saltare plays well enough to be released to the public.   The key next steps to improve the performance would be as follows

1.     Transposition Table – Now the hashing works optimally it would be a short step to add a transposition table to the dynamic search routine.  This would store hashed moves and depth as well as the board position and playing side.  If the search routine encountered a transposed position from its current depth or higher up it would stop descending further and return with the previously evaluated score and move.  This is said to cut the nodes required to be searched by about a factor of four.

2.     Opening Book – An opening book would also be relatively simple to implement as all you need is a series of expert games and processing time.  Both of these are available and so a book could be cheaply added

3.     Endgame Database – The endgame is where Saltare needs most help and implementing a database would be useful.  I would either need to develop one or decode the Chinook one I have obtained.

Overall the assignment was great deal of fun, but I severely underestimated the amount of time that it would take to debug the program.  The algorithm implementations were mostly simple, but the debugging hard and subtle in some cases.

Playing Strength

The program plays quite good Italian Checkers and has had some wins against the Simple Tech Italian Checkers program developed by Martin Fierz.  I cannot beat the program and none of my family, but we are not particularly good checkers players.  Several of its games are provided in appendix one.  Two items seemed to significantly improve it’s playing strength.  The first was the inclusion of killer moves at the front of a node expansion.  This reduced the by about 60% the number of nodes explored for a given depth.  The second was the extension of the quiescence search out from 1-ply to 2-ply.  It would seem that this extension although reducing the overall depth of search increased it significantly down interesting lines of play.  

paul.shields@sportscoach.com.au


Appendix 1 – Sample Games

This appendix provides two example games between Dama (SimpleTech version that plays Italian Checkers) and Saltare.  In both of these games Saltare won and they provide an example of the strengths of the dynamic evaluation.  In other games that Saltare lost or were drawn it was mainly due to the greater depth full width search achieved by Dama.

 

1) A 1-second (not exact) per move game where although down on pieces the program found a winning combination from its selective deepening search.  I have included two analyses of the game.  The first is by Dama and the second by Saltare and shows that Dama searched deeper on average but less deep selectively than Saltare.

Dama (SimpleTech) – Saltare (P Shields)


1 Second Game
Result: Saltare won

Analysis by dama italiana 1.03 at 1s/move on Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz generated with CheckerBoard 1.6

 

1.

21-18

 

best:21-18 time 3.86, depth 11, value 2, nodes 1250091

 

 

10-14

best:10-14 time 2.24, depth 12, value 4, nodes 2364106

2.

25-21

 

best:25-21 time 1.08, depth 11, value 4, nodes 445471

 

 

5-10

best: 5-10 time 1.08, depth 9, value 1, nodes 137545

3.

24-20

 

best:24-20 time 2.92, depth 10, value -1, nodes 337692

 

 

1-5

best: 1- 5 time 1.94, depth 12, value 4, nodes 2045727

4.

28-24

 

best:28-24 time 1.41, depth 11, value 4, nodes 606086

 

 

12-15

best:14-19 time 1.46, depth 11, value -1, nodes 464198

5.

32-28

 

best:22-19 time 1.55, depth 10, value -2, nodes 173743

 

 

14-19

best: 8-12 time 3.86, depth 14, value 0, nodes 2380179

6.

23x14

 

 

 

 

10x19

 

7.

29-25

 

best:29-25 time 1.48, depth 12, value -7, nodes 1083980

 

 

11-14

best: 6-10 time 1.15, depth 12, value -6, nodes 765183

8.

18x11

 

best:18x11 time 1.47, depth 15, value -94, nodes 1200890

 

 

7x14

 

9.

20x11

 

 

 

 

6x15

 

10.

27-23

 

best:27-23 time 1.10, depth 11, value -94, nodes 878174

 

 

3-6

best: 3- 6 time 1.73, depth 12, value -101, nodes 1471201

11.

31-27

 

best:31-27 time 1.32, depth 12, value -103, nodes 1028959

 

 

4-7

best: 8-12 time 1.33, depth 12, value -104, nodes 760157

12.

23-20

 

best:23-20 time 2.32, depth 13, value -119, nodes 1731038

 

 

6-11

best: 6-11 time 2.82, depth 13, value -119, nodes 2163481

13.

27-23

 

best:27-23 time 1.01, depth 13, value -120, nodes 1097595

 

 

8-12

best: 8-12 time 1.23, depth 14, value -122, nodes 1362728

14.

20-16

 

best:20-16 time 1.35, depth 14, value -125, nodes 621563

 

 

2-6

best: 2- 6 time 2.31, depth 16, value -192, nodes 1744713

15.

21-18

 

best:21-18 time 1.15, depth 15, value -192, nodes 911745

 

 

14x21

 

16.

25x18

 

best:25x18 time 1.59, depth 16, value -194, nodes 2015386

 

 

6-10

best: 6-10 time 1.93, depth 16, value -195, nodes 1304999

17.

23x14

 

 

 

 

10x19

 

18.

30-27

 

best:30-27 time 1.24, depth 15, value -195, nodes 985730

 

 

5-10

best: 5-10 time 1.55, depth 16, value -203, nodes 1598827

19.

18-14

 

best:18-14 time 2.28, depth 16, value -251, nodes 2093127

 

 

11x18

 

20.

22x6

 

 

 

 

9-13

best: 9-13 time 1.48, depth 14, value -251, nodes 2111761

21.

27-23

 

best:27-23 time 2.24, depth 14, value -268, nodes 3215107

 

 

19-22

best:19-22 time 1.53, depth 14, value -274, nodes 2258647

22.

26x19

 

 

 

 

15x22

 

23.

24-20

 

best: 6- 2 time 2.09, depth 12, value -269, nodes 3118796

 

 

13-18

best:22-27 time 1.43, depth 12, value -269, nodes 2088462

24.

6-3

 

best: 6- 3 time 1.24, depth 12, value -280, nodes 1748355

 

 

22-27

best:18-21 time 1.53, depth 12, value -330, nodes 2114286

25.

23-19

 

best:23-19 time 2.71, depth 13, value -333, nodes 5219949

 

 

27-31

best:18-22 time 1.27, depth 12, value -333, nodes 2629493

26.

19-15

 

best:19-15 time 1.00, depth 14, value -432, nodes 2052198

 

 

12x19

forced move

27.

3x12

 

 

 

 

31x8

 

28.

16-12

 

 

 

 

8x15

 

 

 


Dama (SimpleTech) – Saltare (P Shields)


1 Second Game
Result: Saltare won

Analysis by Saltare 1.00 (P Shields - Italian Checkers Project) at 1s/move on Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz generated with CheckerBoard 1.6

 

1.

21-18

 

Saltare: Best: 23-19, Time: 1.14s, Depth: 6(29), Score: 1, Nodes: 150557

 

 

10-14

Saltare: Best: 10-14, Time: 3.73s, Depth: 7(30), Score: 4, Nodes: 514817

2.

25-21

 

Saltare: Best: 25-21, Time: 3.01s, Depth: 6(29), Score: 0, Nodes: 428711

 

 

5-10

Saltare: Best: 5-10, Time: 1.34s, Depth: 5(28), Score: 4, Nodes: 173325

3.

24-20

 

Saltare: Best: 22-19, Time: 5.12s, Depth: 6(29), Score: -1, Nodes: 777421

 

 

1-5

Saltare: Best: 12-15, Time: 1.19s, Depth: 5(28), Score: 12, Nodes: 185682

4.

28-24

 

Saltare: Best: 20-15, Time: 1.59s, Depth: 5(28), Score: -5, Nodes: 284260

 

 

12-15

Saltare: Best: 12-15, Time: 1.53s, Depth: 5(28), Score: 9, Nodes: 246916

5.

32-28

 

Saltare: Best: 22-19, Time: 1.66s, Depth: 5(26), Score: 3, Nodes: 297203

 

 

14-19

Saltare: Best: 8-12, Time: 1.26s, Depth: 5(28), Score: 30, Nodes: 175297

6.

23x14

 

 

 

 

10x19

 

7.

29-25

 

Saltare: Best: 29-25, Time: 1.82s, Depth: 6(27), Score: -16, Nodes: 316488

 

 

11-14

Saltare: Best: 11-14, Time: 1.73s, Depth: 5(26), Score: 20, Nodes: 288973

8.

18x11

 

Saltare: Best: 18-11, Time: 1.20s, Depth: 6(23), Score: -8, Nodes: 94065

 

 

7x14

 

9.

20x11

 

 

 

 

6x15

 

10.

27-23

 

Saltare: Best: 22-18, Time: 1.87s, Depth: 4(21), Score: -8, Nodes: 234023

 

 

3-6

Saltare: Best: 3-6, Time: 1.20s, Depth: 3(20), Score: 14, Nodes: 168516

11.

31-27

 

Saltare: Best: 22-18, Time: 1.19s, Depth: 5(22), Score: 101, Nodes: 181700

 

 

4-7

Saltare: Best: 8-12, Time: 1.62s, Depth: 3(20), Score: 14, Nodes: 111684

12.

23-20

 

Saltare: Best: 22-18, Time: 1.42s, Depth: 6(23), Score: 119, Nodes: 200562

 

 

6-11

Saltare: Best: 6-11, Time: 1.98s, Depth: 7(26), Score: -114, Nodes: 296487

13.

27-23

 

Saltare: Best: 27-23, Time: 2.44s, Depth: 7(25), Score: 123, Nodes: 336143

 

 

8-12

Saltare: Best: 8-12, Time: 1.36s, Depth: 7(23), Score: -114, Nodes: 186899

14.

20-16

 

Saltare: Best: 21-18, Time: 1.08s, Depth: 7(28), Score: 123, Nodes: 113804

 

 

2-6

Saltare: Best: 2-6, Time: 1.77s, Depth: 7(27), Score: 4, Nodes: 266752

15.

21-18

 

Saltare: Best: 21-17, Time: 1.01s, Depth: 6(26), Score: 0, Nodes: 118627

 

 

14x21

 

16.

25x18

 

Saltare: Best: 25-18, Time: 2.27s, Depth: 9(26), Score: 121, Nodes: 266019

 

 

6-10

Saltare: Best: 6-10, Time: 3.35s, Depth: 12(29), Score: -231, Nodes: 405118

17.

23x14

 

 

 

 

10x19

 

18.

30-27

 

Saltare: Best: 30-27, Time: 1.27s, Depth: 10(24), Score: 255, Nodes: 162421

 

 

5-10

Saltare: Best: 5-10, Time: 5.56s, Depth: 10(27), Score: -289, Nodes: 632646

19.

18-14

 

Saltare: Best: 18-14, Time: 4.53s, Depth: 9(28), Score: 293, Nodes: 448123

 

 

11x18

 

20.

22x6

 

 

 

 

9-13

Saltare: Best: 9-13, Time: 1.23s, Depth: 8(23), Score: -207, Nodes: 128125

21.

27-23

 

Saltare: Best: 27-23, Time: 2.94s, Depth: 9(24), Score: 155, Nodes: 308320

 

 

19-22

Saltare: Best: 19-22, Time: 1.61s, Depth: 11(23), Score: -276, Nodes: 174780

22.

26x19

 

 

 

 

15x22

 

23.

24-20

 

Saltare: Best: 6-3, Time: 1.77s, Depth: 10(22), Score: 280, Nodes: 230561

 

 

13-18

Saltare: Best: 22-27, Time: 1.07s, Depth: 9(23), Score: -192, Nodes: 121446

24.

6-3

 

Saltare: Best: 28-24, Time: 1.00s, Depth: 9(24), Score: 284, Nodes: 135769

 

 

22-27

Saltare: Best: 22-27, Time: 2.26s, Depth: 11(21), Score: -279, Nodes: 356992

25.

23-19

 

Saltare: Best: 23-19, Time: 1.15s, Depth: 11(24), Score: 336, Nodes: 194718

 

 

27-31

Saltare: Best: 27-31, Time: 2.65s, Depth: 11(23), Score: -351, Nodes: 454105

26.

19-15

 

Saltare: Best: 28-24, Time: 1.58s, Depth: 11(24), Score: 361, Nodes: 277268

 

 

12x19

forced move

27.

3x12

 

 

 

 

31x8

 

28.

16-12

 

 

 

 

8x15

 

 


2) A 30-second (not exact) per move game where Saltare gradually improved its postion to dominate in the end game.  Again I have included two analyses of the game.  The first is by Dama and the second by Saltare and shows that Dama’s deeper but broader search was not as effective as the selective deepening of Saltare

 

Saltare (P Shields) - Dama (SimpleTech)


30 Second per Move Test Game
Result:  Saltare won

 

Analysis by dama italiana 1.03 at 30s/move on Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz generated with CheckerBoard 1.6

 

1.

23-19

 

best:23-19 time 30.57, depth 13, value 0, nodes 11724238

 

 

9-13

best: 9-13 time 37.94, depth 14, value 1, nodes 17277334

2.

28-23

 

best:21-18 time 63.61, depth 15, value 1, nodes 37563353

 

 

11-15

best:11-15 time 48.79, depth 15, value -1, nodes 35253151

3.

21-17

 

best:21-17 time 83.03, depth 16, value -17, nodes 47634793

 

 

5-9

best: 5- 9 time 63.51, depth 16, value -15, nodes 46991342

4.

25-21

 

best:25-21 time 58.11, depth 15, value -15, nodes 26838606

 

 

6-11

best: 6-11 time 33.94, depth 15, value -21, nodes 19540589

5.

21-18

 

best:21-18 time 31.74, depth 15, value -19, nodes 24173633

 

 

2-5

best: 2- 5 time 30.55, depth 16, value -17, nodes 24150665

6.

26-21

 

best:26-21 time 106.32, depth 17, value -19, nodes 60269396

 

 

11-14

best:11-14 time 39.13, depth 17, value -22, nodes 31203059

7.

18x11

 

 

 

 

7x14

 

8.

24-20

 

best:29-25 time 49.88, depth 16, value -107, nodes 30918514

 

 

15x24

 

9.

22-18

 

best:22-18 time 81.33, depth 16, value -17, nodes 51659473

 

 

13x22

 

10.

27x11

 

 

 

 

10-14

best:10-14 time 46.52, depth 14, value -17, nodes 35162678

11.

19x10

 

 

 

 

5x14

 

12.

29-25

 

best:30-27 time 47.01, depth 13, value -62, nodes 40403860

 

 

12-15

best:12-15 time 46.67, depth 14, value -3, nodes 32168973

13.

21-18

 

best:23-20 time 58.27, depth 14, value -6, nodes 39929364

 

 

14x21

 

14.

25x18

 

 

 

 

1-5

best: 1- 5 time 64.95, depth 15, value -48, nodes 60081555

15.

23-20

 

best:30-27 time 47.38, depth 14, value -48, nodes 40630967

 

 

5-10

best: 5-10 time 61.59, depth 15, value 0, nodes 45341111

16.

11-6

 

best:30-26 time 75.43, depth 15, value -1, nodes 69740254

 

 

3-7

best: 3- 7 time 57.06, depth 17, value 35, nodes 39811511

17.

20x11

 

 

 

 

7x21

 

18.

6-2

 

best: 6- 3 time 36.72, depth 14, value 35, nodes 25742915

 

 

10-14

best:10-14 time 57.40, depth 15, value 37, nodes 58374143

19.

2-6

 

best: 2- 5 time 34.02, depth 14, value 37, nodes 33910209

 

 

14-18

best:14-18 time 62.37, depth 14, value 40, nodes 43699427

20.

6-10

 

best: 6-10 time 50.16, depth 13, value 40, nodes 27237940

 

 

21-25

best:21-25 time 47.70, depth 14, value 22, nodes 34888185

21.

10-14

 

best:10-13 time 40.48, depth 14, value 23, nodes 39159383

 

 

18-21

best:18-21 time 38.56, depth 15, value 22, nodes 29347441

22.

14-18

 

best:14-18 time 31.14, depth 14, value 22, nodes 17855706

 

 

9-13

best: 9-13 time 56.19, depth 15, value 17, nodes 28325642

23.

17x10

 

forced move

 

 

4-7

best: 4- 7 time 71.34, depth 15, value -117, nodes 44696783

24.

10-6

 

best:10- 6 time 44.48, depth 14, value -117, nodes 43767402

 

 

7-11

best: 7-11 time 32.32, depth 14, value -117, nodes 30406715

25.

18-22

 

best: 6- 3 time 49.89, depth 13, value -117, nodes 29806550

 

 

25-29

best:25-29 time 32.38, depth 13, value -116, nodes 16891895

26.

6-3

 

best: 6- 3 time 92.00, depth 14, value -112, nodes 69103423

 

 

11-14

best:11-14 time 32.49, depth 14, value -112, nodes 26253987

27.

3-7

 

best: 3- 7 time 67.01, depth 14, value -119, nodes 41215886

 

 

14-19

best:14-19 time 32.23, depth 14, value -119, nodes 19335115

28.

22x15

 

 

 

 

21-25

best:21-25 time 35.72, depth 13, value -118, nodes 22516958

29.

15-19

 

best:15-19 time 70.91, depth 13, value -122, nodes 39491267

 

 

29-26

best:29-26 time 93.40, depth 14, value -125, nodes 54284794

30.

19-14

 

 

 

 

26-22

best:26-22 time 59.97, depth 13, value -114, nodes 37085814

31.

7-12

 

best: 7-12 time 106.91, depth 13, value -115, nodes 63890992

 

 

22-27

 

32.

14-19

 

best:30-26 time 58.53, depth 13, value -119, nodes 36787726

 

 

25-29

 

33.

12-16

 

best:12-16 time 45.63, depth 14, value -123, nodes 32151526

 

 

29-26

best:29-26 time 68.74, depth 15, value -125, nodes 46952737

34.

19-23

 

best:19-23 time 63.59, depth 14, value -125, nodes 40079742

 

 

27x20

 

35.

16x23

 

forced move

 

 

26-22

best:26-22 time 49.84, depth 15, value -131, nodes 37029286

36.

23-20

 

best:23-20 time 41.95, depth 15, value -129, nodes 26831230

 

 

22-26

best:22-26 time 32.76, depth 14, value -129, nodes 23026156

37.

20-15

 

 

 

 

26-22

best:26-22 time 43.64, depth 14, value -132, nodes 22803656

38.

15-12

 

best:30-27 time 78.31, depth 15, value -178, nodes 50724892

 

 

22-27

 

39.

12-15

 

best:32-28 time 41.08, depth 15, value -138, nodes 29882872

 

 

27-23

best:27-23 time 98.51, depth 16, value -138, nodes 71931682

40.

32-28

 

best:32-28 time 70.83, depth 16, value -147, nodes 83940696

 

 

23x32

 

41.

15-20

 

best:15-20 time 39.98, depth 17, value -199, nodes 42181547

 

 

32-28

best:32-28 time 43.83, depth 18, value -204, nodes 56605908

42.

30-26

 

best:30-26 time 68.04, depth 18, value -208, nodes 91837851

 

 

8-12

best: 8-12 time 81.74, depth 20, value -209, nodes 120144917

43.

26-21

 

best:26-22 time 71.51, depth 19, value -209, nodes 106447864

 

 

12-15

best:12-15 time 30.72, depth 18, value -209, nodes 43301304

44.

20x11

 

 

 

 

28-23

best:28-23 time 70.33, depth 18, value -209, nodes 105385375

45.

21-18

 

best:11-14 time 61.95, depth 17, value -209, nodes 93014847

 

 

23-27

best:23-27 time 39.48, depth 17, value -213, nodes 58100756

46.

18-14

 

 

 

 

27-30

best:27-30 time 63.42, depth 18, value -209, nodes 94222590

47.

14-10

 

best:11-15 time 53.07, depth 17, value -209, nodes 79370961

 

 

30-27

best:30-27 time 41.91, depth 17, value -213, nodes 62814174

48.

10-6

 

 

 

 

27-30

best:27-30 time 40.52, depth 16, value -212, nodes 59089212

49.

6-3

 

best: 6- 3 time 31.75, depth 15, value -212, nodes 46149014

 

 

30-27

best:30-27 time 61.80, depth 16, value -214, nodes 90196164

50.

3-6

 

 

 

 

27-30

best:27-30 time 40.49, depth 15, value -218, nodes 51016086

51.

11-15

 

best:11-14 time 57.68, depth 15, value -262, nodes 84169519

 

 

30-27

best:30-27 time 69.81, depth 16, value -267, nodes 103993523

52.

15-19

 

 

 

 

27-30

best:27-30 time 72.43, depth 16, value -267, nodes 74279874

53.

6-11

 

best: 6-10 time 47.67, depth 15, value -267, nodes 71302690

 

 

30-26

best:30-26 time 32.13, depth 16, value -374, nodes 80247503

54.

11-14

 

best:-4--4 time 0.00, depth 1, value 0, nodes 2

 

 

26-29

best:-4--4 time 0.00, depth 1, value 0, nodes 2

55.

19-22

 

best:-4--4 time 0.00, depth 1, value 0, nodes 2

 

 

24-28

best:24-28 time 4.68, depth 16, value -5000, nodes 13253096

56.

31x24

 

 

 

 

29-26

best:29-26 time 0.06, depth 10, value -5000, nodes 104447

57.

22x29

 

 

 

 
Saltare (P Shields) – Dama (SimpleTech)


30 Second per Move Test Game
Result: Saltare won

Analysis by Saltare 1.00 (P Shields - Italian Checkers Project) at 30s/move on Mobile Intel(R) Pentium(R) 4 CPU 3.06GHz generated with CheckerBoard 1.6

 

1.

23-19

 

Saltare: Best: 23-19, Time: 107.54s, Depth: 9(32), Score: 0, Nodes: 20239251

 

 

9-13

Saltare: Best: 11-14, Time: 43.14s, Depth: 8(31), Score: 4, Nodes: 7979914

2.

28-23

 

Saltare: Best: 28-23, Time: 48.12s, Depth: 8(31), Score: 2, Nodes: 8962934

 

 

11-15

Saltare: Best: 5-9, Time: 41.65s, Depth: 8(31), Score: 3, Nodes: 7657838

3.

21-17

 

Saltare: Best: 21-17, Time: 53.19s, Depth: 8(31), Score: 6, Nodes: 10468781

 

 

5-9

Saltare: Best: 6-11, Time: 45.09s, Depth: 7(32), Score: -2, Nodes: 9015071

4.

25-21

 

Saltare: Best: 25-21, Time: 44.87s, Depth: 8(31), Score: 3, Nodes: 9052226

 

 

6-11

Saltare: Best: 6-11, Time: 32.20s, Depth: 7(32), Score: 1, Nodes: 6596831

5.

21-18

 

Saltare: Best: 21-18, Time: 49.97s, Depth: 8(32), Score: 9, Nodes: 10154738

 

 

2-5

Saltare: Best: 12-16, Time: 38.43s, Depth: 8(31), Score: -14, Nodes: 8022446

6.

26-21

 

Saltare: Best: 26-21, Time: 69.59s, Depth: 9(34), Score: 30, Nodes: 12264643

 

 

11-14

Saltare: Best: 12-16, Time: 46.41s, Depth: 10(31), Score: -27, Nodes: 9803622

7.

18x11

 

 

 

 

7x14

 

8.

24-20

 

Saltare: Best: 32-28, Time: 95.49s, Depth: 9(32), Score: 111, Nodes: 17822221

 

 

15x24

 

9.

22-18

 

Saltare: Best: 22-18, Time: 67.10s, Depth: 9(30), Score: 22, Nodes: 13177357

 

 

13x22

 

10.

27x11

 

 

 

 

10-14

Saltare: Best: 9-13, Time: 42.78s, Depth: 6(27), Score: -18, Nodes: 7690680

11.

19x10

 

 

 

 

5x14

 

12.

29-25

 

Saltare: Best: 29-25, Time: 30.03s, Depth: 6(22), Score: 23, Nodes: 4204342

 

 

12-15

Saltare: Best: 1-5, Time: 31.95s, Depth: 7(25), Score: -19, Nodes: 6399239

13.

21-18

 

Saltare: Best: 21-18, Time: 54.87s, Depth: 9(28), Score: 22, Nodes: 10401931

 

 

14x21

 

14.

25x18

 

 

 

 

1-5

Saltare: Best: 8-12, Time: 65.21s, Depth: 8(25), Score: -17, Nodes: 12378615

15.

23-20

 

Saltare: Best: 23-20, Time: 39.73s, Depth: 8(25), Score: 22, Nodes: 8394458

 

 

5-10

Saltare: Best: 15-19, Time: 90.65s, Depth: 8(27), Score: -115, Nodes: 17062119

16.

11-6

 

Saltare: Best: 11-6, Time: 136.47s, Depth: 9(26), Score: 72, Nodes: 15922898

 

 

3-7

Saltare: Best: 3-7, Time: 33.79s, Depth: 9(26), Score: -11, Nodes: 4912437

17.

20x11

 

 

 

 

7x21

 

18.

6-2

 

Saltare: Best: 6-2, Time: 36.59s, Depth: 10(25), Score: 6, Nodes: 4428421

 

 

10-14

Saltare: Best: 21-25, Time: 35.19s, Depth: 9(24), Score: -2, Nodes: 4064937

19.

2-6

 

Saltare: Best: 2-6, Time: 35.23s, Depth: 10(27), Score: 5, Nodes: 3825903

 

 

14-18

Saltare: Best: 21-25, Time: 44.00s, Depth: 9(26), Score: -1, Nodes: 3274174

20.

6-10

 

Saltare: Best: 6-10, Time: 69.08s, Depth: 11(27), Score: 3, Nodes: 6815461

 

 

21-25

Saltare: Best: 21-25, Time: 84.11s, Depth: 11(28), Score: 14, Nodes: 10287479

21.

10-14

 

Saltare: Best: 10-14, Time: 71.51s, Depth: 11(27), Score: -5, Nodes: 6229404

 

 

18-21

Saltare: Best: 18-21, Time: 56.54s, Depth: 11(28), Score: 4, Nodes: 7521177

22.

14-18

 

Saltare: Best: 14-18, Time: 48.63s, Depth: 11(27), Score: 6, Nodes: 4537443

 

 

9-13

Saltare: Best: 25-29, Time: 30.30s, Depth: 10(26), Score: -2, Nodes: 3130973

23.

17x10

 

Saltare: Best: 17-10, Time: 33.10s, Depth: 11(25), Score: 181, Nodes: 4023984

 

 

4-7

Saltare: Best: 8-12, Time: 38.58s, Depth: 10(24), Score: -177, Nodes: 4046534

24.

10-6

 

Saltare: Best: 10-6, Time: 33.71s, Depth: 9(23), Score: 181, Nodes: 2988426

 

 

7-11

Saltare: Best: 7-12, Time: 64.68s, Depth: 10(26), Score: -177, Nodes: 7016269

25.

18-22

 

Saltare: Best: 18-22, Time: 41.74s, Depth: 10(27), Score: 203, Nodes: 3618611

 

 

25-29

Saltare: Best: 25-29, Time: 36.01s, Depth: 9(24), Score: -199, Nodes: 2901139

26.

6-3

 

Saltare: Best: 6-3, Time: 31.92s, Depth: 9(23), Score: 207, Nodes: 2362080

 

 

11-14

Saltare: Best: 21-25, Time: 50.18s, Depth: 10(24), Score: -137, Nodes: 3808252

27.

3-7

 

Saltare: Best: 3-7, Time: 107.30s, Depth: 11(25), Score: 141, Nodes: 6222154

 

 

14-19

Saltare: Best: 21-25, Time: 43.13s, Depth: 11(24), Score: -135, Nodes: 3022621

28.

22x15

 

 

 

 

21-25

Saltare: Best: 29-26, Time: 34.86s, Depth: 10(20), Score: -137, Nodes: 4174367

29.

15-19

 

Saltare: Best: 15-19, Time: 137.62s, Depth: 11(21), Score: 143, Nodes: 13700862

 

 

29-26

Saltare: Best: 29-26, Time: 200.07s, Depth: 12(22), Score: -139, Nodes: 20213767

30.

19-14

 

 

 

 

26-22

Saltare: Best: 25-29, Time: 53.33s, Depth: 10(20), Score: -137, Nodes: 6447054

31.

7-12

 

Saltare: Best: 7-12, Time: 115.04s, Depth: 11(22), Score: 143, Nodes: 8915850

 

 

22-27

 

32.

14-19

 

Saltare: Best: 14-19, Time: 89.71s, Depth: 11(20), Score: 142, Nodes: 7573670

 

 

25-29

 

33.

12-16

 

Saltare: Best: 12-16, Time: 47.33s, Depth: 11(20), Score: 142, Nodes: 5409457

 

 

29-26

Saltare: Best: 29-26, Time: 99.75s, Depth: 12(21), Score: -138, Nodes: 7851716

34.

19-23

 

Saltare: Best: 19-23, Time: 47.07s, Depth: 11(20), Score: 142, Nodes: 3929052

 

 

27x20

 

35.

16x23

 

takeback

 

 

26-22

Saltare: Best: 8-12, Time: 45.04s, Depth: 13(21), Score: -137, Nodes: 5803419

36.

23-20

 

Saltare: Best: 23-20, Time: 32.53s, Depth: 13(22), Score: 147, Nodes: 3166371

 

 

22-26

Saltare: Best: 22-19, Time: 34.21s, Depth: 12(19), Score: -143, Nodes: 3105410

37.

20-15

 

 

 

 

26-22

Saltare: Best: 26-22, Time: 35.43s, Depth: 13(20), Score: -143, Nodes: 3259024

38.

15-12

 

Saltare: Best: 15-12, Time: 66.33s, Depth: 13(20), Score: 147, Nodes: 5147510

 

 

22-27

 

39.

12-15

 

Saltare: Best: 12-15, Time: 57.75s, Depth: 13(22), Score: 147, Nodes: 4302698

 

 

27-23

Saltare: Best: 27-22, Time: 32.22s, Depth: 13(21), Score: -143, Nodes: 3135530

40.

32-28

 

Saltare: Best: 32-28, Time: 56.15s, Depth: 13(20), Score: 149, Nodes: 4689537

 

 

23x32

 

41.

15-20

 

Saltare: Best: 15-20, Time: 47.75s, Depth: 14(21), Score: 153, Nodes: 4079791

 

 

32-28

Saltare: Best: 32-28, Time: 47.35s, Depth: 15(24), Score: -151, Nodes: 4931350

42.

30-26

 

Saltare: Best: 30-26, Time: 70.78s, Depth: 15(23), Score: 232, Nodes: 5490213

 

 

8-12

Saltare: Best: 8-12, Time: 54.05s, Depth: 15(24), Score: -223, Nodes: 4780349

43.

26-21

 

Saltare: Best: 26-21, Time: 43.76s, Depth: 15(22), Score: 232, Nodes: 3898697

 

 

12-15

Saltare: Best: 12-15, Time: 31.74s, Depth: 15(24), Score: -228, Nodes: 3202779

44.

20x11

 

 

 

 

28-23

Saltare: Best: 28-23, Time: 32.64s, Depth: 14(21), Score: -233, Nodes: 3163736

45.

21-18

 

Saltare: Best: 21-18, Time: 36.46s, Depth: 13(20), Score: 237, Nodes: 2897144

 

 

23-27

Saltare: Best: 23-19, Time: 42.40s, Depth: 14(21), Score: -233, Nodes: 4647501

46.

18-14

 

 

 

 

27-30

Saltare: Best: 27-22, Time: 61.21s, Depth: 14(21), Score: -234, Nodes: 6617576

47.

14-10

 

Saltare: Best: 14-10, Time: 47.49s, Depth: 13(20), Score: 238, Nodes: 3973938

 

 

30-27

Saltare: Best: 30-26, Time: 74.32s, Depth: 14(21), Score: -234, Nodes: 8866318

48.

10-6

 

 

 

 

27-30

Saltare: Best: 27-22, Time: 60.50s, Depth: 14(23), Score: -234, Nodes: 7790463

49.

6-3

 

Saltare: Best: 6-3, Time: 54.19s, Depth: 13(20), Score: 238, Nodes: 4965287

 

 

30-27

Saltare: Best: 30-26, Time: 43.15s, Depth: 14(21), Score: -236, Nodes: 7035275

50.

3-6

 

 

 

 

27-30

Saltare: Best: 27-22, Time: 63.76s, Depth: 14(19), Score: -238, Nodes: 11642573

51.

11-15

 

Saltare: Best: 11-15, Time: 82.71s, Depth: 13(18), Score: 242, Nodes: 9676043

 

 

30-27

Saltare: Best: 30-26, Time: 75.13s, Depth: 14(21), Score: -294, Nodes: 13440429

52.

15-19

 

 

 

 

27-30

Saltare: Best: 27-30, Time: 40.88s, Depth: 14(19), Score: -304, Nodes: 9236450

53.

6-11

 

Saltare: Best: 6-11, Time: 65.20s, Depth: 13(18), Score: 308, Nodes: 8347332

 

 

30-26

Saltare: Best: 30-26, Time: 59.84s, Depth: 14(21), Score: -304, Nodes: 13183734

54.

11-14

 

Saltare: Best: 11-14, Time: 69.47s, Depth: 13(20), Score: 308, Nodes: 9784998

 

 

26-29

Saltare: Best: 26-29, Time: 33.86s, Depth: 14(19), Score: -406, Nodes: 9687210

55.

19-22

 

Saltare: Best: 19-22, Time: 30.33s, Depth: 13(18), Score: 410, Nodes: 6839167

 

 

24-28

Saltare: Best: 29-25, Time: 49.73s, Depth: 16(21), Score: -10000, Nodes: 22377987

56.

31x24

 

 

 

 

29-26

Saltare: Best: 29-25, Time: 4.86s, Depth: 20(25), Score: -15000, Nodes: 3860431

57.

22x29