Hmmmm ... how isChan Rasjid wrote:As for the one game win against Stockfish
Code: Select all
{Draw by repetition} 1/2-1/2
Sven
Moderators: hgm, Rebel, chrisw
Hmmmm ... how isChan Rasjid wrote:As for the one game win against Stockfish
Code: Select all
{Draw by repetition} 1/2-1/2
If you load the game, you can know it is a win; but my program has an ending bug and just don't know how to wrap up a win. Interesting to see a top program just making a blunder (very rare).Sven Schüle wrote:Hmmmm ... how isChan Rasjid wrote:As for the one game win against Stockfisha "win"?Code: Select all
{Draw by repetition} 1/2-1/2
Sven
You mean this kind of hand-written code (I just found a version 0.085f1a somewhere)? Certainly a good coding exampleChan Rasjid wrote:By the way, the SEE of Robbolito has about 220 lines; mine has abput 350.
Code: Select all
#ifndef BUILD_SEE
#define BUILD_SEE
#include "RobboLito.h"
typedef enum
{ valu_pedone = 100, valu_cavallo = 325, valu_alfiere = 325,
valu_torre = 500, valu_donna = 975, valu_re = 12345 } enum_valu;
static const int valu[16] =
{ 0, valu_pedone, valu_cavallo, 12345678,
valu_alfiere, valu_alfiere, valu_torre, valu_donna,
0, valu_pedone, valu_cavallo, 12345678,
valu_alfiere, valu_alfiere, valu_torre, valu_donna
};
#include "SEE.c"
#include "bianco.h"
#else
#include "nero.h"
#endif
logico
mio_SEE (tipo_posizione *POSIZIONE, uint32 mossa)
{
int di, ai, valu_pezzo, valu_cattura, d, dir;
uint64 bit, cbf, cel, indice_pila[4], gcm = 0, T;
int indice_turno[4], b, w;
T = mio_xray & tuo_occupato;
di = DI (mossa);
ai = AI (mossa);
while (T)
{
b = BSF (T);
w = mio_xray_lista[b];
bitLIBERO (b, T);
if (di != w && indice_linea[ai][b] != indice_linea[b][tuo_quadretto_re])
gcm |= quadretto_fisso[b];
}
gcm = ~gcm;
valu_pezzo = valu[POSIZIONE->qu[di]];
valu_cattura = valu[POSIZIONE->qu[ai]];
if (valu_pezzo - valu_cattura > valu_pedone
&& tuo_attaco_pedone[ai] & bitbordo_tuo_pedone & gcm)
return FALSO;
bit =
(bitbordo_mio_cavallo | (bitbordo_tuo_cavallo & gcm)) &
attaco_cavallo[ai];
d = valu_pezzo - valu_cattura;
if (d > valu_cavallo && bitbordo_tuo_cavallo & bit)
return FALSO;
indice_turno[direzione_h1a8] =
(POSIZIONE->occupato_sinistro45 >> linea_turno[direzione_h1a8][ai]) & 077;
indice_turno[direzione_a1h8] =
(POSIZIONE->occupato_retto45 >> linea_turno[direzione_a1h8][ai]) & 077;
cel =
bitbordo_mio_donna | bitbordo_mio_alfiere |
((bitbordo_tuo_donna | bitbordo_tuo_alfiere) & gcm);
indice_pila[direzione_h1a8] = indice_pila[direzione_a1h8] = cel;
bit |=
(linea_obscura[direzione_h1a8][ai][indice_turno[direzione_h1a8]] |
linea_obscura[direzione_a1h8][ai][indice_turno[direzione_a1h8]]) & cel;
if (d > valu_alfiere && (bitbordo_tuo_alfiere & bit))
return FALSO;
indice_turno[direzione_orizzontale] =
(POSIZIONE->
occupato_nero_bianco >> linea_turno[direzione_orizzontale][ai]) & 077;
indice_turno[direzione_verticale] =
(POSIZIONE->
occupato_sinistro90 >> linea_turno[direzione_verticale][ai]) & 077;
cel =
bitbordo_mio_donna | bitbordo_mio_torre |
((bitbordo_tuo_donna | bitbordo_tuo_torre) & gcm);
indice_pila[direzione_orizzontale] = indice_pila[direzione_verticale] = cel;
bit |=
(linea_obscura[direzione_orizzontale][ai]
[indice_turno[direzione_orizzontale]] |
linea_obscura[direzione_verticale][ai][indice_turno
[direzione_verticale]]) & cel;
bit |= (bitbordo_mio_re | bitbordo_tuo_re) & attaco_re[ai];
bit |= bitbordo_tuo_pedone & tuo_attaco_pedone[ai] & gcm;
bit |= bitbordo_mio_pedone & mio_attaco_pedone[ai];
cbf = ~(quadretto_fisso[di] | quadretto_fisso[ai]);
bit &= cbf;
dir = indice_linea[di][ai];
if (dir != direzione_malato)
bit |= linea_obscura[dir][di][indice_turno[dir]] & indice_pila[dir] & cbf;
valu_cattura -= valu_pezzo;
do
{
cbf &= ~bit;
cel = bitbordo_tuo_pedone & bit;
if (cel)
{
bit ^= (~(cel - 1)) & cel;
valu_pezzo = valu_pedone;
}
else
{
cel = bitbordo_tuo_cavallo & bit;
if (cel)
{
bit ^= (~(cel - 1)) & cel;
valu_pezzo = valu_cavallo;
}
else
{
cel = bitbordo_tuo_alfiere & bit;
if (cel)
{
valu_pezzo = valu_alfiere;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[direzione_a1h8];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
cel = bitbordo_tuo_torre & bit;
if (cel)
{
valu_pezzo = valu_torre;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[direzione_orizzontale];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
cel = bitbordo_tuo_donna & bit;
if (cel)
{
valu_pezzo = valu_donna;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[dir];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
if (!(bitbordo_tuo_re & bit))
return VERO;
valu_pezzo = 12345;
}
}
}
}
}
valu_cattura += valu_pezzo;
if (valu_cattura < -60)
return FALSO;
cel = bitbordo_mio_pedone & bit;
if (cel)
{
bit ^= (~(cel - 1)) & cel;
valu_pezzo = valu_pedone;
}
else
{
cel = bitbordo_mio_cavallo & bit;
if (cel)
{
bit ^= (~(cel - 1)) & cel;
valu_pezzo = valu_cavallo;
}
else
{
cel = bitbordo_mio_alfiere & bit;
if (cel)
{
valu_pezzo = valu_alfiere;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[direzione_a1h8];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
cel = bitbordo_mio_torre & bit;
if (cel)
{
valu_pezzo = valu_torre;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[direzione_orizzontale];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
cel = bitbordo_mio_donna & bit;
if (cel)
{
valu_pezzo = valu_donna;
di = BSF (cel);
dir = indice_linea[di][ai];
cel =
linea_obscura[dir][di][indice_turno[dir]] & cbf &
indice_pila[dir];
bit = cel | (quadretto_libero[di] & bit);
}
else
{
if (!(bitbordo_mio_re & bit))
return FALSO;
if (valu_cattura > 6174)
return VERO;
valu_pezzo = 23456;
}
}
}
}
}
valu_cattura -= valu_pezzo;
}
while (valu_cattura < -60);
return VERO;
}
If all games where I reached a won position would be counted as a win then I would probably be IM today.Chan Rasjid wrote:If you load the game, you can know it is a win; but my program has an ending bug and just don't know how to wrap up a win. Interesting to see a top program just making a blunder (very rare).Sven Schüle wrote:Hmmmm ... how isChan Rasjid wrote:As for the one game win against Stockfisha "win"?Code: Select all
{Draw by repetition} 1/2-1/2
Sven
I don't do EP in SEE myself, as that implies a pawn push, where SEE only considers captures...Chan Rasjid wrote:Hello,
I don't get it why anyone need to run SEE through an en-passant move. Or did I miss out bigtime on some things.
SEE is only about isolating bad captures that may lose material and be pruned or sorted back - it does not matter if a move is clearly winning or equalizes. En-passant can never be a loser and be a candidate for prunning. It should always be make() early if there is one. So what am I missing here?
As for the one game win against Stockfish, this is the first time it happens a few days back after I added some to evaluation. But I am less surprised that it happens, even if just a rare one time event. I am confident my engine, search and evaluation, now is very thoroughly debug and almost bugfree.
Best Regards,
Rasjid.
Yes, but the question would have to be "how much". The only real way to test is a cluster run, which I will fire up right now. Data this afternoon...hgm wrote:Time-to-depth speedup for a pruning is not a decisive measure, right? You also lose accuracy, which might cost you Elo. Some of the SEE-wise bad captures you prune actually win material (because a protector was overloaded or soft-pinned, or a capture delivered a discoverd threat), and your search will now miss that.bob wrote:So at least a factor of 2x, which is 50-70, and I did not remove the extension selection tests or any other uses of Swap(), just q-search...
Besides, SEE is not really necessary for this pruning. With BLIND I make similar prunings too.
My see routine does it correct if you ignore pins and assume only captures on the target square. I basically have a bit board of all pieces that "Might" be attacking the target square (sliders "might" be) and I mask them out after each "pseudo" exchange. So I pick up pieces hiding behind other pieces and bishops attacking through pawns. Whether it makes sense to go to this trouble is not clear.hgm wrote:I would be very surprised if SEE would even gain you 10 Elo.
I would not worry too much about the 'foe-backed captures'. See is inherently unreliable (it does not take into account things like soft-pinning or overloading of the capturers). When you have foe-backed capturers, it would totally suck in most cases anyway. Because the assumption that the exchange will be limited to a single square is completely flawed in such cases. The blocked enemy slider will also attack the capturer, and usually the capturer will attack it back. If one of the two will be more valuable than the other, it usually pays to capture that in stead of on the target square. Imagine two Rooks attacking a Pawn from different direction, but one of those has a Queen of the opponent behind it. Which of the two should I use to capture the Pawn? (Answer: none. Capture the Queen in stead!) Now suppose the Pawn was attacked by two Queens, with an enemy Rook behind one of them. Should I capture with the other first, so that tha Queen keeps 'blocking' the Rook? (Bye bye Queen, despite it being a SEE-wise 'good capture'!).
In general, how would you know if the piece blocking the enemy slider is (sufficiently) protected? Not using it to capture first might make the opponent retaliate against that piece, rather than against the target square (which is likely a less valuable target, as you decided to use it first).
I can call see() on any move. But see() first checks to see if it's en-passant and returns that it is safe. With promotions you just treat them as pawn moves which they are. If you promote and are captured, you don't lose a queen, you lose a pawn because you never really had the queen. If you capture to promote that's always a win of material and if you cannot push forward to promote you lose a pawn anyway. Castling is always safe if it's legal so I simply return that it's safe.bob wrote:I don't do EP in SEE myself, as that implies a pawn push, where SEE only considers captures...Chan Rasjid wrote:Hello,
I don't get it why anyone need to run SEE through an en-passant move. Or did I miss out bigtime on some things.
SEE is only about isolating bad captures that may lose material and be pruned or sorted back - it does not matter if a move is clearly winning or equalizes. En-passant can never be a loser and be a candidate for prunning. It should always be make() early if there is one. So what am I missing here?
As for the one game win against Stockfish, this is the first time it happens a few days back after I added some to evaluation. But I am less surprised that it happens, even if just a rare one time event. I am confident my engine, search and evaluation, now is very thoroughly debug and almost bugfree.
Best Regards,
Rasjid.
Here's the results. Had too many meetings and then class to check on test earlier:bob wrote:Yes, but the question would have to be "how much". The only real way to test is a cluster run, which I will fire up right now. Data this afternoon...hgm wrote:Time-to-depth speedup for a pruning is not a decisive measure, right? You also lose accuracy, which might cost you Elo. Some of the SEE-wise bad captures you prune actually win material (because a protector was overloaded or soft-pinned, or a capture delivered a discoverd threat), and your search will now miss that.bob wrote:So at least a factor of 2x, which is 50-70, and I did not remove the extension selection tests or any other uses of Swap(), just q-search...
Besides, SEE is not really necessary for this pruning. With BLIND I make similar prunings too.
The amount of ELO loss will depend a lot of the particular program, but I suspect it would be more for Komodo.bob wrote:Here's the results. Had too many meetings and then class to check on test earlier:bob wrote:Yes, but the question would have to be "how much". The only real way to test is a cluster run, which I will fire up right now. Data this afternoon...hgm wrote:Time-to-depth speedup for a pruning is not a decisive measure, right? You also lose accuracy, which might cost you Elo. Some of the SEE-wise bad captures you prune actually win material (because a protector was overloaded or soft-pinned, or a capture delivered a discoverd threat), and your search will now miss that.bob wrote:So at least a factor of 2x, which is 50-70, and I did not remove the extension selection tests or any other uses of Swap(), just q-search...
Besides, SEE is not really necessary for this pruning. With BLIND I make similar prunings too.
23.6 is current normal crafty 23.6Q01 has the Swap() code removed from q-search only, so that all captures are searched in usual MVV/LVA order.
Crafty-23.6-1 2667 4 4 30000 62% 2572 25%
Crafty-23.6Q01-1 2615 3 3 30000 56% 2572 25%
Bottom line was 52 Elo roughly, or about 2x slower overall due to larger q-search tree...