Phew!
Finally got my othello program to play properly. Try it out ok? Not exactly efficient code though..but it's not bad i reckon.
Phew!
Finally got my othello program to play properly. Try it out ok? Not exactly efficient code though..but it's not bad i reckon.
Last edited by Nutshell; 04-15-2003 at 01:07 AM.
Nice!
Spent 5 minutes in my office playing with it :°)
[R]evolution!
Programming related articles, downloads, demos
Good job, it looks great! The AI unfortunately isn't all that strong, I had no problems beating it on my first try and I've only played othello maybe 10 times in my life.
Question, I looked at your code for a second. Shouldn't the computer actually make each move it looks at in your minimax function? Otherwise the board state never changes and every move it looks at no matter what depth it is at is based off of the original unchanged board, not a future board. Could explain why the game plays exactly the same irregardless if the max depth search is 2 or 40.
nice but the one thing i noticed was it is hard to see where the comp went. i cant tell y so many of them suddenly turned white. The ai seems to be pretty good, i hardly beat it.
Drink Yer Wilk
I realise that if i change checkMove() to actually do the move in minimax() i'll actually stuff up the board. Must be a bug in my function, because i tried to restore the board from board_save in each recursive call.
PJYelton (or any people who knows how to), in your opinion how should i fix this?
Code:int minimax( int depth, char player, int alpha, int *best_i, int *best_j ) { int i, j, max = -10000, score, dummy; char board_save[ 8 ][ 8 ]; *best_i = 0; *best_j = 0; memcpy( board_save, mainBoard, sizeof mainBoard ); for( i = 0; i < 8 ; i++) for( j = 0; j < 8; j++) if( score = checkMove( i, j, mainBoard, player, 1 ) ) { if( depth != MAX_DEPTH) score -= minimax( otherPlayer( player ), depth + 1, score - max, &dummy, &dummy ); if( MAX_DEPTH == 1) score += 5 * ( ( i == 0 || i == 7 ) + ( j == 0 || j == 7) - ( i == 1 || i == 6 ) - ( j == 1 || j == 6 ) ); if(score > max) { max = score; *best_i = i; *best_j = j; } else if( ( score == max ) ) { *best_i = i; *best_j = j; } memcpy( mainBoard, board_save, sizeof board_save ); if( score >= alpha ) return max; } if( !*best_i ) return 0; return max; }
Last edited by Nutshell; 04-16-2003 at 07:33 AM.
Very nice. I won but barely (I suck at Othello).
Nice job!!!
First off, as far as I can tell I'm not sure you can do a traditional minimax with the way you evaluate the board. Instead of checking to see how many pieces were just turned, you would need to evaluate the entire position, the easiest way just being human pieces minus comp pieces, with maybe bonuses added in for special squares (positive score if human has it, negative score if comp has it). Then your minimax algorithm would look something like this in pseudocode:
I think that would work, but you would have to make sure that you have an evaluation function that evaluates the entire board, and also make sure that you are consistent with your evaluations. By that I mean make sure if you make good positions for the comp negative and good positions for the human positive that the minimax starts off looking at min since comp obviously wants the lowest score possible.Code:int minimax(int depth, bool max, int &bestX, int &bestY) { int dummy; int bestScore; if (max==true) bestScore=-99999; else bestScore=99999; int score; for (int i=0; i<8; i++) { for (int j=0; j<8; j++) { // make move at i,j, if no move possible, then continue with for loop // if depth==maxdepth, evaluate board, erase move, return evaluation // else score=minimax(depth+1, !max, dummy, dummy) // if this is a max (max==true) then // if score>bestScore then bestScore=score, bestI=i, bestJ=j // else if this is a min(max==false) then // if score<bestScore then bestScore=score, bestI=i, bestJ=j // erase move } } return bestScore;
But your game is good as it is! This is just an idea if you want to go and try and make the AI stronger.
great game!!! I found a bug though... I watched the demo play, and it went through all nicely, and white won. Then it said "Alrite.ain <Y or N>?:" i assume its supposed to say something like "play again?"
Nicely done, but the AI could use some work. I played four games and beat the computer easily each time, twice securing all four corners. Some things to take into consideration in your AI...
The four corners are obviously the most advantageous spots on the entire board in any game of Othello, since once gained, they can not be lost.
After the four corners, pieces on the four sides are the next most advantageous to have.
The AI needs to avoid making a move that results in an immediate piece gain, all of which is lost on the player's next move.
It's a good program, though. Good luck
Away.
I vaguely remember his old version of othello had different values for each square, with the corners and other spots being very valuable. Not sure why this one doesn't though.
Thnx for all the nice responses
However, i want to know why my minimax() doesn't save the board and then restore it after the recursive call to itself. As far as i know, i couldn't spot the illogical bug in the algorithm. Also, the algorithm also has alpha/beta pruning.
thnx
>>The AI unfortunately isn't all that strong, I had no problems beating it on my first try and I've only played othello maybe 10 times in my life.
same w/me, but hey man, great none the less, i loved it
guns dont kill people, abortion clinics kill people.
Yes! I found the bug, it's quite obvious, i was just careless. I actually swapped around the first 2 arguments in the recursive call to minimax(). Anyway here's the 0.91 build of the game, weights might be added later on.
note: It might still make stupid moves, such as letting you take corners.
Last edited by Nutshell; 04-17-2003 at 08:13 AM.
I think the AI was better in the last release
You still aren't actually making the move in the minimax function. Without making the move all that happens is that the computer looks 5 moves down, figures out what is the move that turns over the most pieces - based off the CURRENT board, NOT the board 5 moves later - and then returns it. That is why it never considers a good human move, it never looks at one nor makes one in its thinking. Also, like I said, it is better to evaluate the whole board, not the number of pieces turned over.
Take a look at this, I made a couple of small changes, mainly adding a sloppy board evaluation and making it so execute==2 means make the move without showing the move. I played it once and it kicked my arse, but then again I'm not very good at othello
The new AI is better, but I didn't like the flicker that you introduced. I agree that it was hard to tell where the computer moved in the older version, but it's impossible now I think I commented out the line responsible for that, but I don't have access to a compiler right now so I can't be sure. I think the way to approach this problem would be to put where the computer moved, sleep( somethingnottoolong ); then display the rest of the pieces changed at once. Also, it needs to sleep( somethingnottoolong ); before the computer moves at all after the player moves. I fixed a couple spelling errors and the spacing error where it deletes the second | on the left side of where it says the status, too. Anyway, here's a new file with some slight modifications...I'd like to see it compiled if someone has a second. :-/
Away.