Commit b01f7ce5 authored by Michele's avatar Michele

created purposes for tic tac toc, still thre is something wrong

parent 7b15af6c
......@@ -30,26 +30,28 @@ sys.path.append(currentdir)
import socket
import logging
import itertools
from tictacteacher import TicTacToeTeacher
from tictacoracle import TicTacToeOracle
from tictacpurpose import InputPurpose, OutputPurpose
from systems.iopurpose import InputPurpose, OutputPurpose
from learning.learning import LearningAlgorithm
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
HOST = 'localhost'
PORT = 29001 # Arbitrary non-privileged port
PORT = 29000 # Arbitrary non-privileged port
inputs = set(['0','1','2','3','4','5','6','7','8'])
outputs = set(['x','y'])
outputs = set(itertools.product('XO_', repeat=9))
quiescence = 'delta'
outputExpert = OutputPurpose(set(['x','y', quiescence]))
inputExpert = InputPurpose(set(['0','1','2','3','4','5','6','7','8']))
outputExpert = OutputPurpose()
inputExpert = InputPurpose()
T1 = TicTacToeTeacher(HOST, PORT, quiescence)
T1 = TicTacToeTeacher(HOST, PORT)
O1 = TicTacToeOracle()
tester = None
......@@ -61,6 +63,8 @@ path = os.path.join(currentdir, "dotFiles")
print("Starting learning...")
#print(T1.oneOutput(('1')))
L = LearningAlgorithm(T1, O1, printPath=path, maxLoops=4,
tablePreciseness=10000, logger=logger, tester=tester, outputPurpose=outputExpert,
inputPurpose=inputExpert)
......@@ -68,6 +72,8 @@ minus, plus = L.run()
print("Models learned.")
T1.close()
# while True:
#
# data = s.recv(1024)
......
......@@ -38,4 +38,6 @@ class TicTacToeOracle(AbstractOracle):
# trace is a list of inputs and or outputs
# outputs is the set of outputs observed so far (after trace)
def observation(self, trace, outputs):
return True
if len(outputs) > 0:
return True
return False
# Copyright (c) 2015 Michele Volpato
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Classes representing experts for input and output labels for tic tac toe
import os, inspect, sys
# Include project dir in path
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
currentdir = os.path.dirname(currentdir)
currentdir = os.path.dirname(currentdir)
sys.path.append(currentdir)
from systems.basepurpose import Purpose
import itertools
class InputPurpose(Purpose):
def __init__(self):
pass
# Given a trace returns the set of inputs enabled after it.
def getEnabled(self, trace):
# If the trace ends with an input, return empty set, Otherwise the
# entire set of inputs
#TODO: can be improved by removing from inputs those already in the trace
#TODO: can be further improved by checking outputs in trace for cells occupied by player 2
inputs = set(['0','1','2','3','4','5','6','7','8'])
if (trace != None and len(trace) > 0 and trace[-1] in inputs):
return set()
else:
return inputs
class OutputPurpose(Purpose):
def __init__(self):
pass
# Given a trace returns the set of outputs enabled after it.
def getEnabled(self, trace):
# If the trace ends with an output, only quiescence is enabled
# TODO improve here
inputs = set(['0','1','2','3','4','5','6','7','8'])
if (trace != None and len(trace) > 0 and trace[-1] not in inputs):
return set(['delta'])
else:
return set(itertools.product('XO_', repeat=9))
......@@ -30,26 +30,27 @@ import socket
import logging
import sys
import select
import itertools
from teachers.baseteacher import AbstractTeacher
# Teacher for Tic Tac Toe.
class TicTacToeTeacher(AbstractTeacher):
def __init__(self, host, port, quiescence):
self._quiescence = quiescence
def __init__(self, host, port):
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._socket.connect((host, port))
self._outputs = set(itertools.product('XO_', repeat=9))
#Receiving confirmation from game
data = self._socket.recv(1024)
if data.decode("utf-8") != "CONNECTED\n":
logger.error("Cannot connect.")
sys.exit()
self._socket.setblocking(0)
#self._socket.settimeout(1) # 1 second timeout, for quiescence
#self._socket.setblocking(0)
self._socket.settimeout(1) # 1 second timeout, for quiescence
#logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
......@@ -59,48 +60,61 @@ class TicTacToeTeacher(AbstractTeacher):
# trace is a list of inputs and or outputs
def process(self, trace):
# reset SUL
self._socket.sendall(bytes("9", 'UTF-8'))
reset = self.reset()
if not reset:
logger.error("Cannot reset.")
return False
output = None
if len(trace) == 0:
# Get output for the empty trace
ready = select.select([self._socket], [], [], 1) # 1 second timeout, for quiescence
output = self._quiescence
output = 'delta'
if ready[0]:
output = self._socket.recv(1024)
output = self._socket.recv(1024).decode("utf-8")
for action in trace:
# TODO finish here, maybe not needed
print(ddd)
return None
return output
# TODO arrived here!
# Provide a sequence of inputs (possibly one or even zero) end get an output
# Tic Tac Toe is a mealy machine like game, there is alternation of input and
# output. This must be defined in inputExpert
def oneOutput(self, actions):
for i in range(len(actions)):
if self._lts.move(actions[i]) == None:
return None
self._socket.sendall(bytes(str(actions[i]), 'UTF-8'))
return self.output()
# Provide output from current state
def output(self):
# Select a randomic output for current state
output = random.sample(self._lts.outputs(), 1)[0]
self._lts.move(output)
ready = select.select([self._socket], [], [], 1) # 1 second timeout, for quiescence
output = 'delta'
if ready[0]:
output = self._socket.recv(1024).decode("utf-8")
return output
# Reset the SUT
def reset(self):
self._lts.reset()
# reset SUL
self._socket.sendall(bytes("9", 'UTF-8'))
grid = self._socket.recv(1024).decode("utf-8")
if grid == "012345678":
return True
return False
# Get the input alphabet
def getInputAlphabet(self):
return self._lts.getInputs()
return set(['0','1','2','3','4','5','6','7','8'])
# Get the output alphabet
def getOutputAlphabet(self):
return self._lts.getOutputs()
return self._outputs
# Get quiescence
def getQuiescence(self):
return self._lts.getQuiescence()
return 'delta'
# Close connection
def close(self):
self._socket.sendall(bytes("EXIT\r\n", 'UTF-8'))
......@@ -27,6 +27,7 @@ import random
random.seed(100)
import socket
import sys
import logging
turn = -1
xWon = 0
......@@ -350,7 +351,7 @@ def in_line_board():
for j in range(9):
char = cells[j]
if char == '':
char = str(j)
char = '_'
ret = ret + char
......@@ -364,27 +365,30 @@ if __name__ == "__main__":
# 0 to 8 for moves, 9 for reset
HOST = 'localhost'
PORT = 29001 # Arbitrary non-privileged port
PORT = 29000 # Arbitrary non-privileged port
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
logger.info('Socket created')
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
logger.error('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print('Socket bind complete')
logger.info('Socket bind complete')
#Start listening on socket
s.listen(1) # only 1 connection
print('Socket now listening')
logger.info('Socket now listening')
#wait to accept a connection - blocking call
conn, addr = s.accept()
print("Connected with client")
logger.info("Connected with client")
conn.send(bytes('CONNECTED\n', 'UTF-8'))
......@@ -392,13 +396,16 @@ if __name__ == "__main__":
#Receiving from client
data = conn.recv(1024)
if not data or data.decode("utf-8") == "EXIT":
if not data or str(data.decode("utf-8")) == "EXIT\r\n":
break
move1 = int(data.decode("utf-8"))
logger.debug("Received: " + str(move1))
if move1 == 9:
newGame()
logger.debug("Resetting")
elif (move1 > 9 or move1 < 0):
pass
else:
......@@ -408,22 +415,24 @@ if __name__ == "__main__":
state = getState()
winner = detectWin(state)
if winner != 0:
conn.sendall(bytes("END\n", 'UTF-8'))
logger.debug("Sending: END ")
conn.sendall(bytes("END", 'UTF-8'))
newGame()
# build an output
# 0O2X4O6X8 stands for
# | 0 | O | 2 |
# | X | 4 | O |
# | 6 | X | 8 |
# _O_X_O_X_ stands for
# | _ | O | _ |
# | X | _ | O |
# | _ | X | _ |
board = in_line_board()
logger.debug("Sending: " + board)
conn.sendall(bytes(board, 'UTF-8'))
logger.debug("Sending: EXIT")
conn.sendall(bytes("EXIT", 'UTF-8'))
# out of loop
conn.close()
s.close()
print("Socket closed")
logger.info("Socket closed")
......@@ -301,7 +301,7 @@ class LearningAlgorithm:
closingRows = self._table.isNotGloballyClosed()
print("found rows to close")
consistentCheck = self._table.isNotGloballyConsistent()
print("found rows to consistehnt")
print("found rows to consistent")
while closingRows or consistentCheck:
while closingRows:
self._logger.info("Closing table")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment