I thought if it would be possible to quantify the statement of Michel.
Could it be that at 1 minute/game at one 1 core, dragon (or any other decent engine) plays optimal every move in about 50% of games?
With optimal defined as not moving into a position that is theoretically lost.
For this purpose I tried to generate some sort of model, for which i have run a quick and dirty (so it might be flawed) simulation.
Basic assumptions are (wright or wrong, but at least it is a starting point):
* In the first X-moves of the game both players will use a (well-proven) book, and it is assumed that this book will not contain non-optimal moves (according to the definition of Michel, so no moves moving into a theoretical lost position).
* From move Y onwards , the search will mostly/always reach Data-Base nodes, so play from here does not yield errors.
* In the current simulation model the probability to make an error is equal for both players (but this can be easily changed), ans the probability does not change between move X (book) and move Y( endgame end-nodes) (think this is also not true, as i expect that the error-rate will peak somewhere in the middle game).
* An error will result (at that point of the game) in a lost position if the previous position was a draw, and a draw position if the previous position was a win (from the perspective of the player making the last error). I did not include the error which transfers a won game into a lost one.
In the calculation i assumed that X=10 and Y=40. So basically there are (only) 30 moves possible for each player to make an error.
Output for the error probability from 0 o/oo to 10 o/oo (pro-mille) is summarized in next table (actual output simulation).
For better statistics i run the 30-move simulation 1.000.000 times (so basically a 1.000.000 games match).
Code: Select all
0. Win = 0 ( 0.0), Draw = 1000000 (100.0), Lost = 0 ( 0.0)
1. Win = 14775 ( 1.5), Draw = 970477 ( 97.0), Lost = 14748 ( 1.5)
2. Win = 28878 ( 2.9), Draw = 942417 ( 94.2), Lost = 28705 ( 2.9)
3. Win = 42489 ( 4.2), Draw = 914882 ( 91.5), Lost = 42629 ( 4.3)
4. Win = 55453 ( 5.5), Draw = 889193 ( 88.9), Lost = 55354 ( 5.5)
5. Win = 67959 ( 6.8), Draw = 864236 ( 86.4), Lost = 67805 ( 6.8)
6. Win = 79783 ( 8.0), Draw = 840790 ( 84.1), Lost = 79427 ( 7.9)
7. Win = 90141 ( 9.0), Draw = 818342 ( 81.8), Lost = 91517 ( 9.2)
8. Win = 101686 ( 10.2), Draw = 796631 ( 79.7), Lost = 101683 ( 10.2)
9. Win = 111920 ( 11.2), Draw = 776201 ( 77.6), Lost = 111879 ( 11.2)
10. Win = 122363 ( 12.2), Draw = 755859 ( 75.6), Lost = 121778 ( 12.2)
If we would take the 3 matches Damage against Kingsrow at 1 Min - 1Min, we found the result 41 Win Damage (8.6%), 43 Win Kingsrow (9.0%) and 390 Draws (82.3%).
So if we assume that both players have the same ELO_rating (and also the same error-probability) then according to the table the error-rate is around 6-7 o/oo.
So this would indicate that both damage as Kingsrow play optimal moves in 99.993% - 99.994% ....
Actual program code below, so others can also experiment with it. I appreciate feedback, and maybe correct some errors..
I added the loop for probability later so therefore the initial initialization of variables has no function anymore...
Code: Select all
// DSimulation.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdlib.h"
#define XGAME 1000000
#define XMOVE 30
#define GAMESTATUS_WIN 1
#define GAMESTATUS_DRAW 0
#define GAMESTATUS_LOST -1
#define PROBABILITY_RANGE 1000
int _tmain(int argc, _TCHAR* argv[])
{
int iGame, iMove ;
int iGameStatus ;
int iPErrorMove0, iPErrorMove1, iRandomMove ;
int iXWin, iXDraw, iXLost ;
float fWin, fDraw, fLost ;
iXWin = 0 ; // Init WDL Counters
iXDraw = 0 ;
iXLost = 0 ;
iPErrorMove0 = 50 ; // Error probability in %
iPErrorMove1 = 50 ;
for ( int j=0; j<=100; j++ ) {
iPErrorMove0 = j * 1 ; // Error probability in o/oo (pro-mille)
iPErrorMove1 = j * 1 ;
iXWin = 0 ; // Init WDL Counters
iXDraw = 0 ;
iXLost = 0 ;
for ( iGame = 0; iGame < XGAME; iGame++ ) {
iGameStatus = GAMESTATUS_DRAW ; // Perspective Player0
for ( iMove = 0; iMove < XMOVE; iMove++ ) {
iRandomMove = ( rand() % PROBABILITY_RANGE ) + 1 ;
if ( ( iGame + iMove ) % 2 ) { // Player 1
if ( iRandomMove <= iPErrorMove1 ) {
if ( iGameStatus == GAMESTATUS_DRAW )
iGameStatus = GAMESTATUS_WIN ;
else if ( iGameStatus == GAMESTATUS_LOST )
iGameStatus = GAMESTATUS_DRAW ;
// No need to address GAMESTATUS_WIN
}
} else { // Player 0
if ( iRandomMove <= iPErrorMove0 ) {
if ( iGameStatus == GAMESTATUS_DRAW )
iGameStatus = GAMESTATUS_LOST ;
else if ( iGameStatus == GAMESTATUS_WIN )
iGameStatus = GAMESTATUS_DRAW ;
// No need to address GAMESTATUS_LOST
}
}
}
if ( iGameStatus == GAMESTATUS_WIN ) // Update WDL Counters
++iXWin ;
else if ( iGameStatus == GAMESTATUS_DRAW )
++iXDraw;
else if ( iGameStatus == GAMESTATUS_LOST )
++iXLost ;
}
fWin = (float)( 100. * iXWin ) / XGAME ;
fDraw = (float)( 100. * iXDraw ) / XGAME ;
fLost = (float)( 100. * iXLost ) / XGAME ;
printf("%d. Win = %d (%5.1f), Draw = %d (%5.1f), Lost = %d (%5.1f)\n", j, iXWin, fWin, iXDraw, fDraw, iXLost, fLost) ;
}
return 0;
}
Bert