docs: def tick(self):
          """
          Advances time in the game. Use this once all "choices" have been submitted for the current
          game state using the other methods.
          """
          if self.state == AuctionState.NOMINATE:
              # if no nominee submitted, exception
              if self.nominee is None:
                  raise InvalidActionError("Tick was invoked during nomination but no nominee was selected.")
              self.state = AuctionState.BID
              # initialize bids array to hold each owner's bid
              # this holds the latest bids submitted for the current bidding phase
              self.bids = [self.bid if i == self.turn_index else 0 for i in range(len(self.owners))]
              # this holds the bids submitted on a given tick
              self.tickbids = [0] * len(self.owners)
          elif self.state == AuctionState.BID:
              # If no new bids submitted, we're done with this bid and the player gets what they bid for
              if not any(bid > 0 for bid in self.tickbids):
                  winner = self._winning_owner()
                  winner.buy(self.nominee, self.bid)
                  self._player_ownership[self._nominee_index] = self.winning_owner_index()
                  self.undrafted_players.remove(self.nominee)
                  self.nominee = None
                  self._nominee_index = -1
                  # check if we're done, or move to the next player who still has space
                  done = True
                  for i in range(len(self.owners)):
                      next_turn = (self.turn_index + 1 + i) % len(self.owners)
                      if self.owners[next_turn].remaining_picks() > 0:
                          self.turn_index = next_turn
                          done = False
                          break
                  # if we didn't move on, we're done
                  if done:
                      self.state = AuctionState.DONE
                  else:
                      self.state = AuctionState.NOMINATE
              else:
                  # new bids have been submitted,
                  # randomly pick the bid to accept from the highest,
                  # then everyone gets a chance to submit more
                  top_idxs = [i for i, bid in enumerate(self.tickbids) if bid == max(self.tickbids)]
                  accept_idx = random.choice(top_idxs)
                  # set this as the new bid
                  self.bid = self.tickbids[accept_idx]
                  # update the bids for this round
                  self.bids[accept_idx] = self.bid
                  # clear this for the next tick
                  self.tickbids = [0] * len(self.owners)