Trying Bit Boards for Connect-4

Started by
27 comments, last by ashish123 12 years, 10 months ago
@Alvaro:Thanks for the instant reply.

First of all let me know whether I am hijacking this thread, should I start a new one or not.

Last question is if I want to test _XXX condition for threat where _=35,X=36,37,38 , how to do this in bit boards?
in arrays very inefficently we can verify say board[35]==0&&board[36]==X...
but then I am finding this very confusing in bitboards.[/quote]
AFAIK, in standard connect 4, threats on particular rows matter a lot, they decide the game.
see fro example three in a row at row 3 is most effective many a times in game, but 3 in row in row 4 is not that effective for player 1.

So these patterns are particular at some part of the board which should be a very important information. Am I missing something?
result |= empty & (me>>H1) & (me>>(2*H1)) & (me>>(3*H1));
[/quote]
How did you arrive at this condition and what does result hold some sort of board pattern how to mention result in evaluation?
One more question I have is is there any advantage of starting with this 0-7-14... representation?
I thought the answer is that it helps in eliminating boundary conditions say we are at edge of the board and testing _XXX
we reach to square 29 so squares which will be tested are 29,36 and 43 and 50 but since 50 is out of the board, it doesnt count and hence its 0.
What will be wrong to start from 0-1-2-3... representation,apart from not being able to avoid boundary conditions.
where for (int y = 0; y < board.length; y++) {
h |= (1L << y);
}
long empty = (((me ^ h)) & (en ^ h));

also suppose I want to check for the pattern _XXX
then result|=empty&(1L>>1)&(1L>>2)&(1L>>3);

last question of this post is how do I determine the odd and even threats?
result will contain simple 1 in some of the block where the bit is set to be 1 and rest will be 0.
then how do I determine if the threat is odd or even
so result has to be power of 2 but then unable to solve math here:
1L<<x=result so what is the x?
kindly help me with this.
Thank you.
Advertisement

First of all let me know whether I am hijacking this thread, should I start a new one or not.

I think this is pretty on topic.

Last question is if I want to test _XXX condition for threat where _=35,X=36,37,38 , how to do this in bit boards?
in arrays very inefficently we can verify say board[35]==0&&board[36]==X...
but then I am finding this very confusing in bitboards.[/quote]
AFAIK, in standard connect 4, threats on particular rows matter a lot, they decide the game.
see fro example three in a row at row 3 is most effective many a times in game, but 3 in row in row 4 is not that effective for player 1.

So these patterns are particular at some part of the board which should be a very important information. Am I missing something?[/quote]
The code I provided to detect threats returns a bitboard with the location of all the threats for a particular side. It's trivial to AND this bitmap with one that selects whatever rows you are interested in.

result |= empty & (me>>H1) & (me>>(2*H1)) & (me>>(3*H1));
[/quote]
How did you arrive at this condition and what does result hold some sort of board pattern how to mention result in evaluation?[/quote]
This code just means "What are the empty cells that have one of my pieces to the right one step, another to the right two steps and another to the right three steps? That's one of the ways a threat can be made, so mark all those squares in the result."

One more question I have is is there any advantage of starting with this 0-7-14... representation?[/quote]
Yes, there are some advantages. For instance, one can quickly compute from it a 64-bit number that uniquely identifies the position (a trick by John Tromp). You may also be able to gather some information about a column (like where the threats of each side are) and use those bits to build an index into a table telling you something about the column. Actually, that's probably a very reasonable way to try to determine who is ahead. But these are small advantages. If you want to use a different representation, go ahead.

also suppose I want to check for the pattern _XXX
then result|=empty&(1L>>1)&(1L>>2)&(1L>>3);[/quote]
That just computes 0. Perhaps you meant
result|=empty&(me>>1)&(me>>2)&(me>>3);

last question of this post is how do I determine the odd and even threats?
result will contain simple 1 in some of the block where the bit is set to be 1 and rest will be 0.
then how do I determine if the threat is odd or even
so result has to be power of 2 but then unable to solve math here:
1L<<x=result so what is the x?
[/quote]
u64 odd_threats = threats & (0x14 * BOTTOM)
See the definition of BOTTOM in the code I posted earlier in this thread.
@alvaro:Man you are too good are you a professional game programmer or some author, just amazing...the way u have answerd
Quote

Quote

Last question is if I want to test _XXX condition for threat where _=35,X=36,37,38 , how to do this in bit boards?
in arrays very inefficently we can verify say board[35]==0&&board[36]==X...
but then I am finding this very confusing in bitboards.
AFAIK, in standard connect 4, threats on particular rows matter a lot, they decide the game.
see fro example three in a row at row 3 is most effective many a times in game, but 3 in row in row 4 is not that effective for player 1.

