Recommended Posts

I'm trying to code an alphabeta algorithm. I think I got the logic of it right, and with a depth of 7 it plays sort of ok but sometimes it doesn't see that it can win or that the enemy can win. I was wondering if you guys could have a look at the code. First of all, I have a board structure:

I checked the updateboard and evaluateboard seperatly so I don't think that there's a problem there.
Here's the MinMax class which actually uses the Negamax (same as minmax just instead of getting min and max values it always gets max and just flips the - sign) function ans AB:

In the game I have a board that I constantly update and to find the computer's move I do:
move = Computer.GetNextMove(GameBoard);
And one other thing, the variable "turn" in the AB function is 1 if the AB is finding a move for the computer, and -1 for the player. I got a little confused with were I should put -turn and were I should put turn so maybe that is the problem. And for some reason If in the GetNextMove I write 1(instead of -1) he does worse, even though it should really be 1 (cause it's the computer's move)? and that happens when m_iTotalDepth is odd but not when it's even?? Well anyway, what do you guys think?
Thanks.
[Edited by - daniel_i_l on July 7, 2006 4:14:11 AM]

Share this post

Link to post

Share on other sites

You are using ints and flag values instead of enums with named values. This is a serious premature optimization which makes your code harder to follow.

typedef enum { player1, player2 } player;

struct location { bool occupied; player which_side;};

Your AlphaBeta function is far too complicated.

Your evaluation function should take the board and the side, and generate the value of the board for that side.

You are needlessly storing state in the game board. As an example: Why in the hell does EvaluateBoard store the result of the evaluation, why doesn't it just return it?

I would also advise taking your long functions and breaking them up into smaller ones. UpdateBoard, EvaluateBoard -- they are both far far far too long. Heck, you have leftover junk code lieing around!

It may be possible to prevent all of that board copying. Are your moves invertable? If so, you could, with care, use the same board for every single recursive call, simply undoing the changes as you fall back up the stack. This is dangerous, but may give you a significant performance improvement. Naturally do not do this until your code is well structured and correct.

...

By breaking the code down into smaller pieces, it is far easier to check that each piece is doing something reasonably correct. It is also easier to see what each function does from start-to-end, because you can see each step written out as a descriptively named function call.

Once you have your code as a bunch of short, concice functions, you can start with tricks like "make the moves reversable". Or you can try to optimize one of the sub-functions by rewriting it, and then run test runs against the original -- checking to see that the rewrite does the same thing, faster -- and then replace the original subfunction.