-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathengine.py
183 lines (161 loc) · 5.62 KB
/
engine.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/usr/bin/env python3
# from random import choice
from board import Board
from logic import genmove_logic
class Game:
def __init__(self, SIZE=19): # default testing size = 3
self.size = SIZE
self.komi = 6.5
self.white = 1
self.black = -1
self.id_ = ''
self.board = Board(self.size)
self.known_commands = ('protocol_version', 'name', 'version',
'known_command', 'list_commands',
'quit', 'boardsize', 'clear_board',
'komi', 'play', 'genmove')
self.info = self.known_commands[0:5]
self.admin = self.known_commands[5:9]
self.gameplay = self.known_commands[9:]
self.hist = [] # coords, not moves
def output(self, msg=''):
print('=' + self.id_ + msg + '\n')
def error(self, msg=''):
print('? ' + self.id_ + msg + '\n')
def receive_input(game):
"""Parse user input"""
user_in = input().split(' ')
try:
if user_in == ['']:
raise ValueError
if type(user_in[0]) == int:
game.id_, command, arg = user_in[0], user_in[1], user_in[2:]
else:
command, arg = user_in[0], user_in[1:]
except IndexError: # explicitly silenced
pass
except ValueError: # user_in is null
return 'no input', '', ''
return user_in, command, arg
def info(game, user_in, command, arg):
"""Returns queried GTP info command"""
if command == 'name':
game.output('goma')
elif command == 'version':
game.output('0.1.0')
elif command == 'protocol_version':
game.output('2')
elif command == 'known_command':
result = True if user_in.split(' ')[1] in game.known_commands else False
game.output(result)
elif command == 'list_commands':
print('=')
for item in game.known_commands:
print(item, sep="\n")
print('\n')
def gameplay(game, user_in, command, arg):
"""play() and genmove() are routed here"""
if command == 'play':
color, move = arg
if move == 'pass':
game.output()
return
elif ('W' in color) or ('w' in color):
play(game.white, move, game)
elif ('B' in color) or ('b' in color):
play(game.black, move, game)
game.board.asciiboard()
return
elif command == 'genmove':
if ('W' in user_in) or ('w' in user_in):
genmove(game.white, game)
elif ('B' in user_in) or ('b' in user_in):
genmove(game.black, game)
game.board.asciiboard()
return
game.error(f"{command} is not a valid move.")
def admin(game, user_in, command, arg):
if command == 'undo':
game.output('Cannot undo.')
if command == 'komi':
if arg and arg[0].replace('.', '', 1).isnumeric():
game.komi = arg
game.output()
elif arg:
game.error("Not valid komi")
else:
game.error("No komi given")
return
elif command == 'boardsize':
try:
if int(user_in[1]) > 19:
raise ValueError
if user_in[1].isnumeric():
new_size = int(user_in[1]) # everything becomes arbitrary
game.board.empty = [(row, col) for row in
range(new_size) for col in range(new_size)]
game.board.white = game.board.black = []
game.size = new_size
game.board.size = new_size
game.output()
return
except IndexError:
game.output('Please include an interger argument')
except ValueError:
game.output('Unacceptable size')
elif command == 'clear_board':
# everything becomes arbitrary
game.board.empty = [(row, col) for row in range(game.size)
for col in range(game.size)]
game.board.white = game.board.black = []
game.output()
elif command == 'quit':
game.output()
exit()
def game_round(game):
user_in, command, arg = receive_input(game)
if command in game.gameplay:
gameplay(game, user_in, command, arg)
elif command in game.info:
info(game, user_in, command, arg)
elif command in game.admin:
admin(game, user_in, command, arg)
else:
game.error(f"{user_in} is not a valid command")
game.error("Type 'list_commands' for valid commands")
return
def genmove(color, game):
if not game.board.empty:
return game.output('PASS')
row, col = genmove_logic(color, game)
if row is None:
game.output('PASS')
return
game.hist.append((row, col))
game.board.add_stone(row, col, color)
return game.output(coord_to_move(row, col, game.size))
def play(color, move, game):
row, col = move_to_coord(move, game.size)
if ((row, col) in [group for group in game.board.white]) or ((row, col) in [group for group in game.board.black]):
game.error('Illegal move, spot occupied.')
return
game.hist.append((row, col))
game.board.add_stone(row, col, color)
game.output()
def coord_to_move(row, col, size):
col = 'ABCDEFGHJKLMNOPQRST'[col]
row = int(row) + 1
move = str(col) + str(row)
return move
def move_to_coord(move, size):
row = ''
for k in move:
if k.isupper():
col = int('ABCDEFGHJKLMNOPQRST'.find(k))
if k.islower():
col = int('abcdefghjklmnopqrst'.find(k))
elif k.isnumeric():
row += k
if row.isnumeric():
row = int(row) - 1
return row, col