So these patterns are particular at some part of the board which should be a very important information. Am I missing something?
The code I provided to detect threats returns a bitboard with the location of all the threats for a particular side. It's trivial to AND this bitmap with one that selects whatever rows you are interested in.
[/quote]
So this means that I should have 6 separate bitboards for 6 rows.
row1=(1L<<0)^(1L<<7)^...^(1L<<42) and then AND the threats that you provided with if its player 1 then AND them with the odd rows, set high priorities, if they are even rows, give them a little priority.
am i getting it right?
also suppose I want to check for the pattern _XXX
then result|=empty&(1L>>1)&(1L>>2)&(1L>>3);
That just computes 0. Perhaps you meant
result|=empty&(me>>1)&(me>>2)&(me>>3);[/quote]
Yea I am sorry, but i meant it the way you interpreted.


Quote

last question of this post is how do I determine the odd and even threats?
result will contain simple 1 in some of the block where the bit is set to be 1 and rest will be 0.
then how do I determine if the threat is odd or even
so result has to be power of 2 but then unable to solve math here:
1L<<x=result so what is the x?

u64 odd_threats = threats & (0x14 * BOTTOM)[/quote]

Ok this really blew away my mind this is real cool..
from this I did the analysis for even threats and found for even threats its
even_threats=threats&(BOTTOM*0x20) am i correct here?

Last question: How did you manage to know so many things some books regarding bit tweaks or some high level programing course or experience?
Thank you for all replies.

@alvaro:Man you are too good are you a professional game programmer or some author, just amazing...the way u have answerd

Thanks! I was a professional programmer for 10 years, but not in the game industry.


u64 odd_threats = threats & (0x14 * BOTTOM)[/quote]

Ok this really blew away my mind this is real cool..
from this I did the analysis for even threats and found for even threats its
even_threats=threats&(BOTTOM*0x20) am i correct here?[/quote]
No, actually it's
u64 even_threats = threats & (0x2a * BOTTOM)
Notice that 0x2a is 101010 in binary. When you multiply it by BOTTOM, you get that pattern in each column.

Last question: How did you manage to know so many things some books regarding bit tweaks or some high level programing course or experience?[/quote]
I started learning about bit manipulation when I was 11, and I am now in my thirties. I am also generally good at Math, which helps.
No, actually it's
u64 even_threats = threats & (0x2a * BOTTOM)
Notice that 0x2a is 101010 in binary. When you multiply it by BOTTOM, you get that pattern in each column.
[/quote]
If thats the case then did you mean 0x15 , in binary its 010101 pattern in column instead of 0x14?

I have put all threats in place, and now according to me they should return the same score at same ply but its not doing that way, so thinking over that how to do it.
Will let you know more on it later once I think that I have done all possible things that I could think of.
I have implemented like this.

for (int r = 0; r < 42; r++) {
if (original_board[r] == x) {
me ^= bit_board[r];
} else if (original_board[r] == o) {
en ^= bit_board[r];
}
}
empty = ~(me | en) & BOARD;

result |= empty & (me >> H1) & (me >> (2 * H1)) & (me >> (3 * H1));//_XXX
if ((result & bit_board_row_1) != 0) {
weight_p1 += threat_at_row_1;
}

original_board[] represents my array[][] board where in the pieces occupy their place.
bit_board[] is a static array which contains Mr.Tromp's representation.

No, actually it's
u64 even_threats = threats & (0x2a * BOTTOM)
Notice that 0x2a is 101010 in binary. When you multiply it by BOTTOM, you get that pattern in each column.

If thats the case then did you mean 0x15 , in binary its 010101 pattern in column instead of 0x14?
[/quote]
No, I meant 0x14. Threats on the first row only have tactical interest, and when you are interested in looking at odd threats you are normally thinking of long-term threats that will win the endgame, so you are only interested in threats at rows 3 and 5.

I am not sure I understand your problem, but you should be able to find a position where the old code and the new code give you different answers, and then step in with a debugger to see where the difference is coming from.

Normally you would select certain type of threat, then use a "population count" function (count the ones in a number) and multiply the result by the bonus you want to give per occurrence of that type of threat.
@Alvaro: Ok that clears my doubts.
I just made that analogy of being 0x15 rather than 0x14, no maths.
BTW because of your help, this is the improvement:
The program approximately the program is speed up by 57-58%, which I think is very good. Do let me know what you think on this.
I read in you previous post that you too have programed connect-4, do you mind to put that on web so that we can make it play together, I would like to see your program playing against mine.
What say?
Hmmm... I wrote a pretty decent program in 1994, but who knows where that is. I can try to put something together and then we'll match our programs, but it will take me a while, but the only thing I have now is a proof of concept.
@Alvaro:
Do you think that some sort of self learning algorithm would help, if you think so the also let me know what are the steps to go through these type of programing?
Also I am looking forward for that match against your AI, would like to request you for no opening book and should be only based on evaluation.

This topic is closed to new replies.

Advertisement