After a break I have started to program my connect four again.
The AI now searches 14-plys deeper in matter of 5 seconds on empty board and playing first(Comment on the speed,as it wud help me to understand if its fast or not).
I have programed Negamax+AB+ hashtables and killermove heuristics. My primitive version only included the winning conditions but however now since its not enough to contain that only, I would like to make it a bit more stronger by putting some favourable conditions,like odd and even threats.
Here is what I have done:
int threat_at_2 = 60;
int threat_at_3 = 50;
int threat_at_4 = 20;
int threat_at_5 = 10;
int threat_at_6 = 5;
for (column = 0; column < 4; column++) {
row = 4;
if (posn[row][column] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'o')
{
weighto += threat_at_2;
}
if (posn[row][column + 1] == '1' &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == posn[row][column] &&
posn[row][column + 3] == 'o') {
weighto += threat_at_2;
}
if (posn[row][column + 2] == '1' &&
posn[row][column + 1] == posn[row][column] &&
posn[row][column] == posn[row][column + 3] &&
posn[row][column + 3] == 'o') {
weighto += threat_at_2;
}
if (posn[row][column + 3] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column] &&
posn[row][column] == 'o') {
weighto += threat_at_2;
}
row = 3;
if (posn[row][column] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_3;
}
if (posn[row][column + 1] == '1' &&
posn[row][column] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_3;
}
if (posn[row][column + 2] == '1' &&
posn[row][column + 1] == posn[row][column] &&
posn[row][column] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_3;
}
if (posn[row][column + 3] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column] &&
posn[row][column] == 'x') {
weightx += threat_at_3;
}
row = 2;
if (posn[row][column] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'o') {
weighto += threat_at_4;
}
if (posn[row][column + 1] == '1' &&
posn[row][column] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'o') {
weighto += threat_at_4;
}
if (posn[row][column + 2] == '1' &&
posn[row][column + 1] == posn[row][column] &&
posn[row][column] == posn[row][column + 3] &&
posn[row][column + 3] == 'o') {
weighto += threat_at_4;
}
if (posn[row][column + 3] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column] &&
posn[row][column] == 'o') {
weighto += threat_at_4;
}
row = 1;
if (posn[row][column] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_5;
}
if (posn[row][column + 1] == '1' &&
posn[row][column] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_5;
}
if (posn[row][column + 2] == '1' &&
posn[row][column + 1] == posn[row][column] &&
posn[row][column] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weightx += threat_at_5;
}
if (posn[row][column + 3] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column] &&
posn[row][column] == 'x') {
weightx += threat_at_5;
}
row = 0;
if (posn[row][column] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weighto += threat_at_6;
}
if (posn[row][column + 1] == '1' &&
posn[row][column] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weighto += threat_at_6;
}
if (posn[row][column + 2] == '1' &&
posn[row][column + 1] == posn[row][column] &&
posn[row][column] == posn[row][column + 3] &&
posn[row][column + 3] == 'x') {
weighto += threat_at_6;
}
if (posn[row][column + 3] == '1' &&
posn[row][column + 1] == posn[row][column + 2] &&
posn[row][column + 2] == posn[row][column]&&
posn[row][column] == 'x') {
weighto += threat_at_6;
}
}
weight=weightx-weighto;
return whotomove?weight:-weight;
The above code contains only the horizontal threats(one blank and three of same color on one horizontal row.)
I just want to ask whether I am on right track or not.
Please give me some more pointers (pseudo code wud be a lot helpful, some real code of any data-struct will be very help ful.) to improve the eval and further cut down the number of nodes.
PS:The idea is to learn to program ai and slightly difficult game before moving onto reversi. The point is to learn algorithms related to AI board games and implement them, also learn to write evaluation methods.
The goal as of now is to make a real difficult connect4(It might happen that this program would play perfect with odd-even rules and later on some addition of parity(I have not thought of parity yet.))
-TYIA