Skip to content

Instantly share code, notes, and snippets.

@limitpointinf0
Last active April 28, 2018 06:07
Show Gist options
  • Save limitpointinf0/ed4f8a9861d65515a1a510e225ecd728 to your computer and use it in GitHub Desktop.
Save limitpointinf0/ed4f8a9861d65515a1a510e225ecd728 to your computer and use it in GitHub Desktop.
Random Tic Tac Toe Game Simulator
"""
This script was created for the purpose of machine learning on tic-tac-toe.
You may extend the board to any square size.
the script will write to two csv files: one for predictors and the other for target
Special predictor Values:
dd - filled space from either player winning to pad the empty spaces
Target Variable Values:
1 - Player 1 has won
0 - Player 1 has lost
SM - Stalemate
"""
import itertools
import numpy as np
import random
import string
import time
#player has the ability to examine the board for possible moves and choose a random blank space to play on
class Player():
def __init__(self, piece):
"""piece - numerical value representing that player's piece"""
self.piece = piece
def examine(self, b):
"""examine the board b for any empty spaces"""
free_space = [(i,j) for i,j in itertools.product(range(b.shape[0]), range(b.shape[1])) if b[i,j] == 0]
return free_space
def play_random(self, b, available):
"""make a random move from the available spaces. Should pass the output of examine as the parameter available"""
r = random.choice(available)
b[r[0], r[1]] = self.piece
return r
"""
The following functions are self explanatory. Checking horizontals, verticals, and diagonals for any wins.
b should be a square numpy array
side will be the length of the side of b
"""
def check_horiz(b, side):
win = False
way = 'no win'
for i in range(side):
if (list(b[i]).count(b[i][0]) == len(b[i])) & (b[i][0] != 0):
way = 'horizontal row {}'.format(i)
win = True
return (win, way)
def check_vert(b, side):
win = False
way = 'no win'
for i in range(side):
if (list(b[:,i]).count(b[0,i]) == len(b[:,i])) & (b[0,i] != 0):
way = 'vertical column {}'.format(i)
win = True
return (win, way)
def check_diag(b, side):
win = False
way = 'no win'
d_1 = [b[i,i] for i in range(side)]
d_2 = [b[i,(side-1)-i] for i in range(side)]
if ((d_1.count(d_1[0]) == len(d_1)) & (d_1[0] != 0)) | ((d_2.count(d_2[0]) == len(d_2)) & (d_2[0] != 0)):
way = 'diagonal'
win = True
return (win, way)
#check end game
def check_end(b, side):
"""check if the game has ended. Pass the side length of the board to side"""
end = True
for i,j in itertools.product(range(side), range(side)):
if b[i,j] == 0:
end = False
return end
def fill_blank(sequence, tup, length):
"""fill any blank spaces. tup is the tuple you want to fill black spaces with (use a coordinate not on the board).
length for the amount of spaces on the empty board.
"""
s = sequence
n = length - len(s)
if n > 0:
for i in range(n):
s.append(tup)
return s
def encode_abc(tup):
"""encode 2dim tuple coodinates to alphabetical code for example (1,2) == bc"""
return string.ascii_lowercase[tup[0]] + string.ascii_lowercase[tup[1]]
dummy1 = Player(1)
dummy2 = Player(2)
#set side length of the board and initialize win sequence
side_length = 3
wins = []
#run this game for 1000 iterations
for i in range(1000):
board = np.array([[0 for x in range(side_length)] for y in range(side_length)])
this_game = []
while True:
#player one moves
free_1 = dummy1.examine(board)
played_1 = dummy1.play_random(board, free_1)
this_game.append(played_1)
if sum([check_horiz(board,side_length)[0], check_vert(board,side_length)[0], check_diag(board,side_length)[0]]) >= 1:
wins.append(1)
this_game = fill_blank(this_game, (3,3), 9)
print(this_game)
print('dummy 1 wins')
break
#check if the board is filled and if there are no winners, SM: stalemate
end = check_end(board, side_length)
if end and (sum([check_horiz(board,side_length)[0], check_vert(board,side_length)[0], check_diag(board,side_length)[0]]) == 0):
wins.append('SM')
print('SM')
break
#player two moves
free_2 = dummy2.examine(board)
played_2 = dummy2.play_random(board, free_2)
this_game.append(played_2)
if sum([check_horiz(board,side_length)[0], check_vert(board,side_length)[0], check_diag(board,side_length)[0]]) >= 1:
wins.append(0)
this_game = fill_blank(this_game, (3,3), 9)
print(this_game)
print('dummy 2 wins')
break
#check if the board is filled and if there are no winners, SM: stalemate
end = check_end(board, side_length)
if end and (sum([check_horiz(board,side_length)[0], check_vert(board,side_length)[0], check_diag(board,side_length)[0]]) == 0):
wins.append('SM')
print('SM')
break
#encode tuple play sequence into alphabet code
ab_coords = [encode_abc(x) for x in this_game]
print(ab_coords)
with open('predictors.csv','a+') as f:
f.write(','.join(ab_coords)+'\n')
print(wins)
with open('target_var.csv','a+') as f:
f.write(','.join([str(x) for x in wins])+'\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment