def get_metadata(self): to_return = "\n\n" if self.turn: seat_color = self.get_color_code(self.turn) to_return += "It is ^Y%s^~'s turn (%s%s^~)." % (self.turn.player_name, seat_color, self.turn) if self.whist: to_return += " Trumps are ^C%s^~." % self.trump_suit to_return += "\n" + self.get_trick_str() to_return += self.get_bid_str() to_return += "\nThe goal score for this game is ^C%s^~.\n" % get_plural_str(self.goal, "point") to_return += self.get_score_str() if self.positive: partner_str = "^Ymust have" else: partner_str = "^ydo not need to have" to_return += "(Both partners %s^~ a positive score to win.)\n" % partner_str if self.double != 7: if self.double: to_return += "Bids double value at ^C%s^~.\n" % get_plural_str(self.double, "trick") else: to_return += "Bids ^Rnever^~ double their value.\n" if self.minimum != 11: to_return += "The minimum bid for a deal is ^G%s^~.\n" % get_plural_str(self.minimum, "point") return to_return
def resolve_hand(self): for seat in self.seats: # Determine the score delta; if the bid is < self.double (or # doubling is disabled) it's just the bid, otherwise it's double. bid = seat.data.bid if bid < self.double or not self.double: score_delta = bid else: score_delta = bid * 2 score_delta_str = get_plural_str(score_delta, "point") result_str = "%s bid ^G%s^~ and " % (self.get_sp_str(seat), get_plural_str(bid, "trick")) if bid <= seat.data.tricks: # Woot, gain points! seat.data.score += score_delta result_str += "took ^W%d^~, gaining ^G%s^~.\n" % (seat.data.tricks, score_delta_str) else: # Aw, lost points. seat.data.score -= score_delta result_str += "only took ^W%d^~, losing ^R%s^~.\n" % (seat.data.tricks, score_delta_str) self.bc_pre(result_str) self.bc_pre(self.get_score_str())
def show(self, player): state = self.state.get() if state == "need_players": player.tell_cc("The game is not yet active.\n") else: for seat in self.seats: seat_str = "%s [^G%s^~, ^C%s^~]: " % (self.get_sp_str(seat), get_plural_str(seat.data.antidotes + seat.data.poisons, "potion"), get_plural_str(seat.data.score, "point")) if seat.data.is_dead: seat_str += "^Rdead!^~" else: seat_str += "^!%s^~ racked" % get_plural_str(len(seat.data.potion_rack), "potion") if seat == self.turn: if state == "playing": seat_str += " ^C[choosing]^~" elif state == "bidding": seat_str += " ^Y[bidding]^~" elif state == "quaffing": seat_str += " ^R[quaffing]^~" elif state == "bidding": if seat.data.is_bidding == False: seat_str += " ^M[passed]^~" elif seat.data.bid: seat_str += " [bid ^G%d^~]" % seat.data.bid player.tell_cc("%s\n" % seat_str) player.tell_cc("\nThe racks currently hold ^G%s^~.\n" % get_plural_str(self._count_racked_potions(), "potion")) player.tell_cc("\n\nThe goal score for this game is ^C%s^~.\n" % get_plural_str(self.goal, "point"))
def get_metadata(self): to_return = "\n\n" if self.turn: seat_color = self.get_color_code(self.turn) to_return += "%s is the hakem.\n" % (self.get_sp_str(self.hakem)) if self.trump_suit: trump_str = "^C%s^~" % self.trump_suit else: trump_str = "^cwaiting to be chosen^~" to_return += "It is ^Y%s^~'s turn (%s%s^~). Trumps are ^C%s^~.\n" % ( self.turn.player_name, seat_color, self.turn, trump_str) if self.mode == 4: to_return += "Tricks: ^RNorth/South^~: %d ^MEast/West^~: %d\n" % ( self.ns.tricks, self.ew.tricks) else: to_return += "Tricks: ^M%s^~: %d ^R%s^~: %d ^B%s^~: %d\n" % ( self.west.player_name, self.west.data.tricks, self.south.player_name, self.south.data.tricks, self.east.player_name, self.east.data.tricks) to_return += "The goal score for this game is ^C%s^~.\n" % get_plural_str( self.goal, "point") to_return += self.get_score_str() return to_return
def get_metadata_str(self): to_return = "^Y%s^~ remain in the draw pile.\n" % get_plural_str(len(self.draw_pile), "card") if not self.turn: to_return += "The game has not started yet.\n" else: to_return += "It is %s's turn to " % self.get_sp_str(self.turn) sub = self.state.get_sub() if sub == "play": to_return += "^cplay a card^~.\n" else: to_return += "^cdraw a card^~.\n" to_return += "The goal score for this game is ^Y%s^~.\n" % get_plural_str(self.goal, "point") to_return += "Overall: %s: %s %s: %s\n" % (self.get_sp_str(self.left), self.left.data.overall_score, self.get_sp_str(self.right), self.right.data.overall_score) return to_return
def autoquaff(self, seat): # If the bid is less than the number of potions the player has racked, # then we just quaff that many and deal with the consequences. Otherwise # we need to go into proper "quaff" mode. seat_rack = seat.data.potion_rack bid = seat.data.bid if len(seat_rack) > seat.data.bid: self.bc_pre("%s chugs ^C%s^~ from their own rack.\n" % (self.get_sp_str(seat), get_plural_str(bid, "potion"))) else: self.bc_pre("%s chugs ^Yall of the potions^~ from their own rack.\n" % self.get_sp_str(seat)) count = 0 poisoned = False while count < bid and seat_rack: potion = seat_rack.pop() if potion == "poison": poisoned = True count += 1 if poisoned: self.bc_pre("%s has managed to ^Rpoison^~ themselves!\n" % self.get_sp_str(seat)) self.drank_poison(seat, seat) else: self.bc_pre("%s has managed to survive their own potions.\n" % self.get_sp_str(seat)) if count == bid: self.drank_antidotes(seat) else: seat.data.quaffed = count self.tell_pre(seat.player, "You still must quaff ^C%s^~.\n" % get_plural_str(bid - count, "potion")) self.state.set("quaffing")
def bid(self, player, bid_str): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You're not playing!\n") return False elif seat != self.turn: self.tell_pre(player, "It's not your turn!\n") return False if not bid_str.isdigit(): self.tell_pre(player, "You didn't even send a number!\n") return False bid = int(bid_str) if bid < 1: self.tell_pre(player, "You must bid at least one point.\n") return False if bid > 13: self.tell_pre(player, "You can't bid more tricks than there are!\n") return False # Got a valid bid. seat.data.bid = bid self.bc_pre("%s has bid ^G%s^~.\n" % (self.get_sp_str(seat), get_plural_str(bid, "trick"))) return True
def evaluate(self, player): for seat in self.seats: score_str = "%s: " % seat.player_name score_str += " + ".join(["%s%s^~" % (get_color_code(x.suit), x.value) for x in seat.data.expeditions]) score_str += " = %s\n" % (get_plural_str(seat.data.curr_score, "point")) self.tell_pre(player, score_str)
def get_metadata(self): to_return = "\n\n" if self.turn: to_return += "It is ^Y%s^~'s turn (%s%s^~). Trumps are ^C%s^~.\n" % (self.turn.player_name, self.get_color_code(self.turn), self.turn, self.trump_suit) to_return += "Tricks: ^RNorth/South^~: %d ^MEast/West^~: %d\n" % (self.ns.tricks, self.ew.tricks) to_return += "The goal score for this game is ^C%s^~.\n" % get_plural_str(self.goal, "point") to_return += self.get_score_str() return to_return
def resolve_hand(self): for seat in self.left, self.right: addend = seat.data.curr_score if addend > 0: adj_str = "^Ygains ^C%s^~" % get_plural_str(addend, "point") elif addend < 0: adj_str = "^yloses ^c%s^~" % get_plural_str(-addend, "point") else: adj_str = "^Wsomehow manages to score precisely zero points^~" # Actually adjust the scores by the proper amounts, and inform # everyone of the result. seat.data.overall_score += addend # If someone resigned, scores don't matter, so don't show them. if not self.resigner: self.bc_pre("%s %s, giving them ^G%s^~.\n" % (self.get_sp_str(seat), adj_str, seat.data.overall_score))
def set_goal(self, player, goal_str): if not goal_str.isdigit(): self.tell_pre(player, "You didn't even send a number!\n") return False new_goal = int(goal_str) if new_goal < 1: self.tell_pre(player, "The goal must be at least one point.\n") return False # Got a valid goal. self.goal = new_goal self.bc_pre("^M%s^~ has changed the goal to ^G%s^~.\n" % (player, get_plural_str(new_goal, "point")))
def get_metadata(self): to_return = "\n\n" if self.turn: to_return += "It is ^Y%s^~'s turn (%s%s^~). Trumps are ^C%s^~.\n" % ( self.turn.player_name, self.get_color_code( self.turn), self.turn, self.trump_suit) to_return += "Tricks: ^RNorth/South^~: %d ^MEast/West^~: %d\n" % ( self.ns.tricks, self.ew.tricks) to_return += "The goal score for this game is ^C%s^~.\n" % get_plural_str( self.goal, "point") to_return += self.get_score_str() return to_return
def finish_hand(self): # Which side won more than 6 tricks? if self.ns.tricks > 6: winning_side = "^RNorth/South^~" addend = self.ns.tricks - 6 self.ns.score += addend else: winning_side = "^MEast/West^~" addend = self.ew.tricks - 6 self.ew.score += addend # Let everyone know. self.bc_pre("%s wins the hand and gains ^C%s^~.\n" % (winning_side, get_plural_str(addend, "point"))) self.bc_pre(self.get_score_str())
def bid(self, player, bid_str): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You're not playing!\n") return False if seat.data.is_dead: self.tell_pre(player, "You're dead!\n") return False # You can bid either during the 'play' phase or the 'bid' phase. state = self.state.get() if state != "playing" and state != "bidding": self.tell_pre(player, "You can't bid right now.\n") return False if seat != self.turn: self.tell_pre(player, "It's not your turn.\n") return False # Okay, it's a legitimate time to bid. Is the bid valid? if not bid_str.isdigit(): self.tell_pre(player, "You didn't even bid a number!\n") return False bid_value = int(bid_str) # It has to be at least one. if not bid_value: self.tell_pre(player, "Nice try, but you can't bid zero.\n") return False # Is the bid value <= the number of potions available? if bid_value > self._count_racked_potions(): self.tell_pre(player, "There aren't that many racked potions to quaff!\n") return False # If we're in the bidding phase, is it higher than the current bid? if state == "bidding" and bid_value <= self.highest_bidder.data.bid: self.tell_pre(player, "That bid isn't higher than the current bid of ^C%d^~.\n" % self.highest_bidder.data.bid) return False # Valid bid, phew. Let everyone know and note it down. self.bc_pre("%s has bid to quaff ^C%s^~.\n" % (self.get_sp_str(seat), get_plural_str(bid_value, "potion"))) seat.data.bid = bid_value return True
def move(self, player, move_bits): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You can't move; you're not playing!\n") return False if seat != self.turn: self.tell_pre(player, "You must wait for your turn to move.\n") return False col, row = move_bits # Is the move on the board? if not self.layout.is_valid(row, col): self.tell_pre(player, "Your move is out of bounds.\n") return False # Is it a valid Tanbo play? piece = self.can_place_at(seat, row, col) if not piece: self.tell_pre( player, "That location is not adjacent to exactly one of your pieces.\n" ) return False # Valid. Put the piece there. move_str = "%s%s" % (COLS[col], row + 1) self.layout.place(piece, row, col, True) # Update the root statuses. root_kill_str = "" root_kill = self.update_roots(row, col) if root_kill < 0: root_kill_str = ", ^ysuiciding the root^~" elif root_kill > 0: root_kill_str = ", ^Ykilling %s^~" % (get_plural_str( root_kill, "root")) self.bc_pre("%s grows a root to ^C%s^~%s.\n" % (self.get_sp_str(seat), move_str, root_kill_str)) return True
def show_scores(self, player): player.tell_cc("\nSCORES:\n\n") state = "yellow" for seat in self.seats: player_str = seat.player_name if state == "yellow": name_color_code = "^Y" score_color_code = "^C" state = "magenta" elif state == "magenta": name_color_code = "^M" score_color_code = "^G" state = "yellow" tell_string = " ^R%s^~: %s%s^~, %s%s^~" % ( seat, name_color_code, player_str, score_color_code, get_plural_str(seat.data.score, "point")) player.tell_cc(tell_string + "\n") player.tell_cc("\n")
def move(self, player, move_bits): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You can't move; you're not playing!\n") return False if seat != self.turn: self.tell_pre(player, "You must wait for your turn to move.\n") return False col, row = move_bits # Is the move on the board? if not self.layout.is_valid(row, col): self.tell_pre(player, "Your move is out of bounds.\n") return False # Is this move a valid play? if not self.is_valid_play(seat, row, col): self.tell_pre(player, "That move is not valid.\n") return False # Valid. Put a piece there. move_str = "%s%s" % (COLS[col], row + 1) piece = self.get_new_piece(seat) seat.data.groups.append(piece) self.layout.place(piece, row, col, True) # Update the board, making any captures. capture_str = "" self.move_was_capture = False capture_count = self.update_board(row, col) if capture_count: capture_str = ", ^Ycapturing %s^~" % (get_plural_str( capture_count, "group")) self.move_was_capture = True self.bc_pre("%s places a piece at ^C%s^~%s.\n" % (self.get_sp_str(seat), move_str, capture_str)) seat.data.made_move = True return True
def red(self, player, move_bits): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You can't move; you're not playing!\n") return False if seat != self.turn: self.tell_pre(player, "You must wait for your turn to move.\n") return False col, row = move_bits # Is the move on the board? if not self.layout.is_valid(row, col): self.tell_pre(player, "Your move is out of bounds.\n") return False # Is there a piece already there? if self.layout.grid[row][col]: self.tell_pre(player, "There is already a piece there.\n") return False # Is it not a capturing move? piece = self.rp if not self.move_is_capture(piece, row, col): self.tell_pre(player, "That would not cause a capture.\n") return False # Valid. Put the piece there. move_str = "%s%s" % (COLS[col], row + 1) self.layout.place(piece, row, col, True) # Redstones by definition make captures. capture_count = self.capture(row, col) self.bc_pre("%s places a ^Rredstone^~ at ^C%s^~, ^Ycapturing %s^~.\n" % (self.get_sp_str(seat), move_str, get_plural_str(capture_count, "stone"))) seat.data.made_move = True return True
def get_metadata(self): to_return = "\n\n" if self.turn: seat_color = self.get_color_code(self.turn) to_return += "%s is the hakem.\n" % (self.get_sp_str(self.hakem)) if self.trump_suit: trump_str = "^C%s^~" % self.trump_suit else: trump_str = "^cwaiting to be chosen^~" to_return += "It is ^Y%s^~'s turn (%s%s^~). Trumps are ^C%s^~.\n" % (self.turn.player_name, seat_color, self.turn, trump_str) if self.mode == 4: to_return += "Tricks: ^RNorth/South^~: %d ^MEast/West^~: %d\n" % (self.ns.tricks, self.ew.tricks) else: to_return += "Tricks: ^M%s^~: %d ^R%s^~: %d ^B%s^~: %d\n" % (self.west.player_name, self.west.data.tricks, self.south.player_name, self.south.data.tricks, self.east.player_name, self.east.data.tricks) to_return += "The goal score for this game is ^C%s^~.\n" % get_plural_str(self.goal, "point") to_return += self.get_score_str() return to_return
def set_minimum(self, player, minimum_str): if not minimum_str.isdigit(): self.tell_pre(player, "You didn't even send a number!\n") return False new_minimum = int(minimum_str) # It doesn't make sense for the minimum to be below 4, as that's the # lowest possible bid anyhow. 13 is a plausible maximum. if new_minimum < 4: self.tell_pre(player, "The minimum must be at least 4 points.\n") return False if new_minimum > 13: self.tell_pre(player, "The minimum must be at most 13 points.\n") return False # Got a valid minimum. self.minimum = new_minimum self.bc_pre("^M%s^~ has changed the minimum to ^G%s^~.\n" % (player, get_plural_str(new_minimum, "point")))
def inventory(self, player): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You're not playing!\n") return False self.tell_pre(player, "You have ^C%s^~ and ^R%s^~ overall.\n" % (get_plural_str(seat.data.antidotes, "antidote"), get_plural_str(seat.data.poisons, "poison"))) rack_str = "" for potion in seat.data.potion_rack: if potion == "antidote": rack_str += "^C[A]^~ " elif potion == "poison": rack_str += "^R*P*^~ " else: rack_str += "^Y???^~ " if not rack_str: rack_str = "^!Empty!^~" self.tell_pre(player, "Your current rack: %s\n" % rack_str)
def move(self, player, move_bits): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You can't move; you're not playing!\n") return False if seat != self.turn: self.tell_pre(player, "You must wait for your turn to move.\n") return False col, row = move_bits # Is the move on the board? if not self.layout.is_valid(row, col): self.tell_pre(player, "Your move is out of bounds.\n") return False # Is this move a valid play? if not self.is_valid_play(seat, row, col): self.tell_pre(player, "That move is not valid.\n") return False # Valid. Put a piece there. move_str = "%s%s" % (COLS[col], row + 1) piece = self.get_new_piece(seat) seat.data.groups.append(piece) self.layout.place(piece, row, col, True) # Update the board, making any captures. capture_str = "" self.move_was_capture = False capture_count = self.update_board(row, col) if capture_count: capture_str = ", ^Ycapturing %s^~" % (get_plural_str(capture_count, "group")) self.move_was_capture = True self.bc_pre("%s places a piece at ^C%s^~%s.\n" % (self.get_sp_str(seat), move_str, capture_str)) seat.data.made_move = True return True
def move(self, player, move_bits): seat = self.get_seat_of_player(player) if not seat: self.tell_pre(player, "You can't move; you're not playing!\n") return False if seat != self.turn: self.tell_pre(player, "You must wait for your turn to move.\n") return False col, row = move_bits # Is the move on the board? if not self.layout.is_valid(row, col): self.tell_pre(player, "Your move is out of bounds.\n") return False # Is it a valid Tanbo play? piece = self.can_place_at(seat, row, col) if not piece: self.tell_pre(player, "That location is not adjacent to exactly one of your pieces.\n") return False # Valid. Put the piece there. move_str = "%s%s" % (COLS[col], row + 1) self.layout.place(piece, row, col, True) # Update the root statuses. root_kill_str = "" root_kill = self.update_roots(row, col) if root_kill < 0: root_kill_str = ", ^ysuiciding the root^~" elif root_kill > 0: root_kill_str = ", ^Ykilling %s^~" % (get_plural_str(root_kill, "root")) self.bc_pre("%s grows a root to ^C%s^~%s.\n" % (self.get_sp_str(seat), move_str, root_kill_str)) return True
def show_scores(self, player): player.tell_cc("\nSCORES:\n\n") state = "yellow" for seat in self.seats: player_str = seat.player_name if state == "yellow": name_color_code = "^Y" score_color_code = "^C" state = "magenta" elif state == "magenta": name_color_code = "^M" score_color_code = "^G" state = "yellow" tell_string = " ^R%s^~: %s%s^~, %s%s^~" % ( seat, name_color_code, player_str, score_color_code, get_plural_str(seat.data.score, "point"), ) player.tell_cc(tell_string + "\n") player.tell_cc("\n")
def resolve_hand(self, winner): # Assume the hakem won and there was no sweep; we'll adjust later. hakem_won = True swept = False # 4p mode shenanigans first. if self.mode == 4: if winner == self.ns: winning_str = "^RNorth/South^~" if self.hakem != self.seats[0] and self.hakem != self.seats[2]: hakem_won = False loser = self.ew else: winning_str = "^MEast/West^~" if self.hakem != self.seats[1] and self.hakem != self.seats[3]: hakem_won = False loser = self.ns # Did the loser get no tricks? If so, the winner swept! if loser.tricks == 0: swept = True else: # 3P mode. Check whether the hakem really won... if winner != self.hakem: hakem_won = False # ...and whether the winner swept. prev_tricks = self.prev_seat(winner).data.tricks next_tricks = self.next_seat(winner).data.tricks if not prev_tricks and not next_tricks: swept = True winning_str = self.get_sp_str(winner) if swept: action_str = "^Yswept^~" # 2 points if the hakem won, 3 if others did. if hakem_won: addend = 2 else: addend = 3 else: # Standard win. One point. action_str = "^Wwon^~" addend = 1 # Let everyone know. self.bc_pre("%s %s the hand and gains ^C%s^~.\n" % (winning_str, action_str, get_plural_str(addend, "point"))) # Apply the score. if self.mode == 4: winner.score += addend else: winner.data.score += addend # Show everyone's scores. self.bc_pre(self.get_score_str()) # Did the hakem not win? If so, we need to have a new hakem and dealer. if not hakem_won: # In 4p mode, it just rotates... if self.mode == 4: self.dealer = self.hakem self.hakem = self.next_seat(self.hakem) else: # In 3p mode, the winner becomes hakem. self.hakem = winner self.dealer = self.prev_seat(self.hakem) self.bc_pre( "The ^Yhakem^~ has been unseated! The new hakem is %s.\n" % self.get_sp_str(self.hakem)) else: self.bc_pre("%s remains the hakem.\n" % self.get_sp_str(self.hakem))
def resolve_hand(self, winner): # Assume the hakem won and there was no sweep; we'll adjust later. hakem_won = True swept = False # 4p mode shenanigans first. if self.mode == 4: if winner == self.ns: winning_str = "^RNorth/South^~" if self.hakem != self.seats[0] and self.hakem != self.seats[2]: hakem_won = False loser = self.ew else: winning_str = "^MEast/West^~" if self.hakem != self.seats[1] and self.hakem != self.seats[3]: hakem_won = False loser = self.ns # Did the loser get no tricks? If so, the winner swept! if loser.tricks == 0: swept = True else: # 3P mode. Check whether the hakem really won... if winner != self.hakem: hakem_won = False # ...and whether the winner swept. prev_tricks = self.prev_seat(winner).data.tricks next_tricks = self.next_seat(winner).data.tricks if not prev_tricks and not next_tricks: swept = True winning_str = self.get_sp_str(winner) if swept: action_str = "^Yswept^~" # 2 points if the hakem won, 3 if others did. if hakem_won: addend = 2 else: addend = 3 else: # Standard win. One point. action_str = "^Wwon^~" addend = 1 # Let everyone know. self.bc_pre("%s %s the hand and gains ^C%s^~.\n" % (winning_str, action_str, get_plural_str(addend, "point"))) # Apply the score. if self.mode == 4: winner.score += addend else: winner.data.score += addend # Show everyone's scores. self.bc_pre(self.get_score_str()) # Did the hakem not win? If so, we need to have a new hakem and dealer. if not hakem_won: # In 4p mode, it just rotates... if self.mode == 4: self.dealer = self.hakem self.hakem = self.next_seat(self.hakem) else: # In 3p mode, the winner becomes hakem. self.hakem = winner self.dealer = self.prev_seat(self.hakem) self.bc_pre("The ^Yhakem^~ has been unseated! The new hakem is %s.\n" % self.get_sp_str(self.hakem)) else: self.bc_pre("%s remains the hakem.\n" % self.get_sp_str(self.hakem))
def set_double(self, player, double_str): if not double_str.isdigit(): self.tell_pre(player, "You didn't even send a number!\n") return False new_double = int(double_str) if new_double > 13: self.tell_pre(player, "The doubling value must be at most 13 tricks.\n") return False # Got a valid double value. self.double = new_double if self.double: self.bc_pre("^M%s^~ has changed the doubling value to ^G%s^~.\n" % (player, get_plural_str(new_double, "trick"))) else: self.bc_pre("^M%s^~ has ^Rdisabled^~ doubling values.\n" % (player,))
def set_bonus(self, player, bonus_bits): if len(bonus_bits) == 1: bonus = bonus_bits[0] # Gotta be 'none' or 0. if bonus in ("none", "n", "0",): self.bonus = False self.bc_pre("^M%s^~ has disabled the expedition bonuses.\n" % player) return True else: self.tell_pre(player, "Invalid bonus command.\n") return False elif len(bonus_bits) == 2: points, length = bonus_bits if not points.isdigit() or not length.isdigit(): self.tell_pre(player, "Invalid bonus command.\n") return False points = int(points) length = int(length) if not points or not length: self.bonus = False self.bc_pre("^M%s^~ has disabled the expedition bonuses.\n" % player) return True else: self.bonus = True self.bonus_points = points self.bonus_length = length self.bc_pre("^M%s^~ has set the expedition bonuses to ^C%s^~ at length ^R%s^~.\n" % (player, get_plural_str(points, "point"), length)) return True else: self.tell_pre(player, "Invalid bonus command.\n") return False
def handle(self, player, command_str): # Handle common commands. handled = self.handle_common_commands(player, command_str) if not handled: state = self.state.get() command_bits = command_str.split() primary = command_bits[0].lower() if state == "setup": if primary in ("goal", "score", "sc", "g",): if len(command_bits) == 2: self.set_goal(player, command_bits[1]) else: self.tell_pre(player, "Invalid goal command.\n") handled = True elif primary in ("positive", "pos", "po", "p",): if len(command_bits) == 2: self.set_positive(player, command_bits[1]) else: self.tell_pre(player, "Invalid positive command.\n") handled = True elif primary in ("double", "doub",): if len(command_bits) == 2: self.set_double(player, command_bits[1]) else: self.tell_pre(player, "Invalid double command.\n") handled = True elif primary in ("minimum", "min",): if len(command_bits) == 2: self.set_minimum(player, command_bits[1]) else: self.tell_pre(player, "Invalid minimum command.\n") handled = True elif primary in ("whist", "wh",): if len(command_bits) == 2: self.set_whist(player, command_bits[1]) else: self.tell_pre(player, "Invalid whist command.\n") handled = True elif primary in ("done", "ready", "d", "r",): self.bc_pre("The game is now looking for players.\n") self.state.set("need_players") handled = True elif state == "need_players": if primary in ("config", "setup", "conf",): self.state.set("setup") self.bc_pre("^R%s^~ has switched the game to setup mode.\n" % player) handled = True elif state == "bidding": if primary in ("hand", "inventory", "inv", "i",): self.show_hand(player) handled = True elif primary in ("bid", "b",): if len(command_bits) == 2: bid_made = self.bid(player, command_bits[1]) else: self.tell_pre(player, "Invalid bid command.\n") handled = True if bid_made: bid_list = [x for x in self.seats if x.data.bid] if len(bid_list) == 4: # Bidding is complete. Are enough tricks bid? bid_total = 0 point_total = 0 for seat in self.seats: bid = seat.data.bid bid_total += bid point_total += bid # Bids of self.double or more count double, if set. if self.double: if bid >= self.double: point_total += bid bid_str = get_plural_str(bid_total, "trick") point_str = get_plural_str(point_total, "point") if point_total >= self.minimum: # Enough indeed. Start the game proper. self.bc_pre("With ^W%s^~ bid for a total of ^C%s^~, play begins!\n" % (bid_str, point_str)) self.state.set("playing") self.turn = self.next_seat(self.turn) if self.turn.player: self.show_hand(self.turn.player) else: # Not enough. Throw hands in and deal fresh. self.bc_pre("With only ^R%s^~ bid, everyone throws in their hand.\n" % bid_str) self.dealer = self.next_seat(self.dealer) # Deal and set up the first player to bid. self.new_deal() self.turn = self.next_seat(self.dealer) if self.turn.player: self.tell_pre(self.turn.player, "It is your turn to bid.\n") else: # Still need more bids. self.turn = self.next_seat(self.turn) if self.turn.player: self.tell_pre(self.turn.player, "It is your turn to bid.\n") self.show_hand(self.turn.player) # No matter what happened, update the layout. self.layout.change_turn(self.turn.data.who) elif state == "playing": card_played = False if primary in ("hand", "inventory", "inv", "i",): self.show_hand(player) handled = True elif primary in ("play", "move", "pl", "mv",): if len(command_bits) == 2: card_played = self.play(player, command_bits[1]) else: self.tell_pre(player, "Invalid play command.\n") handled = True if card_played: # A card hit the table. We need to do stuff. if len(self.trick) == 4: # Finish the trick up. self.finish_trick() # Is that the last trick? if self.north.data.tricks + self.west.data.tricks + self.south.data.tricks + self.east.data.tricks == 13: # Resolve the hand... self.resolve_hand() # And look for a winner. winner = self.find_winner() if winner: # Found a winner. Finish. self.resolve(winner) self.finish() else: # No winner. Pass the deal to the next player... self.dealer = self.next_seat(self.dealer) # Deal and set up the first player to bid. self.new_deal() self.turn = self.next_seat(self.dealer) self.layout.change_turn(self.turn.data.who) self.state.set("bidding") if self.turn.player: self.tell_pre(self.turn.player, "It is your turn to bid.\n") else: # Trick not over. Rotate. self.turn = self.next_seat(self.turn) self.layout.change_turn(self.turn.data.who) if self.turn.player: self.show_hand(self.turn.player) if not handled: self.tell_pre(player, "Invalid command.\n")
def pick(self, player, pick_str): seat = self.get_seat_of_player(player) if seat != self.turn: self.tell_pre(player, "It's not your turn!\n") return False # In the case where we're picking someone to be first player because we # killed ourselves via poison, the valid list is those players who are # still alive. If we're quaffing, they have to have potions on their # rack. state = self.state.get() if state == "choosing_player": valid_choices = [x for x in self.seats if not x.data.is_dead] elif state == "quaffing": valid_choices = [x for x in self.seats if x.data.potion_rack] else: self.tell_pre(player, "Not sure how you got here, but you can't pick!\n") return False # All right. Let's try to parse out their pick_str. We're going to # be super-lazy and only use the first letter to match. their_pick = pick_str.lower()[0] actual_pick = [x for x in valid_choices if x.name[0] == their_pick] if not actual_pick: self.tell_pre(player, "You can't pick that seat for this!\n") return False # We got a seat. Sweet. If it's for choosing a player, start a new # round with them as the start player. picked_seat = actual_pick[0] if state == "choosing_player": self.bc_pre("%s has chosen %s to be the new starting player.\n" % (self.get_sp_str(seat), self.get_sp_str(picked_seat))) self.new_round(picked_seat) return True else: # state == "quaffing" # Get the newest potion from that seat. potion = picked_seat.data.potion_rack.pop() # If it's a poison, we've been poisoned! if potion == "poison": self.bc_pre("%s chugs a potion from %s and is ^Rpoisoned^~!\n" % (self.get_sp_str(seat), self.get_sp_str(picked_seat))) self.drank_poison(seat, picked_seat) else: # Not a poison; increase quaffing count... self.bc_pre("%s chugs a potion from %s and keeps it down somehow.\n" % (self.get_sp_str(seat), self.get_sp_str(picked_seat))) seat.data.quaffed += 1 # If we've drank enough, we're done! if seat.data.quaffed == seat.data.bid: self.drank_antidotes(seat) return True else: self.tell_pre(seat.player, "You still must quaff ^C%s^~.\n" % get_plural_str(seat.data.bid - seat.data.quaffed, "potion")) return True
def handle(self, player, command_str): # Handle common commands. handled = self.handle_common_commands(player, command_str) if not handled: state = self.state.get() command_bits = command_str.split() primary = command_bits[0].lower() played = False bid = False if state == "need_players": if primary in ('antidotes', 'anti', 'an'): if len(command_bits) == 2: self.set_antidote_count(player, command_bits[1]) else: self.tell_pre(player, "Invalid antidotes command.\n") handled = True elif primary in ('poisons', 'pois', 'po'): if len(command_bits) == 2: self.set_poison_count(player, command_bits[1]) else: self.tell_pre(player, "Invalid poisons command.\n") handled = True elif primary in ('goal', 'score'): if len(command_bits) == 2: self.set_goal(player, command_bits[1]) else: self.tell_pre(player, "Invalid goal command.\n") handled = True elif primary in ('start',): player_count = len([x for x in self.seats if x.player]) if player_count < 3: self.tell_pre(player, "Need at least 3 players!\n") else: self.channel.broadcast_cc(self.prefix + "Game on!\n") self.start_game() handled = True elif state == "initial_placement": if primary in _PLAY_LIST: if len(command_bits) == 2: played = self.play(player, command_bits[1]) else: self.tell_pre(player, "Invalid play command.\n") handled = True elif primary in _INVENTORY_LIST: self.inventory(player) handled = True elif state == "playing": if primary in _PLAY_LIST: if len(command_bits) == 2: played = self.play(player, command_bits[1]) else: self.tell_pre(player, "Invalid play command.\n") handled = True elif primary in _INVENTORY_LIST: self.inventory(player) handled = True elif primary in _BID_LIST: if len(command_bits) == 2: bid = self.bid(player, command_bits[1]) else: self.tell_pre(player, "Invalid bid command.\n") handled = True if played: # It's the next player's turn. self.turn = self.next_seat(self.turn) self.tell_pre(self.turn.player, "It is your turn.\n") elif bid: # If the bid is for "every potion there is," immediately # jump to autoquaff mode. if self._count_racked_potions() == self.turn.data.bid: self.bc_pre("%s has bid for all the potions!\n" % self.get_sp_str(self.turn)) self.state.set("autoquaffing") else: # Start of a bidding round. Make sure everyone can bid. self.state.set("bidding") for seat in self.seats: if seat != self.turn: seat.data.bid = 0 if not seat.data.is_dead: seat.data.is_bidding = True # ...set the high bid... self.highest_bidder = self.turn # ...and pass the buck. self.turn = self.next_seat(self.turn, bidding=True) self.tell_pre(self.turn.player, "It is your turn to bid or pass.\n") elif state == "bidding": if primary in _BID_LIST: if len(command_bits) == 2: bid = self.bid(player, command_bits[1]) else: self.tell_pre(player, "Invalid bid command.\n") handled = True elif primary in _INVENTORY_LIST: self.inventory(player) handled = True elif primary in ('pass', 'pa', 'p'): # No need for a function, as this one's easy. self.turn.data.is_bidding = False self.bc_pre("%s has passed and is no longer bidding.\n" % self.get_sp_str(self.turn)) # Get the next player... self.turn = self.next_seat(self.turn, bidding=True) # ...and see if it's the highest bidder. If it is, they # won the bidding. if self.turn == self.highest_bidder: self.bc_pre("%s has won the bid with ^Y%s^~.\n" % (self.get_sp_str(self.turn), get_plural_str(self.turn.data.bid, "potion"))) self.state.set("autoquaffing") else: self.tell_pre(self.turn.player, "It is your turn to bid or pass.\n") handled = True if bid: # If the bid is the count of racked potions, we're done. if self._count_racked_potions() == self.turn.data.bid: self.bc_pre("%s has bid for all the potions!\n" % self.get_sp_str(self.turn)) self.state.set("autoquaffing") else: # New highest bidder. Set it and go around. self.highest_bidder = self.turn self.turn = self.next_seat(self.turn, bidding=True) self.tell_pre(self.turn.player, "It is your turn to bid or pass.\n") elif state == "choosing_player" or state == "quaffing": if primary in _PICK_LIST: if len(command_bits) == 2: self.pick(player, command_bits[1]) else: self.tell_pre(player, "Invalid pick command.\n") handled = True elif primary in _INVENTORY_LIST: self.inventory(player) handled = True elif state == "tossing": if primary in ('toss', 'to'): if len(command_bits) == 2: self.toss(player, command_bits[1]) else: self.tell_pre(player, "Invalid toss command.\n") handled = True elif primary in _INVENTORY_LIST: self.inventory(player) handled = True if not handled: self.tell_pre(player, "Invalid command.\n")