Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
all: run_computer
#all: run_interactive

run_computer:
./play.py

run_interactive:
@echo '"make vi" loads the files into vim'
./deep-tic.py

vi:
vim README Makefile deep-tic.py play.py
142 changes: 142 additions & 0 deletions deep-tic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/usr/bin/env python3
#from __future__ import print_function
#from ansi import *
import os
import random, os, argparse, time
import numpy as np
from random import randint
import sys
from play import *
import getch
from ansi import *

def getargs():
parser = argparse.ArgumentParser(description='Page undeformer')
#parser.add_argument('-v', '--viewfirst', action='store_true', help='View images before training')
return parser.parse_args()

args = getargs()
tz=0; tx=-1; to=1; # board values: unset, X, and O
bdim = 3 # might we expand from 3x3 to connect four ...?
num_players = 2 # might we have more than 2?
computer = 0 # index of computer (doubles as value for human winning)
human = 1 # index of human (doubles as value for wins/losses)
win_computer = 0 # computer wins, value
win_human = 1 # human wins, value
win_tie = .5 # tie (nobody wins), value
prompt_delay_default = 1 # seconds of delay for messages
prompt_delay = 0 # default, no delay

# Some printing conveniences (with flushing, in case we get elaborate)
def pf(*x, **y):
print(*x, **y); sys.stdout.flush()
def pfp(*x, **y):
y.setdefault('sep', ''); print(*x, **y); sys.stdout.flush()
def pfl(*x, **y):
y.setdefault('end', '')
print(*x, **y); sys.stdout.flush()
def pfpl(*x, **y):
y.setdefault('sep', ''); y.setdefault('end', '')
print(*x, **y); sys.stdout.flush()
def boardval_to_char(board,y,x):
cval = board[computer][y][x] # computer value
hval = board[human][y][x] # human value
return 'X' if hval else ('O' if cval else ' ')
def print_board(board):
for y in range(0,bdim):
pfp(" ", boardval_to_char(board,y,0), " | ",
boardval_to_char(board,y,1), " | ",
boardval_to_char(board,y,2))
def msgdelay():
time.sleep(prompt_delay)
def new_board():
return np.zeros((num_players,bdim,bdim))
def pause_toggle():
global prompt_delay
if not prompt_delay:
prompt_delay = prompt_delay_default
pf("Pause turned on")
else:
prompt_delay = 0
pf("Pause turned off")
def prompt_human_move():
while True:
pf ("uio 789 (T)oggle Pause")
pf ("jkl 456")
pfpl("m,. 123 Your move: ")
inp=getch.getch()
pf("INPUT:", inp[0])
if inp[0] in keymap:
pf("")
return keymap[inp[0]] # y,x pair
elif inp[0].upper() in options:
pfpl(" ")
options[inp[0].upper()]()
else:
pfp(yel, "I'm sorry, I don't understand that input. Try again.", rst)
msgdelay()
def init():
global keymap
global options
seed = 1
random.seed(seed)
keymap=dict()
keymap['7']=keymap['u']=(0,0)
keymap['8']=keymap['i']=(0,1)
keymap['9']=keymap['o']=(0,2)
keymap['4']=keymap['j']=(1,0)
keymap['5']=keymap['k']=(1,1)
keymap['6']=keymap['l']=(1,2)
keymap['1']=keymap['m']=(2,0)
keymap['2']=keymap[',']=(2,1)
keymap['3']=keymap['.']=(2,2)
options=dict()
options['T']=pause_toggle
pf('opt:', options['T'])
def get_computer_move(board):
return find_next_best_move(board, human)
def available_move(board, y, x):
if board[0][y][x] or board[1][y][x]:
return False
return True
init()
def playgame():
board = new_board()
player = randint(0,1) # initial move is player or computer
while True:
pf("\n\n================================================")
pf(board)
pf("\n------------------------------------------------\n")
print_board(board)
pf("")
if has_won(board, human):
pf(bcya, "\nYou won!", rst)
msgdelay();
notify_new_game(win_human)
break
elif has_won(board, computer):
pf(bmag, "\nComputer won!", rst)
msgdelay();
notify_new_game(win_computer)
break
elif is_board_full(board):
pf("\nThe glass is half empty. Everybody loses.")
msgdelay();
notify_new_game(win_tie)
break

if player == human:
y,x = prompt_human_move()
else:
pf("Please wait for computer's move...")
y,x = get_computer_move(board)
if player == human and not available_move(board, y, x):
pf(yel, "Position already played. Try again.", rst)
msgdelay()
else:
board[player][y][x] = 1
remember_game_board(board)
player = 0 if player else 1

while True:
playgame()
19 changes: 12 additions & 7 deletions play.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
import keras
from keras.models import Model
from keras.layers import Flatten, Dense, Dropout
from ansi import *
from os.path import isfile


# Call this like:

model = None
callbacks = []
weight_file = 'model_running.h5'

def makeModel():
global model, callbacks
Expand Down Expand Up @@ -39,16 +42,17 @@ def makeModel():

model.compile(loss='mse', optimizer=keras.optimizers.Adam(lr=0.001))
from keras.models import load_model
#model = load_weights('model_running.h5')
if isfile(weight_file):
model.load_weights(weight_file)

boardgames = []
whowon = []

def train():
global model, boardgames, whowon
makeModel()
#print("Boardgames is:", np.array(boardgames).shape, "whowon:", np.array(whowon).shape)
model.fit(np.array(boardgames), np.array(whowon), epochs=10, validation_split=0.2, shuffle=True,
print("Boardgames is:", np.array(boardgames).shape, "whowon:", np.array(whowon).shape)
model.fit(np.array(boardgames), np.array(whowon), epochs=20, validation_split=0.2, shuffle=True,
verbose=0, callbacks=callbacks)

# board[0,:,:] is for computer player. 0 if there's no piece and 1 if there is
Expand Down Expand Up @@ -76,20 +80,21 @@ def find_next_best_move(board, player):
best_x = x
best_y = y
best_prob_to_win = prob_to_win
#print("Best move is", best_x, best_y, "with probability to win: ", prob_to_win)
print("Best move is", best_x, best_y, "with probability to win: ", prob_to_win)
return best_x, best_y

def remember_game_board(board):
global current_game_boards
current_game_boards.append(board)

# whowon_ should be 1 if computer, 0 if person, 0.5 if tie
def notify_new_game(whowon_):
def notify_new_game(whowon_, dotrain=True):
global boardgames, whowon, current_game_boards
boardgames += current_game_boards
whowon += (np.ones(len(current_game_boards)) * whowon_).tolist()
current_game_boards = []
train()
if dotrain:
train()

def get_valid_moves(board):
valid_moves = []
Expand Down Expand Up @@ -128,7 +133,7 @@ def playGame():
def playAgainstSelfRandomly():
while True:
player_who_won, board = playAgainstSelfRandomly_()
notify_new_game(player_who_won)
notify_new_game(player_who_won, dotrain=(np.random.random()<.5))
printBoard(board)
print("Score:", player_who_won)
print()
Expand Down