def test_bidding_rounds(self): self.assertEquals(CallHistory.from_string("")._bidding_rounds_count(), 0) self.assertEquals(CallHistory.from_string("").bidding_rounds(last_call_only=True), [['?', None, None, None]]) self.assertEquals(CallHistory.from_string("").bidding_rounds(last_call_only=True, mark_to_bid=False), []) self.assertEquals(CallHistory.from_string("P").bidding_rounds(last_call_only=True), [['P', '?', None, None]]) self.assertEquals(CallHistory.from_string("P P").bidding_rounds(last_call_only=True), [['P', 'P', '?', None]]) self.assertEquals(CallHistory.from_string("P P", dealer_string="E").bidding_rounds(last_call_only=True), [[None, 'P', 'P', '?']]) self.assertEquals(CallHistory.from_string("P P", dealer_string="W").bidding_rounds(last_call_only=True), [[None, None, None, 'P'], ['P', '?', None, None]]) self.assertEquals(CallHistory.from_string("2H P 3H P").bidding_rounds(last_call_only=True), [['2H', 'P', '3H', 'P'], ['?', None, None, None]]) self.assertEquals(CallHistory.from_string("P P P P").bidding_rounds(last_call_only=True), [['P', 'P', 'P', 'P']]) self.assertEquals(CallHistory.from_string("P P P P", dealer_string="E").bidding_rounds(last_call_only=True), [[None, 'P', 'P', 'P'], ['P', None, None, None]])
def get_call_history(hands, board_number): call_history = CallHistory([], Position.from_index((board_number + 3) % 4), Vulnerability.from_board_number(board_number)) while len(call_history.calls) < 4 or not call_history.is_complete(): whos_turn = call_history.position_to_call().index call = kbb_bidder.find_call_for(hands[whos_turn], call_history) or Pass() call_history.calls.append(call) return call_history
def test_from_identifier(self): self.assertEqual(CallHistory.from_identifier('E:EW:P').identifier(), CallHistory.from_string('P', 'E', 'E-W').identifier()) # Test that from_identifier is forgiving of a missing trailing colon self.assertEqual(CallHistory.from_identifier('E:EW:').identifier(), CallHistory.from_string('', 'E', 'E-W').identifier()) self.assertEqual(CallHistory.from_identifier('E:EW').identifier(), CallHistory.from_string('', 'E', 'E-W').identifier()) # Test that from_identifier is forgiving of a trailing comma. self.assertEqual(CallHistory.from_identifier('N:NO:P,').calls_string(), "P")
def _getCallsAndAuction(cls, bidsMade, dealno): tmp_auction = CallHistory.empty_for_board_number(dealno) allCalls = [] for actions in bidsMade: (call, caller) = actions.split(sep=";") call = cls.call(call.strip(), caller.strip()) allCalls.append(call) tmp_auction.append_call(call) return (allCalls, tmp_auction)
def from_expectation_tuple_in_group(cls, expectation, test_group): hand_string = expectation[0] assert '.' in hand_string, "_split_expectation expectes C.D.H.S formatted hands, missing '.': %s" % hand_string expected_call = Call.from_string(expectation[1]) history_string = expectation[2] if len(expectation) > 2 else "" vulnerability_string = expectation[3] if len(expectation) > 3 else None hand = Hand.from_cdhs_string(hand_string) call_history = CallHistory.from_string(history_string, vulnerability_string=vulnerability_string) return cls(test_group, hand, call_history, expected_call)
def from_identifier(self, identifier): components = identifier.split("-") if len(components) == 2: (board_number_string, deal_and_history_identifier) = components if ':' in deal_and_history_identifier: deal_identifier, call_history_identifier = deal_and_history_identifier.split(':') # We have to do a bit of a dance to convert from the board url system that # the JS code uses to the one the python uses. call_history = CallHistory.from_board_number_and_calls_string(int(board_number_string), call_history_identifier) else: deal_identifier = deal_and_history_identifier call_history = CallHistory.empty_for_board_number(int(board_number_string)) else: (board_number_string, deal_identifier, call_history_identifier) = components call_history = CallHistory.from_identifier(call_history_identifier) board_number = int(board_number_string) deal = Deal.from_identifier(deal_identifier) return Board(number=board_number, deal=deal, call_history=call_history)
def test_copy_with_partial_history(self): history = CallHistory.from_string("P P 1N P P P") self.assertEquals(len(history.calls), 6) self.assertEquals(len(history.copy_with_partial_history(0).calls), 0) self.assertEquals(len(history.copy_with_partial_history(2).calls), 2) self.assertEquals(len(history.copy_with_partial_history(-2).calls), 4) partial_history = history.copy_with_partial_history(3) self.assertEquals(len(history.calls), 6) self.assertEquals(len(partial_history.calls), 3) partial_history.calls.append(None) # Invalid, but fine for testing. self.assertEquals(len(history.calls), 6) self.assertEquals(len(partial_history.calls), 4)
def test_last_to_call(self): self.assertEquals(CallHistory.from_string("").last_to_call(), None) self.assertEquals(CallHistory.from_string("P").last_to_call(), NORTH) self.assertEquals(CallHistory.from_string("1N P").last_to_call(), EAST) self.assertEquals(CallHistory.from_string("1N P 2C").last_to_call(), SOUTH) self.assertEquals(CallHistory.from_string("1N P 2C P").last_to_call(), WEST) self.assertEquals(CallHistory.from_string("1N P 2C P 2D").last_to_call(), NORTH)
def test_is_passout(self): self.assertEquals(CallHistory.from_string("").is_passout(), False) self.assertEquals(CallHistory.from_string("P").is_passout(), False) self.assertEquals(CallHistory.from_string("P P").is_passout(), False) self.assertEquals(CallHistory.from_string("P P P").is_passout(), False) self.assertEquals(CallHistory.from_string("P P P P").is_passout(), True) self.assertEquals(CallHistory.from_string("P 1N P P P").is_passout(), False)
def _board_from_request(self): board_number = int(self.request.get('number')) vulnerability_string = self.request.get('vunerability') hand_strings = map(str, [ self.request.get('deal[north]'), self.request.get('deal[east]'), self.request.get('deal[south]'), self.request.get('deal[west]'), ]) deal = Deal.from_string(' '.join(hand_strings)) dealer_char = self.request.get('dealer') calls_string = self.request.get('calls_string', '') history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) return Board(board_number, deal, history)
def _board_from_request(self): board_number = int(self.request.get('number')) vulnerability_string = self.request.get('vunerability') hand_strings = map(str, [ self.request.get('deal[north]'), self.request.get('deal[east]'), self.request.get('deal[south]'), self.request.get('deal[west]'), ]) deal = Deal.from_string(' '.join(hand_strings)) dealer_char = self.request.get('dealer') # Note: We keep bids_string around to I can test old requests. calls_string = self.request.get('calls_string') or self.request.get('bids_string') or '' history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) return Board(board_number, deal, history)
def _board_from_request(self): board_number = int(self.request.get("number")) vulnerability_string = self.request.get("vunerability") hand_strings = map( str, [ self.request.get("deal[north]"), self.request.get("deal[east]"), self.request.get("deal[south]"), self.request.get("deal[west]"), ], ) deal = Deal.from_string(" ".join(hand_strings)) dealer_char = self.request.get("dealer") # Note: We keep bids_string around to I can test old requests. calls_string = self.request.get("calls_string") or self.request.get("bids_string") or "" history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) return Board(board_number, deal, history)
def get(self): interpreter = InterpreterProxy() calls_string = self.request.get('calls_string') or '' dealer_char = self.request.get('dealer') or '' vulnerability_string = self.request.get('vulnerability') or '' call_history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) knowledge_string, rule = interpreter.knowledge_string_and_rule_for_last_call(call_history) explore_dict = { 'knowledge_string': knowledge_string, } explore_dict.update(self._json_from_rule(rule, call_history.calls[-1])) self.response.headers["Content-Type"] = "application/json" self.response.headers["Cache-Control"] = "public" expires_date = datetime.datetime.utcnow() + datetime.timedelta(days=1) expires_str = expires_date.strftime("%d %b %Y %H:%M:%S GMT") self.response.headers.add_header("Expires", expires_str) self.response.out.write(json.dumps(explore_dict))
def get(self): interpreter = BidInterpreter() calls_string = self.request.get('calls_string') or '' dealer_char = self.request.get('dealer') or '' vulnerability_string = self.request.get('vulnerability') or '' history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) existing_knowledge, knowledge_builder = interpreter.knowledge_from_history(history) matched_rules = knowledge_builder.matched_rules() explore_dict = { 'knowledge_string': existing_knowledge.rho.pretty_one_line(include_last_call_name=False) if existing_knowledge else None, } explore_dict.update(self._json_from_rule(matched_rules[-1], history.calls[-1])) self.response.headers["Content-Type"] = "application/json" self.response.headers["Cache-Control"] = "public" expires_date = datetime.datetime.utcnow() + datetime.timedelta(days=1) expires_str = expires_date.strftime("%d %b %Y %H:%M:%S GMT") self.response.headers.add_header("Expires", expires_str) self.response.out.write(json.dumps(explore_dict))
def get(self): interpreter = Interpreter() calls_string = self.request.get('calls_string') or '' dealer_char = self.request.get('dealer') or '' vulnerability_string = self.request.get('vulnerability') or '' call_history = CallHistory.from_string(calls_string, dealer_char, vulnerability_string) interpretations = [] with interpreter.create_history(call_history) as history: for call in CallExplorer().possible_calls_over(call_history): knowledge_string, rule = self._knowledge_string_and_rule_for_additional_call(history, call, interpreter) explore_dict = self._json_from_rule(knowledge_string, rule, call) interpretations.append(explore_dict) self.response.headers["Content-Type"] = "application/json" self.response.headers["Cache-Control"] = "public" expires_date = datetime.datetime.utcnow() + datetime.timedelta(days=1) expires_str = expires_date.strftime("%d %b %Y %H:%M:%S GMT") self.response.headers.add_header("Expires", expires_str) self.response.out.write(json.dumps(interpretations))
def test_suits_bid_by(self): self.assertEqual(CallHistory.from_string("P 1C P 1D P 1H P 1S").suits_bid_by(EAST), set([CLUBS, HEARTS])) self.assertEqual(CallHistory.from_string("P 1C P 1D P 1H P 1S").suits_bid_by(WEST), set([DIAMONDS, SPADES]))
def _rule_for_last_call(self, call_history_string): history = CallHistory.from_string(call_history_string) knowledge, knowledge_builder = self.interpreter.knowledge_from_history(history) matched_rules = knowledge_builder.matched_rules() return matched_rules[-1]
def _hand_knowledge_from_last_call(self, call_history_string): history = CallHistory.from_string(call_history_string) knowledge, _ = self.interpreter.knowledge_from_history(history) return knowledge.rho
def _assert_point_range(self, call_history_string, expected_point_range): history = CallHistory.from_string(call_history_string) knowledge, matched_rules = self.interpreter.knowledge_from_history(history) # We use rho() instead of me() because knowledge_from_history auto-rotates the Knowledge. self.assertEqual(knowledge.rho.hcp_range_tuple(), expected_point_range)
def _assert_declarer(self, history_string, dealer, declarer): self.assertEquals(CallHistory.from_string(history_string, position_char(dealer)).declarer(), declarer)
def _assert_is_legal_call(self, history_string, bid, is_legal=True): call_history = CallHistory.from_string(history_string) bid = Call.from_string(bid) self.assertEquals(call_history.is_legal_call(bid), is_legal)
def history_iglob(self, glob_string): glob_string = self._normalize_glob_string(glob_string) glob_string, last_token = self._split_before_last_token(glob_string) histories = self.history_iglob(glob_string) if self._has_wildcards(glob_string) else [CallHistory.from_string(glob_string)] call_generator = self._match_pattern_over if self._has_wildcards(last_token) else self._glob_helper for history in histories: # If we already have 3 passes in a row, there is nothing more we an add to this history. if history.is_complete(): continue for call in call_generator(history, last_token): yield history.copy_appending_call(call)
def _assert_opener(self, history_string, dealer, opener): self.assertEquals(CallHistory.from_string(history_string, position_char(dealer)).opener(), opener)
def _assert_competative_auction(self, history_string, is_competative): self.assertEquals(CallHistory.from_string(history_string).competative_auction(), is_competative)
def _assert_history_until_after_last_call_from_position(self, full_history_string, position, expected_calls_string): history = CallHistory.from_string(full_history_string) partial_history = history.copy_with_history_until_after_last_call_from_position(position) self.assertEquals(partial_history.calls_string(), expected_calls_string)
def _assert_is_legal_call(self, history_string, call_name, is_legal=True): call_history = CallHistory.from_string(history_string) call = Call.from_string(call_name) self.assertEquals(call_history.is_legal_call(call), is_legal)
def test_empty_for_board_number(self): self.assertEquals(CallHistory.empty_for_board_number(1).dealer, NORTH) self.assertEquals(CallHistory.empty_for_board_number(6).dealer, EAST) self.assertEquals(CallHistory.empty_for_board_number(16).dealer, WEST)
def _history_from_calls_string(self, calls_string): history_identifier = "N:NO:%s" % calls_string # FIXME: I doubt this is right with the new identifiers. return CallHistory.from_identifier(history_identifier)
def __init__(self, number=None, deal=None, call_history=None): self.number = number or 1 self.deal = deal or Deal.random() self.call_history = call_history or CallHistory.empty_for_board_number(number)
def test_can_double(self): self.assertTrue(CallHistory.from_string("1S 2H 2S").can_double())
def _assert_opener(self, history_string, dealer, opener): self.assertEquals(CallHistory.from_string(history_string, dealer.char).opener(), opener)