forked from ayushv/entropy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.py
109 lines (82 loc) · 2.7 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# client.py:
# python2 client.py <port> <address> <botname> <path_to_run.sh> <delay>
# purpose:
# - language independence for AI coders
# - better control for killing, resetting
# - tournament can be (partially/fully) automated at server side
# TO TEST: what if a client segfaults - hopefully controlled?
from subprocess import Popen, PIPE
import sys, socket, json, time
import os
sys.path.insert(0, os.path.realpath('../utils/'))
from nbstreamreader import NonBlockingStreamReader as NBSR
botname = 'bazooka' # PLEASE CHOOSE A UNIQUE BOTNAME
SAFETY_TIMEOUT = 65 # For dumb clients, who think too much or die while thinking
server_address = 'localhost'
server_port = 8000
aiProc = None
advStdout = None
pathToRun = 'run.sh'
# print >>sys.stderr, repr(sys.argv)
if (len(sys.argv) > 1):
server_port = int(sys.argv[1])
if (len(sys.argv) > 2):
server_address = sys.argv[2]
if (len(sys.argv) > 3):
botname = sys.argv[3]
if (len(sys.argv) > 4):
pathToRun = sys.argv[4]
if (len(sys.argv) > 5):
delay = float(sys.argv[5])
time.sleep(delay)
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect((server_address, server_port))
clientsocket.send(botname)
print '%s connected to server (hopefully)'% botname
if (botname != 'TA-AI'):
print ('extra options: python client.py <optional-port> <address>')
def resetCode(args):
global aiProc, advStdout
if (aiProc != None):
aiProc.kill()
aiProc = Popen (['sh', pathToRun], stdin = PIPE, stdout = PIPE, bufsize=0)
advStdout = NBSR(aiProc.stdout)
def updateCode(args):
try:
aiProc.stdin.write(args['payload'])
my_move = advStdout.readline(SAFETY_TIMEOUT)
except:
print 'Something bad happened with the client (# need to kill it?)'
my_move = None
print 'My move (%s): %s'%(botname, my_move)
if not my_move:
# idiot bot still thinking :-/
payload = json.dumps({'status': False, 'comment': 'timeout'})
else:
payload = json.dumps({'payload': my_move, 'status': True})
clientsocket.send(payload)
safety_count = 1
SAFETY_MAX_CHATTER = 1000 # this is safe unless n >
# wait for command...
while True:
data = clientsocket.recv(1024)
safety_count += 1
if (safety_count > SAFETY_MAX_CHATTER):
print 'too much talking: killing and exiting \
\n - this is not student\'s fault (hopefully). Sorry'
aiProc.kill()
exit(0)
if (len(data) <= 0):
continue
dct = json.loads(data)
# print 'packet recv:', dct
if (dct['purpose'] == 'reset'):
safety_count = 0
resetCode(dct)
elif (dct['purpose'] == 'kill'):
safety_count = 0
aiProc.kill()
elif (dct['purpose'] == 'update'): # this is actually update and wait for output
updateCode(dct)
elif (dct['purpose'] == 'update_only'):
aiProc.stdin.write(dct['payload'])