I redid a Python Reversi move preview routine that is online. I could use comments about using Python better and/or better OOP design since the original did not use classes. There are three main classes: Board for the Reversi board, Location to hold an x,y coordinate (0-7,0-7), and Move to store a location to put a disc on a board and how many discs would be affected by that move. I separated out Move because I would like to keep a sequence of Moves in memory to play forward or reverse. Board knows about where the discs are in a bitfield and knows how to turn over discs and return if a disc is at a location. import unittest import copy from bitarray import bitarray INITIAL_BOARD = """ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|B|W|_|_|_| |_|_|_|W|B|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| """ def other_player(playerId): return 'B' if playerId == 'W' else 'W' class Location: def __init__(self,x=0,y=0): self.offset = self.convertToOffset(x,y) def convertToOffset(self,x,y): self.invalid = (x < 0 or x > 7 or y < 0 or y > 7) return x + y * 8 def translate(self,dx,dy): self.invalid = ((self.offset < 8 and dy == -1) or (self.offset > 56 and dy == 1) or (self.offset % 8 == 0 and dx == -1) or (self.offset % 8 == 7 and dx == 1)) self.offset = self.offset + dx + dy * 8 def __eq__(self, other): if isinstance(other, self.__class__): return self.__dict__ == other.__dict__ else: return False def __ne__(self, other): return not self.__eq__(other) class Board: def __init__(self, board=INITIAL_BOARD): self.discs = self.parse_board(board) def make_bitstring(self,board,color_current): other_color = other_player(color_current) def parse_to_bit(square): if square == color_current: return '1' elif square == '_' or square == other_color: return '0' return '' return bitarray(''.join(map(parse_to_bit,board))) def parse_board(self,board): return (self.make_bitstring(board,'B'), self.make_bitstring(board,'W')) def show(self): print self.discs def at(self, location, player): return not location.invalid and self.discs[int(player=='W')][location.offset] def empty(self, location): return location.invalid or (not self.at (location,'B') and not self.at (location,'W')) def turnoverDisc(self, location): offset = location.offset self.discs[0][offset], self.discs[1][offset] = self.discs[1][offset], self.discs[0][offset] def placeDisc(self, location, player): self.discs[int(player=='W')][location.offset] = 1 def __eq__(self, other): if isinstance(other, self.__class__): return self.__dict__ == other.__dict__ else: return False def __ne__(self, other): return not self.__eq__(other) class Move: def __init__(self, board, location, color_player): self.location = location self.player = color_player self.board = board self.discDelta = self.makeDiscDelta() def makeDiscDelta(self): result = [] other = other_player(self.player) if not self.board.empty(self.location): return result next_location = Location() for dir in [(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1)]: next_location.offset = self.location.offset next_location.translate(dir[0],dir[1]) dirDelta = [] while self.board.at(next_location,other): dirDelta.append(copy.copy(next_location)) next_location.translate(dir[0],dir[1]) if self.board.at(next_location,self.player): result.extend(dirDelta) return result def makeBoard(self): result = copy.deepcopy(self.board) for location in self.discDelta: result.turnoverDisc(location) result.placeDisc(self.location,self.player) return result class ReversiTest(unittest.TestCase): def testMovePreviewWhite(self): board = Board() location = Location(4,5) move = Move(board,location,'W') self.assertEquals([Location(4,4)], move.discDelta) def testMovePreviewBlack(self): board = Board() location = Location(3,2) move = Move(board,location,'W') self.assertEquals([Location(3,3)], move.discDelta) def testMove(self): board = Board() expected_board = """ |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|B|W|_|_|_| |_|_|_|W|W|_|_|_| |_|_|_|_|W|_|_|_| |_|_|_|_|_|_|_|_| |_|_|_|_|_|_|_|_| """ expected = Board(expected_board) location = Location(4,5) move = Move(board,location,'W') result = move.makeBoard() self.assertEquals(expected, result) self.assertEquals(board, Board()) self.assertEquals(location, Location(4,5))