判子草案
shhgs <"".join(chr(ord(c) -2) for c in 'ujjiu0ghjknvBiockn0eqo')> 贡献 请大家共同参详
shhgs对程序算法的一个简单的介绍:
首先我把棋子分成4类,border, available, white, black。黑白好理解,available就是没有放棋子的地方,border就是边界。棋盘是21×21的,最外圈都是border,里面初始化的时候都设成available,下了黑子,就变成black,下了白子就变成white,反正每个交叉点上都必须有一个棋子。
然后每个棋子都保留一个board对象,相当于parent。棋子要通过这个board访问它左右上下的邻居。
block是个数据结构。所有属于同一块的棋子都放在一个block里面。然后把所有的block放在一个叫blocks的list里面。
扫描整个棋盘,碰到一个棋子就检查blocks。具体方法是检查这个棋子的上下左右的邻居,看这个邻居是属于哪个block的。然后把棋子加到这个block里面。如果一个棋子同时属于两个或两个以上的block,那就必须把这几个block合并,放到blocks里面,同时把原先的block删除,如果棋子不属于任何一个block,就创建一个新的block放到blocks里面。
计算气。很简单,逐个扫描block里面的棋子,看它上下左右的邻居是不是available的,是就放到一个set里面,然后这个set的长度就是这块棋的气。
1 #coding=cp936
2
3 WHITE = "WHITE"
4 BLACK = "BLACK"
5 BORDER = "BORDER"
6 AVAILABLE = "AVAILBALE"
7
8 class Board(object) :
9 def __init__(self) :
10 self.stones = []
11 self.initialize()
12 def initialize(self) :
13 for i in range(0, 21) :
14 self.stones.append([None,] * 21)
15 for x in (0, 20) :
16 for y in range(0, 21) :
17 self.stones[x][y] = Stone(self, BORDER, x, y)
18 for y in (0, 20) :
19 for x in range(0, 21) :
20 self.stones[x][y] = Stone(self, BORDER, x, y)
21 for x in range(1, 20) :
22 for y in range(1, 20) :
23 self.stones[x][y] = Stone(self, AVAILABLE, x, y)
24 def __str__(self) :
25 result = ""
26 for y in range(0, 21) :
27 line = ""
28 for x in range(0, 21) :
29 line += str(self.stones[x][y])
30 result = line + '\n' + result
31 return result
32 def WipeBlock(self, block) :
33 for stone in block :
34 x = stone.X
35 y = stone.Y
36 self.stones[x][y] = Stone(self, AVAILABLE, x, y)
37 def __iter__(self) :
38 stones = []
39 for x in range(1, 20) :
40 for y in range(1, 20) :
41 stones.append(self.stones[x][y])
42 return iter(stones)
43 def GetBlocks(self) :
44 result = []
45 for stone in self :
46 if stone.Color not in (BLACK, WHITE) :
47 continue
48 neighbor_blocks = []
49 for block in result :
50 if block.AddStone(stone) :
51 neighbor_blocks.append(block)
52 if len(neighbor_blocks) == 0 :
53 new_block = Block.CreateBlock(stone)
54 result.append(new_block)
55 elif len(neighbor_blocks) >= 2 :
56 result.append(Block.merge(neighbor_blocks))
57 for block in neighbor_blocks :
58 result.remove(block)
59 return result
60 def AddStone(self, stone) :
61 x = stone.X
62 y = stone.Y
63 self.stones[x][y] = stone
64 if stone.Color == WHITE :
65 my = WHITE
66 other = BLACK
67 else :
68 my = BLACK
69 other = WHITE
70 blocks = self.GetBlocks()
71 for block in blocks :
72 if block.Color == other and block.Breath == 0 :
73 self.WipeBlock(block)
74 blocks = self.GetBlocks()
75 for block in blocks :
76 if block.Color == my and block.Breath == 0 :
77 self.WipeBlock(block)
78
79 class Block(object) :
80 def __init__(self, color) :
81 assert color in (BLACK, WHITE)
82 self.stones = set()
83 self.color = color
84 @property
85 def Color(self) :
86 return self.color
87 def AddStone(self, stone) :
88 if stone.color != self.color :
89 return False
90 if len(self.stones) == 0 :
91 self.stones.add(stone)
92 return True
93 for direction in ('Up', 'Down', 'Left', 'Right') :
94 neighbor = getattr(stone, direction)
95 if neighbor in self.stones :
96 self.stones.add(stone)
97 return True
98 else :
99 return False
100 def __iter__(self) :
101 return iter(self.stones)
102 @classmethod
103 def merge(self, blocks) :
104 newBlock = Block(blocks[0].Color)
105 for block in blocks :
106 for stone in block :
107 newBlock.stones.add(stone)
108 return newBlock
109 @classmethod
110 def CreateBlock(self, stone) :
111 if stone.Color not in (BLACK, WHITE) :
112 return
113 block = Block(stone.color)
114 block.stones.add(stone)
115 return block
116 @property
117 def Breath(self) :
118 breaths = set()
119 for stone in self.stones :
120 for direction in ('Up', 'Down', 'Left', 'Right') :
121 neighbor = getattr(stone, direction)
122 if neighbor.IsAvailable :
123 breaths.add(neighbor)
124 return len(breaths)
125 def __str__(self) :
126 result = "------------------------\n"
127 for s in self.stones :
128 result += repr(s) + "\n"
129 result += "------------------------"
130 return result
131
132 class Stone(object) :
133 def __init__(self, board, color , x, y) :
134 assert color in (BLACK, WHITE, BORDER, AVAILABLE)
135 self.board = board
136 self.color = color
137 self.x = x
138 self.y = y
139 def __repr__(self) :
140 return "<%s %d, %d>" % (self.Color, self.X, self.Y)
141 @property
142 def X(self) :
143 return self.x
144 @property
145 def Y(self) :
146 return self.y
147 @property
148 def Color(self) :
149 return self.color
150 @property
151 def IsBorder(self) :
152 if self.X in (0, 20) or self.Y in (0, 20) :
153 return True
154 else :
155 return False
156 @property
157 def IsBlack(self) :
158 return self.color == BLACK
159 @property
160 def IsWhite(self) :
161 return self.color == WHITE
162 @property
163 def IsAvailable(self) :
164 return self.color == AVAILABLE
165 def __str__(self) :
166 if self.IsBorder :
167 if (self.X == 20) and (self.Y in (0, 20)):
168 return '-+'
169 elif (self.X == 0) and (self.Y in (0, 20)):
170 return "+"
171 elif self.Y in (0, 20) :
172 return "--"
173 elif self.X == 20:
174 return ' |'
175 else:
176 return '|'
177 elif self.IsBlack :
178 return ' X'
179 elif self.IsWhite :
180 return ' O'
181 else :
182 return ' .'
183 def __eq__(self, other) :
184 try :
185 assert type(self) == type(other)
186 assert self.color == other.color
187 assert self.board == other.board
188 assert self.X == other.X
189 assert self.Y == other.Y
190 return True
191 except :
192 return False
193 def __ne__(self, other) :
194 return not self == other
195 @property
196 def Up(self) :
197 x = self.x
198 y = self.y + 1
199 return self.board.stones[x][y]
200 @property
201 def Down(self) :
202 x = self.x
203 y = self.y - 1
204 return self.board.stones[x][y]
205 @property
206 def Left(self) :
207 x = self.x - 1
208 y = self.y
209 return self.board.stones[x][y]
210 @property
211 def Right(self) :
212 x = self.x + 1
213 y = self.y
214 return self.board.stones[x][y]
215
216 if __name__ == "__main__" :
217 board = Board()
218 TURNS = (BLACK, WHITE)
219 round = 0
220 while 1 :
221 turn = TURNS[round % 2]
222 round += 1
223 x = int(raw_input("x: "))
224 if x == 0 :
225 break
226 y = int(raw_input("y: "))
227 stone = Stone(board, turn, x, y)
228 board.AddStone(stone)
229 print board