pythonリバーシ...pyreversi
課題のc++オセロAIが弱すぎて萎える。得点ボード+確定石の近似で評価して終盤は完全読みをしてはいるんだが・・・flashのオセロに負けた・・・
そのせいで一気に萎えた。で、気分転換にpythonでリバーシのプログラム書いた。AIは無し。基本的なルールだけの実装。バーッと書いたのでReversi::display_game_overが若干不安。
#!/usr/bin/env python import re WHITE = -1 BLANK = 0 BLACK = 1 class Board: # represent reversi board def __init__(self): self.board = [[0] * 8 for x in range(8)] self.board[3][3] = WHITE self.board[4][4] = WHITE self.board[3][4] = BLACK self.board[4][3] = BLACK self.turns = 0 # turn counter self.current = BLACK # current player self.stones = [2, 60, 2] # white, blank, black def get_stone(self, x, y): return self.board[x][y] def get_current(self): return self.current def get_turn(self): return self.turns def count_stone(self, st): return self.stones[1 + st] def pass_turn(self): self.current *= -1 def validate_range(self, x, y): # validate input range if x < 0 or x > 7 or y < 0 or y > 7: return False return True def validate_input(self, x, y): # validate input if not self.validate_range(x, y): return False if not self.board[x][y] == BLANK: return False elif not self.can_reverse(x, y): return False return True def can_reverse(self, x, y): storex, storey = x, y for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if not self.validate_range(x + dx, y + dy): continue if self.board[x + dx][y + dy] == -self.current: if self.can_reverse_one_dir(x + dx, y + dy, dx, dy): return True return False def can_reverse_one_dir(self, x, y, dx, dy): while self.validate_range(x, y): if self.board[x][y] == BLANK: return False elif self.board[x][y] == -self.current: x += dx y += dy continue elif self.board[x][y] == self.current: return True return False def reverse_one_dir(self, x, y, dx, dy): while self.board[x][y] != self.current: if self.board[x][y] == -self.current: self.board[x][y] *= -1 # reverse self.stones[1 + self.current] += 1 self.stones[1 + -self.current] -= 1 x += dx y += dy def put_stone(self, x, y): self.board[x][y] = self.current self.stones[1 + BLANK] -= 1 self.stones[1 + self.current] += 1 for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if self.can_reverse_one_dir(x + dx, y + dy, dx, dy): self.reverse_one_dir(x + dx, y + dy, dx, dy) self.turns += 1 # incremnt turn self.current *= -1 # change turn class Reversi: def __init__(self): self.board = Board() self.pass_flag = False self.mark = ["W", "-", "B"] # each represents white, blank, black def display_board(self): table = [[0] * 8 for x in range(8)] for i in range(8): for j in range(8): if self.board.validate_input(i, j): table[i][j] = "*" else: table[i][j] = self.mark[1 + self.board.get_stone(i ,j)] print "x\\y", for i in range(8): print "%d" % i, print "" # newline print " ", print "--"*8 for i in range(8): print i,"|", for j in range(8): print "%c" % table[i][j], print "" # newline def isover(self): for i in range(8): for j in range(8): if self.board.validate_input(i, j): self.pass_flag = False return False if not self.pass_flag: self.pass_flag = True return False if self.pass_flag: return True # game is over def display_game_over(self): print "game is now over" black = self.board.count_stone(BLACK) white = self.board.count_stone(WHITE) table = self.mark[1+BLACK]*black + self.mark[1+WHITE]*white if len(table) < 64: table += "-" * (64 - len(table)) print "B:",black,",W:",white for i in range(8): for j in range(8): print table[i*8 + j], print "" # newline if black > white: print "winner black" elif black < white: print "winner white" else: print "draw" def play(self): while not self.isover(): self.display_board() if self.pass_flag: print "*PASS* ", self.mark[1 + self.board.get_current()] self.board.pass_turn() continue print "TURN",self.mark[1 + self.board.get_current()], print ":",self.board.get_turn()+1 # user input while True: point = raw_input("(x, y)>") if point == "": continue if not re.match(r"\s*?\d \d\s*?", point): print "validater reject." continue point = map(eval, point.split()) if self.board.validate_input(*point): break print "validater reject." self.board.put_stone(*point) self.display_game_over() def main(): r = Reversi() r.play() if __name__ == '__main__': main()