This was one of my projects I’ve completed for an AI class I took during my college term. The project goal is to implement an AI game using one of the key algorithms we learned, Alpha-beta pruning. The game idea is simple: The player is to play against an AI. The win factor is that the player should have 4 pieces consecutively in a row or column. The programming language used was Python 3.1.
What is Alpha-beta pruning?
Read an clear explanation on Wikipedia, our implementation follows it directly. Here is the implementation for my code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def alphabeta(problem, alpha, beta, MaxPlayer, limit): global starttime if (time.clock() - starttime) >= limit or problem[0].isfull(): return problem if MaxPlayer: return maxstate(problem[0], alpha, beta, MaxPlayer) else: return minstate(problem[0], alpha, beta, MaxPlayer) def maxstate(problem, alpha, beta, MaxPlayer): for child in problem.getsuccessors('X'): clone = copy.deepcopy(problem) clone.move(child[1][0], child[1][1], 'X') node = (clone, child[1]) alpha = max(alpha, alphabeta(node, alpha, beta, not MaxPlayer, limit)) if beta[0].h <= alpha[0].h: break; return alpha def minstate(problem, alpha, beta, MaxPlayer): for child in problem.getsuccessors('O'): clone = copy.deepcopy(problem) clone.move(child[1][0], child[1][1], 'O') node = (clone, child[1]) beta = min(beta, alphabeta(node, alpha, beta, not MaxPlayer, limit)) if beta[0].h <= alpha[0].h: break; return beta |
How the AI chooses the best possible move:
I will give a very general explanation. Please read the Wikipedia link for a elaborate explanation.
1.) Given an player’s move, the AI will generate a minimax tree till the search limit time is reached. In other words: Predict player’s next move and then find my best move. Iterate this n-levels deep.
2.) For each move the AI predicts, give it an score. The evaluation function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | def getsum(self, string): sum = 0 superbad = -5000 bad1 = -100 bad2 = -75 bad3 = -50 bad4 = -25 bad5 = -1 supergood = 5000 good1 = 100 good2 = 75 good3 = 50 good4 = 25 good5 = 1 #opponent if 'OOOO' in string: sum += superbad if '-OOO-' in string: sum += bad1 if 'OOO-' in string: sum += bad1 if '-OOO' in string: sum += bad1 if 'OO-O' in string: sum += bad2 if 'O-OO' in string: sum += bad2 if 'O-OO-' in string: sum += bad2 if '-OO-O' in string: sum += bad2 if '-O-OO' in string: sum += bad2 if 'OO-O-' in string: sum += bad2 if '-OO-' in string: sum += bad2 if '-OO' in string: sum += bad3 if 'OO-' in string: sum += bad3 if 'O-O-' in string: sum += bad4 if '-O-O' in string: sum += bad4 if '-O-O-' in string: sum += bad2 if 'O-O' in string: sum += bad5 if 'OO' in string: sum += bad5 if '-O-' in string: sum += bad5 ..... |
3.) The AI will consider all the player’s moves that are against itself and find its worse case.
4.) The AI evaluates itself to find it’s best move to counter the player’s move.
Disadvantage:
Our Design: Too many combinations of player’s moves to evaluate, therefore AI may not make the best move in our consideration.
Strength:
Python’s fast sorting. Alpha-beta pruning which cuts off any worse-off moves from consideration.
Try it out!
An python installation is required. Please make sure you have already installed on your computer, Python 3.1+.
connect4.py [Download]
Download the above file and open it. Enter an time you want the AI to search for an solution. For example, enter 5 for 5 seconds.
