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
|
"""Handles translation of input text to internal data and vice versa."""
import re
from enum import Enum, auto as enumAuto
from imago.data.enums import Player
VALID_WHITE_STRINGS = {
"W",
"WHITE"
}
VALID_BLACK_STRINGS = {
"B",
"BLACK"
}
def parseMove(args, boardsize):
"""Converts the textual representation of a move to a move instance."""
if len(args) != 2:
raise RuntimeError(
"Unable to transform string [%s] to move: Wrong format."
% args)
color = parseColor(args[0])
vertex = parseVertex(args[1], boardsize)
return GtpMove(color, vertex)
def parseColor(text):
"""Returns color of a move given its input string."""
textUpper = text.upper()
if textUpper in VALID_WHITE_STRINGS:
return Player.WHITE
if textUpper in VALID_BLACK_STRINGS:
return Player.BLACK
raise RuntimeError("Unknown color [%s]." % text)
def parseVertex(text, boardSize):
"""Returns row and column of a vertex given its input string. A vertex can also be the
string "pass".
GTP uses A1 style notation: columns are letters left to right, rows are number bottom
to top.
"""
text = text.upper()
if not re.match("^[A-HJ-Z][1-9][0-9]*$", text):
if text == "PASS":
return "pass"
raise RuntimeError(
"Unable to transform string [%s] to vertex. Wrong format."
% text)
vertexCol = ord(text[0])
# Column 'I' does not exist
if vertexCol > ord('I'):
vertexCol -= 1
vertexCol -= ord('A')
vertexRow = boardSize - int(text[1:])
if (vertexCol < 0 or vertexRow < 0
or vertexCol >= boardSize or vertexRow >= boardSize):
raise RuntimeError(
"Unable to transform string [%s] to vertex. Maps to [%d, %d], which is out of board bounds (size [%d])"
% (text, vertexCol, vertexRow, boardSize))
return (vertexRow, vertexCol)
def vertexToString(vertex, boardSize):
"""Returns a string representing the vertex.
GTP uses A1 style notation: columns are letters left to right, rows are number bottom
to top.
"""
if vertex == "pass":
return "pass"
if len(vertex) != 2:
raise RuntimeError(
"Unable to transform vertex [%s] to string. Too many elements."
% str(vertex))
if vertex[0] >= boardSize or vertex[1] >= boardSize or vertex[0] < 0 or vertex[1] < 0:
raise RuntimeError(
"Unable to transform vertex [%s] to string. Vertex out of board bounds (size [%d])"
% (str(vertex), boardSize))
vertexRow = boardSize - vertex[0]
vertexCol = ord('A') + vertex[1]
# Column 'I' does not exist
if vertexCol >= ord('I'):
vertexCol += 1
return "%s%d" % (chr(vertexCol), vertexRow)
class GtpMove:
"""Stores the info of a move according to GTP specification: color and vertex."""
def __init__(self, color, vertex):
self.color = color
self.vertex = vertex
|