##在这里详述"PyIgoPys". === 判子草案 === ''' 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的长度就是这块棋的气。 {{{#!python #coding=cp936 WHITE = "WHITE" BLACK = "BLACK" BORDER = "BORDER" AVAILABLE = "AVAILBALE" class Board(object) : def __init__(self) : self.stones = [] self.initialize() def initialize(self) : for i in range(0, 21) : self.stones.append([None,] * 21) for x in (0, 20) : for y in range(0, 21) : self.stones[x][y] = Stone(self, BORDER, x, y) for y in (0, 20) : for x in range(0, 21) : self.stones[x][y] = Stone(self, BORDER, x, y) for x in range(1, 20) : for y in range(1, 20) : self.stones[x][y] = Stone(self, AVAILABLE, x, y) def __str__(self) : result = "" for y in range(0, 21) : line = "" for x in range(0, 21) : line += str(self.stones[x][y]) result = line + '\n' + result return result def WipeBlock(self, block) : for stone in block : x = stone.X y = stone.Y self.stones[x][y] = Stone(self, AVAILABLE, x, y) def __iter__(self) : stones = [] for x in range(1, 20) : for y in range(1, 20) : stones.append(self.stones[x][y]) return iter(stones) def GetBlocks(self) : result = [] for stone in self : if stone.Color not in (BLACK, WHITE) : continue neighbor_blocks = [] for block in result : if block.AddStone(stone) : neighbor_blocks.append(block) if len(neighbor_blocks) == 0 : new_block = Block.CreateBlock(stone) result.append(new_block) elif len(neighbor_blocks) >= 2 : result.append(Block.merge(neighbor_blocks)) for block in neighbor_blocks : result.remove(block) return result def AddStone(self, stone) : x = stone.X y = stone.Y self.stones[x][y] = stone if stone.Color == WHITE : my = WHITE other = BLACK else : my = BLACK other = WHITE blocks = self.GetBlocks() for block in blocks : if block.Color == other and block.Breath == 0 : self.WipeBlock(block) blocks = self.GetBlocks() for block in blocks : if block.Color == my and block.Breath == 0 : self.WipeBlock(block) class Block(object) : def __init__(self, color) : assert color in (BLACK, WHITE) self.stones = set() self.color = color @property def Color(self) : return self.color def AddStone(self, stone) : if stone.color != self.color : return False if len(self.stones) == 0 : self.stones.add(stone) return True for direction in ('Up', 'Down', 'Left', 'Right') : neighbor = getattr(stone, direction) if neighbor in self.stones : self.stones.add(stone) return True else : return False def __iter__(self) : return iter(self.stones) @classmethod def merge(self, blocks) : newBlock = Block(blocks[0].Color) for block in blocks : for stone in block : newBlock.stones.add(stone) return newBlock @classmethod def CreateBlock(self, stone) : if stone.Color not in (BLACK, WHITE) : return block = Block(stone.color) block.stones.add(stone) return block @property def Breath(self) : breaths = set() for stone in self.stones : for direction in ('Up', 'Down', 'Left', 'Right') : neighbor = getattr(stone, direction) if neighbor.IsAvailable : breaths.add(neighbor) return len(breaths) def __str__(self) : result = "------------------------\n" for s in self.stones : result += repr(s) + "\n" result += "------------------------" return result class Stone(object) : def __init__(self, board, color , x, y) : assert color in (BLACK, WHITE, BORDER, AVAILABLE) self.board = board self.color = color self.x = x self.y = y def __repr__(self) : return "<%s %d, %d>" % (self.Color, self.X, self.Y) @property def X(self) : return self.x @property def Y(self) : return self.y @property def Color(self) : return self.color @property def IsBorder(self) : if self.X in (0, 20) or self.Y in (0, 20) : return True else : return False @property def IsBlack(self) : return self.color == BLACK @property def IsWhite(self) : return self.color == WHITE @property def IsAvailable(self) : return self.color == AVAILABLE def __str__(self) : if self.IsBorder : if (self.X == 20) and (self.Y in (0, 20)): return '-+' elif (self.X == 0) and (self.Y in (0, 20)): return "+" elif self.Y in (0, 20) : return "--" elif self.X == 20: return ' |' else: return '|' elif self.IsBlack : return ' X' elif self.IsWhite : return ' O' else : return ' .' def __eq__(self, other) : try : assert type(self) == type(other) assert self.color == other.color assert self.board == other.board assert self.X == other.X assert self.Y == other.Y return True except : return False def __ne__(self, other) : return not self == other @property def Up(self) : x = self.x y = self.y + 1 return self.board.stones[x][y] @property def Down(self) : x = self.x y = self.y - 1 return self.board.stones[x][y] @property def Left(self) : x = self.x - 1 y = self.y return self.board.stones[x][y] @property def Right(self) : x = self.x + 1 y = self.y return self.board.stones[x][y] if __name__ == "__main__" : board = Board() TURNS = (BLACK, WHITE) round = 0 while 1 : turn = TURNS[round % 2] round += 1 x = int(raw_input("x: ")) if x == 0 : break y = int(raw_input("y: ")) stone = Stone(board, turn, x, y) board.AddStone(stone) print board }}}