diff --git a/board.py b/board.py index 10d071e..936d947 100644 --- a/board.py +++ b/board.py @@ -14,69 +14,79 @@ class Board: 0, -3, 0, 0, 0, 5, -5, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, -2, - 0, 0, 0] + 0, 0, 0 ] def get_state(self): return self.state - def switch(self,cur): - return -1 * cur - - # Remember to handle edge case when we're on the last moves and you may go # from position 22 -> 24 on a 6, if you have no pieces behind 22. Simply # check if any are behind if you're circle or if any are higher if you are # X, then it can be allowed. # Also, the check_move will also fail when you're attempting to leave a - # jail. A fix of this is of course to check if the from_idx = jail and if so, + # bar. A fix of this is of course to check if the from_idx = bar and if so, # allow some extra stuff! - - def check_move(self, move, sym, roll): - from_idx = int(move[0]) - to_idx = int(move[1]) + + # TODO: write tests + # FIXME: make sure to disallow backwards movement + # TODO: implement double roll feature (4 dice if dice are equal) + # TODO: implement moving checkers into home (bearing off) + # TODO: handle barring in a more elengant way + # TODO: allow bearing off with non-exact die roll if this is only possible + # move + def check_move(self, move, player, roll): + from_idx = int(move[0]) + to_idx = int(move[1]) + to_state = self.state[to_idx] + from_state = self.state[from_idx] + if from_idx == 26: from_idx = 1 roll -= 1 elif from_idx == 27: from_idx = 24 roll -= 1 - if (from_idx < 1 or from_idx > 24) or (to_idx < 1 or to_idx > 24): + + if not (1 <= from_idx <= 24 and + 1 <= to_idx <= 24): return False - elif (abs(from_idx - to_idx) != roll): + elif ( abs( from_idx - to_idx ) != roll ): return False - elif ((self.state[to_idx] * sym >= 0 or self.state[to_idx] == 0) or (self.state[to_idx] * self.switch(sym) == 1)) and self.state[from_idx] * sym >= 1: + elif (from_state * player >= 1 and # Is moving player's own checker? + (to_state * player >= 0 or # Is 'to' empty or has player's own checkers? + to_state * -player == 1)): # Can opponent checker be hit? return True - def find_pieces_for_player(self,sym): + def find_pieces_for_player(self, player): idxs = [] for idx, pip in enumerate(self.state): - if pip * sym >= 1: + if pip * player >= 1: idxs.append(idx) return idxs - def is_winner(self,sym): + def is_winner(self, player): for i in range(1,25): - if sym * self.state[i] > 0: + if player * self.state[i] > 0: return False return True - def find_legal_moves(self,sym,roll): + def find_legal_moves(self, player, roll): # Find all pips with things on them belonging to the player # Iterate through each index and check if it's a possible move given the roll # If player is O, then check for idx + roll # If player is X, then check for idx - roll # Rewrite this, it's shit. - idxs_with_thing = self.find_pieces_for_player(sym) + idxs_with_thing = self.find_pieces_for_player(player) legal_moves = [] for index in idxs_with_thing: from_idx = index - to_idx = index+(roll*sym) - if self.check_move([from_idx,to_idx], sym, roll): + to_idx = index+(roll*player) + if self.check_move([from_idx,to_idx], player, roll): legal_moves.append([from_idx,to_idx]) return legal_moves @@ -98,21 +108,22 @@ class Board: ------------------------------------------------------------ """.format(*temp) - def move_to_jail(self,sym): - if sym == 1: - self.state[26] += sym + def move_to_bar(self, to_idx): + # Find the owner of the hit checker + player = self.state[to_idx] + + # FIXME: find better bar solution + if player == 1: + self.state[26] += player else: - self.state[27] += sym - - def move_thing(self, cur_sym, from_idx, to_idx): + self.state[27] += player - self.state[from_idx] -= cur_sym + self.state[to_idx] = 0 + + def move_thing(self, player, from_idx, to_idx): + self.state[from_idx] -= player - if self.state[to_idx] * cur_sym <= -1: - self.move_to_jail(self.switch(cur_sym)) - self.state[to_idx] = 0 + if self.state[to_idx] * player == -1: + self.move_to_bar(to_idx) - self.state[to_idx] += cur_sym - - - + self.state[to_idx] += player