1. 判子草案

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