A.I. for a turn-based board game ...

Started by
35 comments, last by AticAtac 11 years, 6 months ago

Move moves[33]; shouldn't this be Move moves[35] for this ?


Ooops! I shouldn't post code that I wrote late at night. :)

I think it should actually be 34 (31 non-empty combinations for bringing figures out of the base plus 3 moves). But 35 wouldn't hurt anything.
Advertisement
Oh, also, the code I posted had
for (depth = 1; depth < 5 || now() < start_time + 120.0; ++depth) {

That means that it will dare explore more depth if less than two minutes have elapsed. I had that in there for a test. I will edit the post and change it to something more tolerable. I will also make the 33->34 change.

Wow ... great code!

Thanks.

I tried to run it and get the following error:

"Run-Time Check Failure #2 - Stack around the variable 'moves' was corrupted"
Edit: found the problem, since there can be maximum of 34 moves the declarations of "Move moves[33];" must be changed to "Move moves[34];" ![/quote]
Yup, thanks for caching that. I guess my compiler probably reserves 36 bytes when asked for 33, which is what "saved" me in my tests.

P.S: there are 2 additional rules i idn't mention cuz of simplicity:
- once a piece moves into hostile base, that hostile base is broken, which means that any pieces moving into it will be destroyed[/quote]
I did not implement that, and the rule didn't come up in the games I played. This is an important rule because without it there are infinite games (draws, I would say). I'll implement it later.

- a piece located directly beside a base will always move into it regardless of the move-type, e.g. if piece is on 3rd row beside the hosile base and the chossen move is "up", then the piece will go into the base on 3rd row and not , as expected, into base on 4th row.[/quote]
Yes, I figured this out from playing with the emulator.

PPS: i am not sure but bringing out too many pieces out of a base may strategically not be so good. So in my move generation i only consider moves with only one base (in your case 1,2,4,8,16) with additional base moves only if there is a hostile piece outside beside the base. This reduces the number of possible moves a lot.
I might also be wrong with this consideration ... i have to get a better player with this game.
[/quote]
That seems a little harsh. My program picks one of these moves that you forbid occasionally. What I did was penalize them as costing 2 plies in depth. So the nominal depth that my program searches to is only for normal moves (1,2,4,8,16,32,33,34 in my notation). I have a table called "cost" (bad name, sorry) to encode that.

EDIT: Oh, I also generate normal moves before multiple-figures-out-of-base moves, in the hopes that this order will speed up alpha-beta.
Once again great work!

Next I will try to play you A.I. against the CPU in the emulator game (level 1-5) and see how it performs ;)

[quote name='SimonForsman' timestamp='1348753705' post='4984347']
Move moves[33]; shouldn't this be Move moves[35] for this ?


Ooops! I shouldn't post code that I wrote late at night. smile.png

I think it should actually be 34 (31 non-empty combinations for bringing figures out of the base plus 3 moves). But 35 wouldn't hurt anything.
[/quote]

ah yes, i just thought, highest move value = 34 so 35 moves, (gotta learn to actually read the code and not just skim through it), you're right that it should be 34.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
I did not implement that, and the rule didn't come up in the games I played. This is an important rule because without it there are infinite games (draws, I would say). I'll implement it later.[/quote]
In the emulator the door of the destroyed base stays always open!

Another rule: there cann't be more than 3 pieces in a base! So any additional piece moving into a base with already 3 pieces inside will be destroyed.
the change:

void make_move(Board &b, Move m, int player) {
u32 &bnp = b.net[player];

if (m<32) {
for (unsigned i=0; i<5; ++i) {
if (test(m, i)) {
b.base[player]--;
bnp |= (077u<<(6*i)) & target[!player];
}
}
}
else {
u32 boarding = bnp & target[player];
for (; boarding; boarding &= boarding-1) {
int row = lowest_bit_set(boarding) / 6;
b.base[row][!player] = 0;
if (b.base[row][player] < 3) <---- limit to 3
b.base[row][player]++;
}
bnp &= ~target[player];
bnp = player==0 ? bnp << 1 : bnp >> 1;

if (m==32)
bnp = ((bnp & 00000000077u) << 24) + (bnp >> 6);
else if (m==34)
bnp = ((bnp & 00077777777u) << 6) + ((bnp & 07700000000u) >> 24);

bnp &= ~holes;
}

b.net[!player] &= ~bnp;
}



Now i hope we got all the rules smile.png

Another rule: there cann't be more than 3 pieces in a base! So any additional piece moving into a base with already 3 pieces inside will be destroyed.


Actually, I thought I tested that against the emulator and it's not true. The graphics only display three, but if you take a figure out of the base it still shows 3. Could you make sure one way or another?
Actually, I thought I tested that against the emulator and it's not true. The graphics only display three, but if you take a figure out of the base it still shows 3. Could you make sure one way or another?[/quote]

I just verfied it, there are only 3 pieces allowed, the 4th piece is destroyed!
So first game won against emu on level 1 smile.png
(settings: "for (depth = 1; depth < 5 || now() < start_time + 1; ++depth)", i didn't saved the console output)

Second game against emu (level 2) won
I played one game against level 4 yesterday and my program won.

This topic is closed to new replies.

Advertisement