Skip to content

Instantly share code, notes, and snippets.

@sanketsudake
Created February 17, 2014 12:11
Show Gist options
  • Save sanketsudake/9049493 to your computer and use it in GitHub Desktop.
Save sanketsudake/9049493 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
"""
File :aitictac.py
Arficital Intelligence to play tictac toe
Using MinMax n-ply search algorithm
"""
class Board:
def __init__(self, board=[]):
self.boardvisual = {2: '-', 3:'X', 5: 'O' }
if board:
self.board = board
else:
self.board = [ 2 for i in range(0, 9)]
def visual_val(self, val):
return self.boardvisual[val]
def mark(self, val, pos):
self.board[pos] = val
def unmark(self, pos):
self.board[pos] = 2
def freepos(self):
return [ i for i, val in enumerate(self.board) if val == 2]
def heuristic(self):
max = ((0, 1, 2), (3, 4, 5), (6, 7, 8),
(0, 3, 6), (1, 4, 7), (2, 5, 8),
(0, 4, 8), (2, 4, 6))
values = [(self.board[k1], self.board[k2], self.board[k3]) for k1, k2, k3 in max]
#print(self.board)
count_occur = [ ( i.count(3), i.count(5)) for i in values]
x_win, o_win = 0, 0
for x_val, o_val in count_occur:
if not x_val and not o_val:
x_win += 1
o_win += 1
elif not x_val and o_val:
o_win += 1
elif x_val and not o_val:
x_win += 1
else:
pass
return x_win - o_win
def checkwin(self):
max = ((0, 1, 2), (3, 4, 5), (6, 7, 8),
(0, 3, 6), (1, 4, 7), (2, 5, 8),
(0, 4, 8), (2, 4, 6))
values = [(self.board[k1], self.board[k2], self.board[k3]) for k1, k2, k3 in max]
for i in values:
x_win, o_win = i.count(3), i.count(5)
if x_win == 3:
return 3
elif o_win == 3:
return 5
else:
pass
return 0
def __str__(self):
return "\n\t" + '\n ------------------------\n\t'.join(
[' |\t'.join(map(self.visual_val, self.board[i:i+3]))
for i in map(lambda x: x*3, range(3))])
class Game:
def __init__(self, board):
self.boardvisual = {2: '-', 3:'X', 5: 'O' }
self.choice = '-'
while self.choice not in ('X', 'O'):
self.choice = str(input("Select X or O: "))
self.board = board
if self.choice == 'X':
self.human_choice = 3
self.comp_choice = 5
self.game_start = 0
else:
self.comp_choice = 3
self.human_choice = 5
self.game_start = 1
self.play()
def play(self):
for i in range(9):
print(str(self.board))
win_val = self.board.checkwin()
if(win_val):
if win_val == 3:
print("X player won")
else:
print("O player won")
exit()
if self.game_start % 2:
self.comp()
else:
self.human()
self.game_start += 1
def human(self):
print('Human =>')
free_positions = self.board.freepos()
valid_positions = range(0, 9)
pos = -1
while (pos not in free_positions) or (pos not in valid_positions):
pos = int(input("Give position : "))
self.board.mark(self.human_choice, pos - 1)
def comp(self):
print('Computer =>')
if self.comp_choice == 5:
status = 0
else:
status = 1
depth = 2
self.board.mark(self.comp_choice,
self.minimax(Board(self.board.board.copy()), status, depth)[0])
def minimax(self, board, status=True, depth=2):
bestscore = -1
bestpos = -1
free_positions = board.freepos()
states = {}
for i in free_positions:
board.mark(self.comp_choice, i)
h_val = board.heuristic()
if h_val not in states.keys():
states[h_val] = []
states[h_val].append([i, Board(board.board.copy()), h_val])
board.unmark(i)
if(status):
next = states[max(states.keys())]
else:
next = states[min(states.keys())]
depth = depth - 1
if len(next) == 1 or not depth or len(free_positions) == 1:
pos, h_val = next[0][0], next[0][2]
return (pos, h_val)
states = []
i_index = -1
if status:
check_val= 1000
else:
check_val = -1000
for i, entry in enumerate(next):
local_value = self.minimax(entry[1], (not status), depth)
m_value = local_value[1]
#retvals.append([entry[0], entry[2], m_value[0], m_value[1]])
if status:
if m_value < check_val:
check_val = m_value
i_index = i
else:
if m_value > check_val:
check_val = m_value
i_index = i
pos , h_val= next[i_index][0], next[i_index][2]
return (pos, h_val)
def main():
g = Game(Board())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment