def test_2_heart_plain(self) : self.assertEquals(110, bridge.tricks_to_result('2H', True, 8)) self.assertEquals(470, bridge.tricks_to_result('2Hd', False, 8)) self.assertEquals(670, bridge.tricks_to_result('2Hd', True, 8)) self.assertEquals(640, bridge.tricks_to_result('2Hr', False, 8)) self.assertEquals(840, bridge.tricks_to_result('2Hr', True, 8))
def test_1_club_over(self) : self.assertEquals(90, bridge.tricks_to_result('1C', True, 8)) self.assertEquals(240, bridge.tricks_to_result('1Cd', False, 8)) self.assertEquals(340, bridge.tricks_to_result('1Cd', True, 8)) self.assertEquals(430, bridge.tricks_to_result('1Cr', False, 8)) self.assertEquals(630, bridge.tricks_to_result('1Cr', True, 8))
def answer_claim(prof, toput, key, side, answer) : table = repo.Table.get(key) if table.claim is None : logging.warn('%s @%s/%s tries to answer absent claim', prof.user, key, side) return proto = table.protocol if table.user_by_side(side) != prof.user : logging.warn('User %s answering claim for %s@%s/%s', prof.user, table.user_by_side(side), key, side) return if bridge.relation_idx(proto.contract[-1], side) % 2 == 0 : logging.warn('User %s@%s/%s answering claim being part of claimant or claimant himself' , prof.user, key, side) return toput.append(table) if answer == '0' : # declined table.claim = '00' + table.claim[2] table.broadcast(m('claim.decline')) return if not table.claim.endswith(bridge.partner_side(side)) : #partner didn't yet answered table.claim += side return # partner answered, so deal is done toput.append(proto) deal = proto.deal trickcnt = int(table.claim[:2]) proto.tricks = int(proto.contract[0]) + 6 - trickcnt proto.result = bridge.tricks_to_result(proto.contract, deal.vulnerability, trickcnt) toput.append(table.broadcast(m('end.play', contract = proto.contract.replace('d', 'x').replace('r','xx')\ , declearer = proto.contract[-1]\ , points = proto.result\ , tricks = trickcnt\ , protocol_url = 'protocol.html?%s' % deal.key()))) start_new_deal(table, toput)
def do_claim(prof, toput, key, side, tricks_s) : table = repo.Table.get(key) proto = table.protocol if proto.contract is None : logging.warn('%s@%s/%s tries to claim %s while nothing declared', prof.user, key, side, tricks_s) return decl = proto.contract[2] umap = table.usermap() if decl != side or umap.get(side) != prof.user : logging.warn('%s@%s/%s tries to claim %s while not in position to', prof.user, key, side, tricks_s) return if table.claim is not None and not table.claim.startswith('00') : logging.warn('%s@%s/%s tries to claim %s while other claim in progress', prof.user, key, side) return decl_tricks = bridge.decl_tricks_and_next_move_offset(proto.moves, proto.contract[1])[0] defender_tricks = (len(proto.moves) / 4) - decl_tricks tricks = int(tricks_s) if tricks > 13 - defender_tricks or tricks < decl_tricks : logging.warn('%s@%s/%s tries to claim %s while %s:%s could be taken' , prof.user, key, side, tricks_s, decl_tricks, 13 - defender_tricks) return table.claim = "%02d%s" % (tricks, side) toput.append(table) deal = proto.deal claim_res = bridge.tricks_to_result(proto.contract, deal.vulnerability, tricks) si = bridge.SIDES.index(side) claimant_part = bridge.partner_side(side) moves = proto.moves common_m = [m('hand', cards=hand_left(deal.hand_by_side(side), moves), side=side) , m('hand', cards=hand_left(deal.hand_by_side(claimant_part), moves), side=claimant_part)] umap.pop(side, None) umap.pop(claimant_part, None) items = umap.items() # FIXME: process situation when one or both defenders are not at the table if len(items) > 0 : side1, def1 = items[0] if len(items) > 1 : side2, def2 = items[1] toput.append(repo.UserProfile.uenqueue( def1, common_m + [m('hand', cards=hand_left(deal.hand_by_side(side2), moves), side=side2)])) toput.append(repo.UserProfile.uenqueue( def2, common_m + [m('hand', cards=hand_left(deal.hand_by_side(side1), moves), side=side1)])) else : side2 = bridge.partner_side(side1) toput.append(repo.UserProfile.uenqueue( def1, common_m + [m('hand', cards=hand_left(deal.hand_by_side(side2), moves), side=side2)])) toput.append(table.broadcast(m('claim', side=side, tricks=tricks_s, result=claim_res)))
def test_1_club_even(self) : self.assertEquals(70, bridge.tricks_to_result('1C', False, 7)) self.assertEquals(70, bridge.tricks_to_result('1C', True, 7)) self.assertEquals(140, bridge.tricks_to_result('1Cd', False, 7)) self.assertEquals(140, bridge.tricks_to_result('1Cd', True, 7)) self.assertEquals(230, bridge.tricks_to_result('1Cr', False, 7)) self.assertEquals(230, bridge.tricks_to_result('1Cr', True, 7))
def test_undertricks(self) : self.assertEquals(-50, bridge.tricks_to_result('1C', False, 6)) self.assertEquals(-100, bridge.tricks_to_result('1C', True, 6)) self.assertEquals(-100, bridge.tricks_to_result('1Cd', False, 6)) self.assertEquals(-200, bridge.tricks_to_result('1Cd', True, 6)) self.assertEquals(-200, bridge.tricks_to_result('1Cr', False, 6)) self.assertEquals(-400, bridge.tricks_to_result('1Cr', True, 6))
def current_table_state(user, place, table, allow_moves=True) : tkey = table.key() umap = table.usermap() messages = [m('player.sit', position = p, name = u.nickname(), tid = str(tkey)) for p, u in umap.iteritems()] p = table.protocol if p is None : if len(umap) == 4 : logging.warn('4 users @%s, but deal not dealed', tkey) actions.start_new_deal(table, []) table.put() return messages deal = p.deal moves = p.moves hand = actions.hand_left(deal.hand_by_side(place), moves) messages += [m('hand', cards = hand, side = place) , m('start.bidding', vuln = deal.vulnerability, dealer = deal.dealer)] if len(p.bidding) == 0 : return messages side = deal.dealer place_idx = bridge.SIDES.index(place) part_idx = (place_idx + 2) % 4 def bidmes(bid, side, part_idx) : s = bid.split(':', 1) b = s[0] if len(s) > 1 and side != part_idx: alert = s[1] return m('bid', side = side, alert = process_chat_message(alert), bid = b) else: return m('bid', side = side, bid = b) for bid in p.bidding[:-1] : messages.append(bidmes(bid, side, part_idx)) side = (side + 1) % 4 last_bid = bidmes(p.bidding[-1], side, part_idx) last_bid['value']['dbl_mode'] = actions.get_dbl_mode(p.bidding) messages.append(last_bid) c = p.contract if c is None : return messages decl_side = c[-1] dummy_side = p.dummy() messages.append(m('start.play', contract = c.replace('d', 'x').replace('r','xx') , lead = (bridge.SIDES.index(c[-1]) + 1) % 4)) move_done = len(moves) > 0 if place == dummy_side : messages.append(m('hand', cards = actions.hand_left(deal.hand_by_side(decl_side), moves) , side = decl_side)) elif move_done or decl_side == place: messages.append(m('hand', cards = actions.hand_left(deal.hand_by_side(dummy_side), moves) , side = dummy_side)) if move_done : trump = c[1] full_rounds_played = len(moves) / 4 rounds_total = int(math.ceil(float(len(moves)) / 4)) decl_tricks, taker = bridge.decl_tricks_and_next_move_offset(moves[:(rounds_total - 2) * 4], trump) cards_to_show = moves[(rounds_total - 2) * 4:] lasttrick, lasttaker = bridge.decl_tricks_and_next_move_offset(cards_to_show, trump) if len(cards_to_show) > 3 : if taker % 2 == 1 : decl_tricks += 2 - (rounds_total - full_rounds_played) - lasttrick else : decl_tricks += lasttrick defen_tricks = full_rounds_played - decl_tricks decl_idx = bridge.SIDES.index(decl_side) if decl_idx % 2 == 0 : ns_t = decl_tricks ew_t = defen_tricks else : ns_t = defen_tricks ew_t = decl_tricks messages.append(m('tricks', NS = ns_t, EW = ew_t)) rel_idx = (decl_idx + 1) if len(cards_to_show) > 3 : lastrnd = cards_to_show[:4] lt_base = taker + rel_idx messages += [m('move', card = lastrnd[i], side = bridge.SIDES[(lt_base + i)%4]) for i in xrange(4)] move_offs = bridge.decl_tricks_and_next_move_offset(lastrnd, trump)[1] + taker currnd = cards_to_show[4:] else : currnd = cards_to_show move_offs = taker s = (rel_idx + move_offs) % 4 for card in currnd : messages.append(m('move', card = card, side = bridge.SIDES[s])) s = (s + 1) % 4 s = bridge.SIDES[(rel_idx + taker + lasttaker) % 4] if s == dummy_side and place == decl_side : messages[-1]['value']['next'] = dummy_side hand = actions.hand_left(deal.hand_by_side(dummy_side), moves) s = decl_side else : messages[-1]['value']['next'] = s if allow_moves and s == place: if rounds_total != full_rounds_played and bridge.has_same_suit(hand, currnd[0]): messages[-1]['value']['allowed'] = currnd[0] / 13 else : messages[-1]['value']['allowed'] = 'any' if table.claim is None : return messages tricks_s = table.claim[:2] tricks = int(table.claim[:2]) claim_side = table.claim[2] if tricks > 0 : claim_res = bridge.tricks_to_result(c, deal.vulnerability, tricks) messages.append(m('claim', side=claim_side, tricks=tricks_s, result=claim_res)) if bridge.relation_idx(claim_side, place) % 2 == 1 : #opponent claim part_side = bridge.SIDES[part_idx] messages.append(m('hand', cards=actions.hand_left(deal.hand_by_side(claim_side), moves), side=claim_side)) messages.append(m('hand', cards=actions.hand_left(deal.hand_by_side(part_side), moves), side=part_side)) messages.append(m('hand', cards=actions.hand_left(deal.hand_by_side(dummy_side), moves), side=dummy_side)) return messages
def test_3nt(self) : self.assertEquals(400, bridge.tricks_to_result('3Z', False, 9))