fully implemented chance tree AI
This commit is contained in:
parent
cdf6df64a4
commit
616f3a8db5
3 changed files with 986467 additions and 4 deletions
986410
TicTacToe_AI/Chancetree/boards.bds
Normal file
986410
TicTacToe_AI/Chancetree/boards.bds
Normal file
File diff suppressed because it is too large
Load diff
12
TicTacToe_AI/Chancetree/game.py
Normal file
12
TicTacToe_AI/Chancetree/game.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
from .main import Board
|
||||||
|
|
||||||
|
end = False
|
||||||
|
board = [0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0]
|
||||||
|
b = Board(barray=board)
|
||||||
|
while not end:
|
||||||
|
n = int(input('Enter field: '))
|
||||||
|
b.board[n] = -1
|
||||||
|
b.refresh()
|
||||||
|
print(b)
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
import copy
|
def boarddiff(b1, b2):
|
||||||
|
sums = [0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
for i, n in enumerate(b1.board):
|
||||||
|
sums[i] = n + b2.board[i]
|
||||||
|
|
||||||
|
for i, n in enumerate(sums):
|
||||||
|
if (n is 1) or (n is -1):
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
|
|
@ -7,6 +14,7 @@ class Board:
|
||||||
self.full = self.getfull()
|
self.full = self.getfull()
|
||||||
self.next = self.getnext() # Cross always starts
|
self.next = self.getnext() # Cross always starts
|
||||||
self.winner = self.getwinner()
|
self.winner = self.getwinner()
|
||||||
|
self.printversion = ','.join(str(x) for x in self.board)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
retstr = ''
|
retstr = ''
|
||||||
|
|
@ -24,6 +32,7 @@ class Board:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# check who is next
|
||||||
def getnext(self):
|
def getnext(self):
|
||||||
if self.full:
|
if self.full:
|
||||||
return None
|
return None
|
||||||
|
|
@ -37,6 +46,7 @@ class Board:
|
||||||
elif countdict[-1] < countdict[1]:
|
elif countdict[-1] < countdict[1]:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
# check who has won
|
||||||
def getwinner(self):
|
def getwinner(self):
|
||||||
# check rows
|
# check rows
|
||||||
if (sum(self.board[0:3]) is -3) or (sum(self.board[3:6]) is -3) or (sum(self.board[6:]) is -3):
|
if (sum(self.board[0:3]) is -3) or (sum(self.board[3:6]) is -3) or (sum(self.board[6:]) is -3):
|
||||||
|
|
@ -63,11 +73,18 @@ class Board:
|
||||||
elif (self.board[2] + self.board[4] + self.board[6]) is 3:
|
elif (self.board[2] + self.board[4] + self.board[6]) is 3:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
return None
|
return 0
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
self.next = self.getnext()
|
||||||
|
self.full = self.getfull()
|
||||||
|
self.winner = self.getwinner()
|
||||||
|
self.printversion = ','.join(str(x) for x in self.board)
|
||||||
|
|
||||||
|
# generate valid next boards
|
||||||
def nextboards(self):
|
def nextboards(self):
|
||||||
if self.full:
|
if self.full:
|
||||||
return
|
return []
|
||||||
else:
|
else:
|
||||||
newboards = []
|
newboards = []
|
||||||
for i, block in enumerate(self.board):
|
for i, block in enumerate(self.board):
|
||||||
|
|
@ -79,7 +96,7 @@ class Board:
|
||||||
|
|
||||||
b = Board(barray=arr)
|
b = Board(barray=arr)
|
||||||
b.board[i] = self.next
|
b.board[i] = self.next
|
||||||
b.next = b.getnext()
|
b.refresh()
|
||||||
newboards.append(b)
|
newboards.append(b)
|
||||||
|
|
||||||
return newboards
|
return newboards
|
||||||
|
|
@ -89,8 +106,14 @@ class Node:
|
||||||
def __init__(self, board):
|
def __init__(self, board):
|
||||||
self.board = board
|
self.board = board
|
||||||
self.children = self.genchildren()
|
self.children = self.genchildren()
|
||||||
|
self.worth = self.calcworth()
|
||||||
|
self.nextbest = self.getnextbest()
|
||||||
print('generated node of board: \n' + str(self.board))
|
print('generated node of board: \n' + str(self.board))
|
||||||
|
print('nextbest: ' + str(self.nextbest))
|
||||||
|
with open('boards.bds', 'a') as of:
|
||||||
|
of.write(self.board.printversion + '|' + str(self.nextbest) + '\n')
|
||||||
|
|
||||||
|
# generate children of node
|
||||||
def genchildren(self):
|
def genchildren(self):
|
||||||
children = []
|
children = []
|
||||||
for nextboard in self.board.nextboards():
|
for nextboard in self.board.nextboards():
|
||||||
|
|
@ -98,6 +121,24 @@ class Node:
|
||||||
children.append(n)
|
children.append(n)
|
||||||
return children
|
return children
|
||||||
|
|
||||||
|
def calcworth(self):
|
||||||
|
worth = 0
|
||||||
|
for b in self.children:
|
||||||
|
worth += b.board.winner
|
||||||
|
return worth
|
||||||
|
|
||||||
|
def getnextbest(self):
|
||||||
|
if not self.board.full:
|
||||||
|
highest = -9999999999
|
||||||
|
highchild = None
|
||||||
|
for child in self.children:
|
||||||
|
if child.worth > highest:
|
||||||
|
highest = child.worth
|
||||||
|
highchild = child
|
||||||
|
return boarddiff(self.board, highchild.board)
|
||||||
|
else:
|
||||||
|
return -1 # returns -1 as next best index if board is full
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
b = Board(barray=[0, 0, 0,
|
b = Board(barray=[0, 0, 0,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue