* The book files are not very complete. I just used a few lines that
my program's sparring partner tends to play, in absence of further
work.
* The program is set up right now for running a simple 18-position
benchmark, included in the file benchmk.dat. I never bothered to
put this in as a compile-time option in the main header file.
* The program has no pondering or time control yet.
* The program
Current results on the 18-position benchmark included, on my
Pentium-133, with a constant 4-ply search with quiescence and capture
extensions:
Total nodes: 2111006
Average nodes: 117278
Total time: 108.68 seconds
Average time: 6.04 seconds
Average NPS: 19424
I would be interested to compare results on this benchmark with other
programs.
Matt Craighead
Anyway, I average 20,838 NPS on these positions with my 486/80. It takes
33,318 nodes (average) to hit 4 ply. My 6 ply average is 521,134, or 25
seconds.
These positions are significantly harder than BK, for example. My 4 ply
node average for BK is 16,178.
Regarding the rest of your program, I have a few suggestions. First, in
your move generator you should use an array of offsets instead of code
for each offset. This makes it more legible and it may save you a bit of
time in terms of cache. Second, MVV/LVA orders captures of the *largest
piece first*. I'm not sure, but your weights may be screwing this up. If
this is the case, expect to see a big performance gain when you fix it.
No wonder MVV was working better... Third, move generator wise, you may
save a bit of time using a mailbox array instead of, uh, whatever you're
doing. Fourth, I notice you have a lot of special-case logic in
makemove() to update your castle flags, and it may not consider a few
cases (when a rook is captured, for example). Consider having an array of
castle bits, and an array of castle masks. When you make a move, AND the
bits with the masks for the source and destination squares. Fifth,
consider a 'takeback' function, so you don't have to copy the position
when you takeback AND makemove... Also, en passant is often nice. :)
Cheers,
Tom
------------------------------------------------------------------------------
"You can bring any calculator you like to the midterm, as long as it
doesn't dim the lights when you turn it on." -Hepler, Systems Design 182
Thomas C. Kerrigan
'kerr...@alpha.pr1.k12.co.us'
>yours again. :)
What is a FEN? I've never heard of them. I presume it's a test
format?
>Anyway, I average 20,838 NPS on these positions with my 486/80. It
takes
>33,318 nodes (average) to hit 4 ply. My 6 ply average is 521,134, or
25
>seconds.
Interesting... I am getting about 4x the nodes you are at 4 ply.
I just tried 5 ply, and seemed to have come up with a buggy position in
which my program claimed it was only searching about 20 NPS, and spent
100 minutes before giving up. A very confusing part of this was that
the program was set to spend at most 1000 seconds. First, though, I'd
better check whether I can reproduce this.
>These positions are significantly harder than BK, for example. My 4
ply
>node average for BK is 16,178.
I would like to be able to post a comparison, but I have never found a
copy of BK. Could you point me to one?
>Regarding the rest of your program, I have a few suggestions. First,
in
>your move generator you should use an array of offsets instead of code
>for each offset. This makes it more legible and it may save you a bit
of
>time in terms of cache. Second, MVV/LVA orders captures of the
*largest
>piece first*. I'm not sure, but your weights may be screwing this up. If
>this is the case, expect to see a big performance gain when you fix it.
I'll look at my MVV/LVA code. I _thought_ I was prioritizing the largest piece
captured over the lowest-valued attacker, but I'd better check.
>No wonder MVV was working better... Third, move generator wise, you may
>save a bit of time using a mailbox array instead of, uh, whatever you're
>doing. Fourth, I notice you have a lot of special-case logic in
A mailbox array? Never heard of it...
>makemove() to update your castle flags, and it may not consider a few
>cases (when a rook is captured, for example). Consider having an array of
>castle bits, and an array of castle masks. When you make a move, AND the
>bits with the masks for the source and destination squares. Fifth,
This brings to mind a bug in my old Neptune program, which was deficient in this
manner. Its rook on h1 was trapped by a long-diagonal bishop and captured, and
it somehow decided to play h1f1. I copied my (fixed) logic from that program
here.
>consider a 'takeback' function, so you don't have to copy the position
>when you takeback AND makemove... Also, en passant is often nice. :)
Yes, en passant, threefold repetition, and the 50-move rule will sometimes save
me games. They are messy, though, and I would rather work on getting my search
sizes stabilized before I start screwing around with hacks to implement them.
>Cheers,
>Tom
>
>------------------------------------------------------------------------------
>"You can bring any calculator you like to the midterm, as long as it
>doesn't dim the lights when you turn it on." -Hepler, Systems Design 182
>
>Thomas C. Kerrigan
>'kerr...@alpha.pr1.k12.co.us'
Matt Craighead
int bounds[48]= {
-1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, -1,
-1, 4, 5, 6, 7, -1,
-1, 8, 9, 10, 11, -1,
-1, 12, 13, 14, 15, -1,
-1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1
};
Then you need an array to convert to the mailbox subscripts:
int xbounds[16]= {
13, 14, 15, 16,
19, 20, 21, 22,
25, 26, 27, 28,
31, 32, 33, 34
};
Then, if you have an offset x, you check check to see if this offset will
take sq out of bounds with:
if(bounds[xbounds[sq]+x]==-1)
; /* out of bounds */
I didn't realize this method was called "mailboxing" until Hyatt told me.
Evidently the -1s around the edge of 'bounds' remind him of a mailbox. :)
Also, I think Bruce Moreland posted an article a while back on 0x88
bounds checking. I don't think you'd want to use this, seeing as your
program is already set up to use a 64 square board, but you may be
interested all the same...