Ah well...
Hope you guys can tell me what you think of the game. I gave up debugging it. It plays a bit better than before, but the bug is still there.
Ah well...
Hope you guys can tell me what you think of the game. I gave up debugging it. It plays a bit better than before, but the bug is still there.
Well firstly, the generateMoves() function tend to report wrong figures. It's suppose to return the number of legal moves (mobility), but it doesn't. In the mid-game it reports stuff like 90, 80 etc...where there are only 64 squares on the board.
Secondly the minimax algorithm seems to have a serious implementation problem, even though i took the algorithm pseudocode from a othello game thesis someone made. I had to switch over the min and max evaluation procedures to make it work.
I posted a thread earlier about the bugs, but no one responded. Well, it's ok, no-one's obligued to help me. But now at least tell me what you think of the game >_<.
>>In the mid-game it reports stuff like 90, 80 etc
I haven't looked at the code yet, but are you sure you're not counting somethings twice by mistake, or maybe counting outside of the board?
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Nah, the value jumps suddenly from 5 to like 80 and jumps back down again...
Anywayz, how was the game Hammer? And everyone else?
I've been looking at the code, and i have a few ideas. If its not fixed when i get home from school (around 1pm EST) i'll get back on it.
I've actually fixed some minor bugs since the last time i posted the source at the other thread. This is the most updated version of the code. Note that i've actually swapped the code between MINIMIZE and MAXIMIZE, it seems to play better that way, i think it's the problem of the implementation of minimax, but don't have any idea how to fix it, as i said, i copied the algorithm from a pdf on a site.
i dloaded, gimme a few hours.
Did you get my private message I sent yesterday? I haven't been able to find yet why your generatemoves function isn't working yet, but you have a serious flaw with the implemenation of your minimax.
Minimax ONLY works if a board can only have one value at a given time irregardless of who made the last move. Right now you have it set up so that both player 1 and player 2 are trying to get the highest possible value. So when it is player one's move (which is in mode maximum) he is trying to get the highest possible positive value. But when it is player 2's turn to move, then a great score for him is ALSO positive, yet its mode minimize, so he in turn ends up picking the lowest score - which is bad for him because he wants positive!
What you need to do is change the eval function so that if the board is in favor of player 1 then it has a positive score, and if the board is in favor of player 2 then it it has a negative score - irregardless of who made the last move - ALWAYS. In fact, don't even pass to the eval function the player who made the last move, it shouldn't matter at all to it.
Let me know if this makes sense, and if not I'll try and explain it better!
Oh, and I think you said you changed this part recently, but make sure you change these lines:
back toCode:if ( mode == MINIMIZE ) if ( evalVal > max) { max = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; } else if ( mode == MAXIMIZE ) if ( evalVal < min ) { min = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; }
I'm pretty sure you minimax was right to begin with, just needed to change the eval function.Code:if ( mode == MINIMIZE ) if ( evalVal < min) { min = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; } else if ( mode == MAXIMIZE ) if ( evalVal > max) { max = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; }
Thanks. But it still doesn't seem total correct after i did this. What i did was change this
to....Code:if ( depth <= MAX_DEPTH ) evalVal = minimax( depth + 1, otherPlayer( player ), boardCopy, &chosenMove ); else evalVal = evalBoard( boardCopy, player );
What about not doing the above and doing this:Code:if ( depth <= MAX_DEPTH ) evalVal = -minimax( depth + 1, otherPlayer( player ), boardCopy, &chosenMove ); else evalVal = evalBoard( boardCopy, player );
Also, if i change thisCode:else if ( mode == MAXIMIZE ) { evalVal = -evalVal; if ( evalVal < min ) { min = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; } }
back it will play Very bad. See how i mean a frustrating bug. Please give a hand, i realli want to do this well.Code:if ( mode == MINIMIZE ) if ( evalVal > max) { max = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; } else if ( mode == MAXIMIZE ) if ( evalVal < min ) { min = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; }
Last edited by Nutshell; 01-24-2003 at 03:02 PM.
Try this, as far as I can see this should work:
Code:if ( mode == MINIMIZE ) { evalVal=-evalVal; if ( evalVal < min) { min = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; } else if ( mode == MAXIMIZE ) if ( evalVal > max ) { max = evalVal; chosenMove->row = listMoves[ counter ].row; chosenMove->col = listMoves[ counter ].col; }
Ahah! Found another major bug! Make sure you change to what I wrote in the post above and also make sure you change the line
at the end of the minimax function toCode:return evalVal;
You were accidentally sending back the evalVal which will always be the last move the function looked at, NOT the best value! Try this and see how much it helps.Code:if (mode==MAXIMIZE) return max; else return min;
i found nothing not already said, sorry.
Oops, actually I just realized that you can't just make evalVal negative like that. Really you should change the program so that you can get an accurate value from the board without having to know who made the last move so that you know that a negative value is ALWAYS good for player 2 and positive is ALWAYS good for player 1. But if you want to keep it the way you have it, I think you need to first take out the line
under the if(mode==MINIMIZE). You only want to have it change signs when you actually evaluate the board and never again, so change the lineCode:evalVal=-evalVal;
toCode:if ( depth <= MAX_DEPTH ) evalVal = minimax( depth + 1, otherPlayer( player ), boardCopy, &chosenMove ); else evalVal = evalBoard( boardCopy, player );
I think this should work. But like I said the standard (and best)way is take out the player parameter in the evalBoard() function.Code:if ( depth <= MAX_DEPTH ) evalVal = minimax( depth + 1, otherPlayer( player ), boardCopy, &chosenMove ); else { evalVal = evalBoard( boardCopy, player ); if (mode==MINIMIZE) evalVal=-evalVal; }
Last edited by PJYelton; 01-24-2003 at 03:46 PM.