def test_bad_position(self):
     r = Rook()
     b = Board()
     failed_correctly = False
     try:
         b.place_piece(r, 'x42')
     except PositionError:
         failed_correctly = True
     assert failed_correctly
    def test_knight_moves(self):
        k = Knight()
        b = Board()

        b.place_piece(k, 'a8')
        possible_moves = b.list_possible_moves(k)
        possible_moves.sort()
        assert possible_moves == ['b6', 'c7'], possible_moves

        b.clear_board()

        b.place_piece(k, 'h1')
        possible_moves = b.list_possible_moves(k)
        possible_moves.sort()
        assert possible_moves == ['f2', 'g3'], possible_moves
Beispiel #3
0
 def __init__(self, player_agents):
     n = len(player_agents)
     if not 2 <= n <= 5:
         raise Exception(
             'Unsupported number of players: {}'.format(player_agents))
     cheques = {
         2: CHEQUES_FOR_2[:],
         3: CHEQUES_FOR_3[:],
         4: CHEQUES_FOR_4[:],
         5: CHEQUES_FOR_5[:]
     }
     players = [Player(p, cs) for p, cs in zip(player_agents, cheques[n])]
     self._players = players
     self._deck = Deck()
     self._board = Board(CHEQUE_STARTING)
     self._round = 1
     self._round_end_policemen = ROUND_END_POLICEMEN if n > 2 else ROUND_END_POLICEMEN_TWOPLAYER
     self._end = False
     self._round_order_generator = TurnOrder(
         self._players, lambda x, y: x.player_agent == y.player_agent)
 def test_rook_moves(self):
     r = Rook()
     b = Board()
     b.place_piece(r, 'd2')
     assert b.list_possible_moves(r) == [
         'a2', 'b2', 'c2', 'd1', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'e2',
         'f2', 'g2', 'h2'
     ], b.list_possible_moves(r)
 def test_queen_moves(self):
     q = Queen()
     b = Board()
     b.place_piece(q, 'd2')
     assert b.list_possible_moves(q) == [
         'a2', 'a5', 'b2', 'b4', 'c1', 'c2', 'c3', 'd1', 'd3', 'd4', 'd5',
         'd6', 'd7', 'd8', 'e1', 'e2', 'e3', 'f2', 'f4', 'g2', 'g5', 'h2',
         'h6'
     ], b.list_possible_moves(q)
Beispiel #6
0
SCREEN_HEIGHT = 512
FPS = 30
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
LIGHT_TILE = (255, 206, 158)
DARK_TILE = (209, 139, 71)

spritesheet = pygame.image.load("sprites.png")
spritesheet = pygame.transform.scale(spritesheet, (384, 128))

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
board = Board(sys.argv)


def renderPiece(piece):
    subimageY = 0
    if piece[0] == 0:
        subimageY = 64
    screen.blit(spritesheet, (piece[2] * 64, piece[3] * 64),
                ((6 - piece[1]) * 64, subimageY, 64, 64))


running = True

#game loop
while running:
    clock.tick(FPS)
Beispiel #7
0
import argparse
from pieces import Board, create_piece

parser = argparse.ArgumentParser()
parser.add_argument('-piece', dest='piece', required=True,
                    help='The piece to move')
parser.add_argument('-position', dest='position', required=True,
                    help='The starting position of the piece')
args = parser.parse_args()

position = args.position.lower()
# Instantiate the piece's class from user input
piece = create_piece(args.piece.lower())

board = Board()
# The board has-a piece
board.place_piece(piece, position)

# The board tells us the possible moves
possible_moves = board.list_possible_moves(piece)

print("Moves for {} at {}:".format(piece.name, position))
print(", ".join(possible_moves))
Beispiel #8
0
class Game:
    def __init__(self, player_agents):
        n = len(player_agents)
        if not 2 <= n <= 5:
            raise Exception(
                'Unsupported number of players: {}'.format(player_agents))
        cheques = {
            2: CHEQUES_FOR_2[:],
            3: CHEQUES_FOR_3[:],
            4: CHEQUES_FOR_4[:],
            5: CHEQUES_FOR_5[:]
        }
        players = [Player(p, cs) for p, cs in zip(player_agents, cheques[n])]
        self._players = players
        self._deck = Deck()
        self._board = Board(CHEQUE_STARTING)
        self._round = 1
        self._round_end_policemen = ROUND_END_POLICEMEN if n > 2 else ROUND_END_POLICEMEN_TWOPLAYER
        self._end = False
        self._round_order_generator = TurnOrder(
            self._players, lambda x, y: x.player_agent == y.player_agent)

    def _execute_winning_bid(self, bidder, bid_cheque, board):
        cheque_ordinal = bidder.num_unavailable_cheques + 1
        new_cards = board.take_all_booty_cards()
        bidder.gain_cards(new_cards, self._round, bid_cheque, cheque_ordinal)
        gained_cheque = board.cheque
        bidder.remove_available_cheque(bid_cheque)
        bidder.add_unavailable_cheque(gained_cheque)
        board.replace_cheque(bid_cheque)
        logging.debug('  {} wins the auction:'.format(bidder.player_agent))
        logging.debug('    loses cheque {}'.format(bid_cheque))
        logging.debug(
            '    gains cheque {} (as unavailable)'.format(gained_cheque))
        logging.debug('    gains cards: {}'.format(', '.join(
            c.name for c in new_cards)))

    def _execute_auction(self, auction_mode, initiator, board):
        auction = Auction(auction_mode, initiator, board.get_cards(),
                          board.cheque)
        for player in self._round_order_generator.one_circle_from_next(
                auction.initiator):
            top = auction.highest_bid
            agent = player.player_agent
            if player.round_is_over:
                logging.debug(
                    '  {} PASSes bid because no cheques are available.'.format(
                        agent))
                continue
            avail_cheques_str = ','.join(
                str(c) for c in player.available_cheques())
            if top and player.highest_cheque < top:
                logging.debug(
                    '  {} PASSes bid because cannot outbid (had {} available).'
                    .format(agent, avail_cheques_str))
                continue
            is_mandated = auction.auction_mode == AuctionMode.ByPlayer and player == auction.initiator
            game_view = GameView(self, player, self._players, self._board)
            auction_view = AuctionView(auction)
            player_view = PlayerView(player)
            bidded_cheque = player.player_agent.bid(game_view, auction_view,
                                                    player_view, is_mandated)
            if bidded_cheque:
                logging.debug(
                    '  {} BIDs with cheque {} (had {} available).'.format(
                        agent, bidded_cheque, avail_cheques_str))
                auction.set_highest_bid(bidded_cheque, player)
            elif is_mandated:
                raise Exception('Missing mandated bid.')
            else:
                logging.debug(
                    '  {} PASSes bid deliberately (had {} available).'.format(
                        agent, avail_cheques_str))
        if auction.highest_bid:
            self._execute_winning_bid(auction.highest_bidder,
                                      auction.highest_bid, board)
            if not auction.highest_bidder.num_available_cheques:
                logging.debug('    is out of cheques and out of round')
        else:
            logging.debug('  No bids in this auction.')

    def _execute_auction_by_full_board(self, initiator):
        logging.debug('Starting an Auction (by full board)')
        highest_bidder = self._execute_auction(AuctionMode.ByFullBoard,
                                               initiator, self._board)
        if not highest_bidder:
            self._board.discard_booty_cards()

    def _execute_auction_by_player(self, initiator):
        pass  # FIXME: implement this action

    def _execute_auction_by_policeman(self, initiator):
        logging.debug('Starting an Auction (by Policeman)')
        self._execute_auction(AuctionMode.ByPoliceman, initiator, self._board)

    def _execute_draw(self, initiator):
        card = self._deck.draw()
        logging.debug('Player agent {} DRAWs a card: {}'.format(
            initiator.player_agent, card))
        if card == Card.Policeman:
            self._board.add_policeman()
            logging.debug('added policeman (total {})'.format(
                self._board.num_policemen))
            is_instant_round_end = self._board.num_policemen == self._round_end_policemen
            if is_instant_round_end:
                logging.debug('Policemen limit reached.')
                discarded_str = ', '.join(
                    str(c) for c in self._board.get_cards())
                logging.debug('Discarding {} cards from board: {}'.format(
                    self._board.num_cards, discarded_str))
                if not self.last_round:
                    logging.debug(
                        'Round ends with {} cards in deck remaining.'.format(
                            self._deck.size()))
                self._board.discard_booty_cards()
                self._board.discard_policemen()
                return Trigger.Round
            else:
                self._execute_auction_by_policeman(initiator)
                return Trigger.Turn
        else:
            self._board.add_card(card)
            board_is_full = self._board.num_cards == AUTOMATIC_AUCTION_NUM_CARDS
            if board_is_full:
                self._execute_auction_by_full_board(initiator)
            return Trigger.Turn

    def _execute_thieves(self, initiator):
        num_thieves = initiator.num_thieves
        if not num_thieves or not self._board.num_cards:
            raise Exception(
                'Cannot execute Thief action: player has no thieves or no cards on board.'
            )
        cards_to_steal = initiator.player_agent.steal(
            GameView(self, initiator, self._players, self._board))
        stolen_str = ', '.join([sc.name for sc in cards_to_steal])
        logging.debug('Player agent {} STEALs cards with thieves: {}'.format(
            initiator.player_agent, stolen_str))
        num_steal = len(cards_to_steal)
        if num_thieves < num_steal:
            raise Exception('Cannot steal {} cards with {} thieves.'.format(
                num_steal, num_thieves))
        initiator.remove_cards(num_steal * [Card.Thief])
        self._board.take_booty_cards(cards_to_steal)
        initiator.gain_cards(cards_to_steal, self.round, Card.Thief,
                             Card.Thief)  # Thief used instead of a cheque.
        return Trigger.Turn

        # 1. Check that initiator has thieves and there are cards on board.
        # 2. Call thief action (player agent decides how may thieves to use and what cards to pick.)
        # 3. Remove a number of thieves from player.
        # 4. Remove picked-up cards from board
        # 5. Let player gain the cards.
        # 6. Trigger Turn

    def _advance_round(self):
        self._round += 1

    def _determine_starting_player(self):
        return max([p for p in self._players], key=lambda x: x.highest_cheque)

    def _play_one_turn(self, player):
        action = player.player_agent.act(
            GameView(self, player, self._players, self._board))
        logging.debug('{} chooses {}'.format(player.player_agent, action))
        if action == ActionType.Thief:
            return self._execute_thieves(player)
        elif action == ActionType.Draw:
            return self._execute_draw(player)
        elif action == ActionType.AuctionByPlayer:
            return self._execute_auction_by_player(player)
        else:
            raise Exception('Unexpected action: {}'.format(action))

    def _score_round(self):
        nums_bodyguards = [player.num_bodyguards for player in self._players]
        for player in self._players:
            player.do_round_scoring(min(nums_bodyguards), max(nums_bodyguards))

    def _play_round(self, round_number):
        logging.debug('-------')
        logging.debug('Round {}'.format(round_number))
        logging.debug('-------')
        for player in self._players:
            player.refresh_cheques()
        starting_player = self._determine_starting_player()
        logging.debug(
            'Starting player: {} has highest cheque ({}) and starts the Round.'
            .format(starting_player.player_agent,
                    max(starting_player.available_cheques())))
        consecutive_passes = 0
        for player in self._round_order_generator.circling_from(
                starting_player):
            if player.round_is_over:
                logging.debug('Player agent {} passed (out of Round).'.format(
                    player.player_agent))
                consecutive_passes += 1
                if consecutive_passes < self.num_players:
                    continue
                else:
                    logging.debug('All cheques have been used.')
                    break
            consecutive_passes = 0
            trigger = self._play_one_turn(player)
            #logging.debug(player)
            #logging.debug(self._board)
            if trigger == Trigger.Round:
                break

    def _is_game_end_valid(self):
        expected_cards = sum([c.how_many for c in Card])
        deck_cards = self._deck.size()
        policemen = self._board.num_policemen
        discarded_booty_cards = len(self._board._discarded_booty)
        discarded_policemen = self._board._num_discarded_policemen
        player_cards = sum([len(p._scards) for p in self._players
                            ])  # TODO: avoid accessing internals
        player_scored_cards = sum([
            len(p._scored_scards) for p in self._players
        ])  # TODO: avoid accessing internals
        player_removed_cards = sum([
            len(p._removed_scards) for p in self._players
        ])  # TODO: avoid accessing internals
        num_cards = deck_cards + discarded_booty_cards + policemen + discarded_policemen + player_cards + player_scored_cards + player_removed_cards
        if num_cards != expected_cards:
            raise Exception(
                'Unexpected number of cards at game end: expected {}, but had {}.'
                .format(expected_cards, num_cards))
        counted_player_cards = sum(v for p in self._players
                                   for k, v in p._counts.items())
        counted_cards = deck_cards + discarded_booty_cards + policemen + discarded_policemen + counted_player_cards + player_scored_cards + player_removed_cards
        if counted_cards != expected_cards:
            raise Exception(
                'Unexpected card counts at game end: expected {}, but had {}.'.
                format(expected_cards, counted_cards))

    def _score_game_end(self):
        cheque_totals = [player.cheque_total for player in self._players]
        for player in self._players:
            player.do_game_end_scoring(min(cheque_totals), max(cheque_totals))

    def _get_player_scorings(self):
        return {
            player.player_agent: player.get_final_scoring()
            for player in self._players
        }

    def play_game(self):
        if self._end:
            raise Exception('Game has already ended.')
        logging.debug('===============================')
        logging.debug('Starting Razzia! with {} players'.format(
            self.num_players))
        logging.debug('===============================')
        for r in range(1, GAME_ROUNDS + 1):
            self._play_round(r)
            self._score_round()
            self._advance_round()
        self._end = True
        self._score_game_end()
        logging.debug('Game ends with {} cards in deck remaining.'.format(
            self._deck.size()))
        logging.debug('==============')
        logging.debug('Game has ended')
        logging.debug('==============')
        self._is_game_end_valid()
        scorings = self._get_player_scorings()
        return scorings

    def auctioned_cards(self):
        return len(self._board.get_cards())

    @property
    def num_players(self):
        return len(self._players)

    @property
    def round(self):
        return self._round

    @property
    def rounds_remaining(self):
        return GAME_ROUNDS - self._round

    @property
    def last_round(self):
        return self._round == GAME_ROUNDS

    @property
    def end(self):
        return self._end
 def test_constructors(self):
     b = Board()
     r = Rook()
     q = Queen()
     k = Knight()
 def test_placing_piece(self):
     r = Rook()
     b = Board()
     b.place_piece(r, 'd2')
     assert b.squares[b.chessboard[6][3]] == [(6, 3), r], \
         b.squares[b.chessboard[6][3]]
 def test_chessboard(self):
     b = Board()
     assert b.chessboard[0][0] == 'a8', b.chessboard[0][0]
     assert b.chessboard[7][7] == 'h1', b.chessboard[7][7]
Beispiel #12
0
from pieces import Board
from minmax import evaluate

board = Board()
print(evaluate(board, 0))