restarting the search
[imago.git] / imago_pack / output.py
1 """Imago output module."""
2
3 import copy
4 import sys
5
6 COORDS = 'abcdefghijklmnopqrs'
7
8 class Board:
9     def __init__(self, size, stones):
10         self.stones = stones        
11         self.size = size
12
13     def __str__(self):
14         lines = []
15         k = 0
16         for i in range(self.size):
17             line = []
18             for j in range(self.size):
19                 line.append(self.stones[k])
20                 k += 1
21             lines.append(" ".join(line))
22         lines.append("")
23         return ("\n".join(lines))
24
25     def asSGFsetPos(self):
26         """Returns SGF (set position) representation of the position."""
27
28         #TODO version numbering
29         sgf = "(;FF[4]GM[1]SZ[" + str(self.size) + "]AP[Imago:0.1.0]\n"
30         sgf += self.SGFpos()
31         sgf += ")"
32         return sgf
33
34     def SGFpos(self):
35         black = []
36         white = []
37
38         for i in range(self.size):
39             for j in range(self.size):
40                 stone = self.stones[i * self.size + j]
41                 if stone == 'B':
42                     black.append(Move('B', i, j))
43                 elif stone == 'W':
44                     white.append(Move('W', i, j))
45         sgf = ""
46         if len(black) > 0:
47             sgf += "AB" + ''.join('[' + m.sgf_coords() + ']'
48                               for m in black) + "\n"
49         if len(white) > 0:
50             sgf += "AW" + ''.join('[' + m.sgf_coords() + ']' 
51                               for m in white) + "\n"
52         return sgf
53
54     def addMove(self, m):
55         self.stones[(m.y * self.size) + m.x] = m.color
56
57     def getMoveCandidates(self, board):
58         candidates = []
59         for i in range(self.size):
60             for j in range(self.size):
61                 if (self.stones[self.size * i + j] == "."):
62                     if (board.stones[self.size * i + j] == "W"):
63                         candidates.append(Move("W", i, j))
64                     elif (board.stones[self.size * i + j] == "B"):
65                         candidates.append(Move("B", i, j))
66         return candidates
67
68 class Move:
69     def __init__(self, color, y, x, comment=None):
70         self.color = color
71         self.x = x
72         self.y = y
73         self.comment = comment
74
75     def sgf_coords(self):
76         return COORDS[self.x] + COORDS[self.y]
77
78 class Game:
79     def __init__(self, size, board=None, debug=True):
80         self.init_board = board or Board(size, (size * size) * ".")
81         self.board = copy.deepcopy(self.init_board)
82         self.moves = []
83         self.size = size
84         self.debug = debug
85         self.debug_comment = ""
86
87     def addMove(self, board):
88         candidates = self.board.getMoveCandidates(board)
89         if self.debug:
90             comment = str(board)
91             comment += "Candidates: " + str(len(candidates))
92             
93         if not candidates:
94             self.debug_comment += "No candidates."
95             return
96
97         move = candidates[0]
98         move.comment = comment
99         self.moves.append(move)
100         self.board.addMove(move)
101
102     def asSGF(self):
103         sgf = "(;FF[4]GM[1]SZ[" + str(self.size) + "]AP[Imago:0.1.0]\n"
104         sgf += self.init_board.SGFpos()
105         for m in self.moves:
106             if m:
107                 sgf += ";" + m.color + "[" + m.sgf_coords() + "]"
108                 if m.comment:
109                     sgf += "C[" + m.comment + "]"
110                 sgf += "\n"
111         sgf += ")"
112         return sgf
113
114