def run_buzzin_attempts(screen, question, answer, question_score,
                        answered_questions, player_names, scores,
                        daily_doubles):
    state = QUESTION_PRE_BUZZ  # was QUESTION_PRE_BUZZ_EXIT until now
    state_start_time = time.time()

    players_allowed = set((NOBODY_BUZZED, ) + tuple(range(len(player_names))))

    mis_buzz_players = set()
    mis_buzz_player_penalty = [
        0,
    ] * len(player_names)

    buzzed_in_player_id = NOBODY_BUZZED

    # should draw something to show our readyness for buzzing
    while state not in END_STATES:
        previous_state = state
        player_name = ("" if buzzed_in_player_id == NOBODY_BUZZED else
                       player_names[buzzed_in_player_id])
        draw_window_question_prompts_and_refresh(
            screen,
            question,
            player_names,
            buzzed_in_player_id,
            state=state,
            mis_buzz_players=mis_buzz_players)
        if state in STATES_WITH_BUZZ_OPEN:
            buzzed_in_player_id = wait_4_buzz(players_allowed,
                                              mis_buzz_player_penalty)
            if state == QUESTION_PRE_BUZZ:
                if buzzed_in_player_id == NOBODY_BUZZED:
                    state = QUESTION_BUZZ_OPEN
                else:
                    mis_buzz_players.add(buzzed_in_player_id)
                    mis_buzz_player_penalty[buzzed_in_player_id] = (min(
                        5, mis_buzz_player_penalty[buzzed_in_player_id] + 1))
                continue  # makes for less indendation below

            # everything below here is state != QUESTION_PRE_BUZZ
            # thanks to continue above
            if buzzed_in_player_id == NOBODY_BUZZED:
                # Make sure players have had some time to answer first
                if time.time() - state_start_time > MIN_QUESTION_TIME:
                    audio.everybody_wrong()
                    state = QUESTION_EVERYBODY_WRONG
            else:  # else a real player
                audio.beep_for_player(buzzed_in_player_id)
                players_allowed.remove(buzzed_in_player_id)
                state = QUESTION_WAIT_ANSWER
        else:
            # only possible state we could be in, two END_STATES stop the loop
            # three apply to above if, one is never in this loop
            assert (state == QUESTION_WAIT_ANSWER)

            if run_wait_for_right_wrong(screen):
                adjust_score_and_save(buzzed_in_player_id, answered_questions,
                                      player_names, scores, daily_doubles,
                                      question_score)
                state = QUESTION_ANSWERED_RIGHT
                audio.correct()
            else:
                adjust_score_and_save(buzzed_in_player_id, answered_questions,
                                      player_names, scores, daily_doubles,
                                      -question_score)
                # if all the players have had a chance
                if len(players_allowed) == 1:
                    audio.everybody_wrong()
                    state = QUESTION_EVERYBODY_WRONG
                else:
                    audio.wrong()
                    state = QUESTION_BUZZ_OPEN_AFTER_WRONG

        if previous_state != state:
            state_start_time = time.time()

    # state is one of these two,
    # this approach is a a little more defensive against future changes
    # vs just testing == QUESTION_ANSWERED_WRONG outright
    if state != QUESTION_ANSWERED_RIGHT:
        assert (state == QUESTION_EVERYBODY_WRONG)
        draw_window_question_prompts_and_refresh(screen,
                                                 question,
                                                 player_names,
                                                 buzzed_in_player_id,
                                                 state=state)
        run_until_space(screen)

    draw_window_question_prompts_and_refresh(screen,
                                             answer,
                                             player_names,
                                             buzzed_in_player_id,
                                             state=state)
    run_until_space(screen)
def run_buzzin_attempts(
    screen, question, answer, question_score,
    answered_questions, player_names, scores, daily_doubles):
    state = QUESTION_PRE_BUZZ # was QUESTION_PRE_BUZZ_EXIT until now
    state_start_time = time.time()

    players_allowed = set(
        (NOBODY_BUZZED,) +
        tuple( range(len(player_names)) ))

    mis_buzz_players = set()
    mis_buzz_player_penalty = [ 0, ] * len(player_names)

    buzzed_in_player_id = NOBODY_BUZZED

    # should draw something to show our readyness for buzzing
    while state not in END_STATES:
        previous_state = state
        player_name = ("" if buzzed_in_player_id == NOBODY_BUZZED
                       else player_names[buzzed_in_player_id] )
        draw_window_question_prompts_and_refresh(
            screen, question, player_names, buzzed_in_player_id, state=state,
            mis_buzz_players=mis_buzz_players)
        if state in STATES_WITH_BUZZ_OPEN:
            buzzed_in_player_id = wait_4_buzz(players_allowed,
                                              mis_buzz_player_penalty)
            if state == QUESTION_PRE_BUZZ:
                if buzzed_in_player_id == NOBODY_BUZZED:
                    state = QUESTION_BUZZ_OPEN
                else:
                    mis_buzz_players.add(buzzed_in_player_id)
                    mis_buzz_player_penalty[buzzed_in_player_id] = (
                        min(5, mis_buzz_player_penalty[buzzed_in_player_id]+1))
                continue # makes for less indendation below

            # everything below here is state != QUESTION_PRE_BUZZ
            # thanks to continue above
            if buzzed_in_player_id == NOBODY_BUZZED:
                # Make sure players have had some time to answer first
                if time.time() - state_start_time > MIN_QUESTION_TIME:
                    audio.everybody_wrong()
                    state = QUESTION_EVERYBODY_WRONG
            else: # else a real player
                audio.beep_for_player(buzzed_in_player_id)
                players_allowed.remove(buzzed_in_player_id)
                state = QUESTION_WAIT_ANSWER
        else:
            # only possible state we could be in, two END_STATES stop the loop
            # three apply to above if, one is never in this loop
            assert(state == QUESTION_WAIT_ANSWER)

            if run_wait_for_right_wrong(screen):
                adjust_score_and_save(
                    buzzed_in_player_id, answered_questions, player_names,
                    scores, daily_doubles, question_score)
                state = QUESTION_ANSWERED_RIGHT
                audio.correct()
            else:
                adjust_score_and_save(
                    buzzed_in_player_id, answered_questions, player_names,
                    scores, daily_doubles, -question_score)
                # if all the players have had a chance
                if len(players_allowed) == 1:
                    audio.everybody_wrong()
                    state = QUESTION_EVERYBODY_WRONG
                else:
                    audio.wrong()
                    state = QUESTION_BUZZ_OPEN_AFTER_WRONG

        if previous_state != state:
            state_start_time = time.time()

    # state is one of these two,
    # this approach is a a little more defensive against future changes
    # vs just testing == QUESTION_ANSWERED_WRONG outright
    if state != QUESTION_ANSWERED_RIGHT:
        assert(state == QUESTION_EVERYBODY_WRONG)
        draw_window_question_prompts_and_refresh(
            screen, question, player_names, buzzed_in_player_id, state=state )
        run_until_space(screen)

    draw_window_question_prompts_and_refresh(
        screen, answer, player_names, buzzed_in_player_id, state=state )
    run_until_space(screen)
def run_question(screen, category, question, answer, is_dd, question_score,
                 selected_question, answered_questions, player_names, scores,
                 daily_doubles, answer_server):

    answer_server.current_answer = answer

    if is_dd:
        draw_daily_double_splash(screen, player_names, scores)
        pick_player = pick_dd_player(screen, player_names)
        if pick_player == None:
            return False
        else:
            draw_daily_double_splash(screen, (player_names[pick_player], ),
                                     (scores[pick_player], ))
            how_much = input_dd_player_wager(
                screen, MIN_DAILY_DOUBLE_WAGER,
                max(scores[pick_player], MAX_DAILY_DOUBLE_FOR_NEG))

    pre_question = (question if not SHOW_CATEGORY else "%s for %s" %
                    (category, question_score if not is_dd else how_much))

    draw_window_question_prompts_and_refresh(screen,
                                             pre_question,
                                             player_names,
                                             NOBODY_BUZZED,
                                             state=QUESTION_PRE_BUZZ_EXIT)

    while True:
        event = screen.getch()

        if event == ord('s'):
            if is_dd:
                draw_window_question_prompts_and_refresh(
                    screen, question, player_names, pick_player,
                    QUESTION_WAIT_ANSWER)
                correct = run_wait_for_right_wrong(screen)
                scores[pick_player] += (how_much if correct else -how_much)
                if correct:
                    draw_window_question_prompts_and_refresh(
                        screen, answer, player_names, pick_player,
                        QUESTION_ANSWERED_RIGHT)
                else:
                    draw_window_question_prompts_and_refresh(
                        screen, question, player_names, pick_player,
                        QUESTION_EVERYBODY_WRONG)
                    run_until_space(screen)
                    draw_window_question_prompts_and_refresh(
                        screen, answer, player_names, pick_player,
                        QUESTION_EVERYBODY_WRONG)
                # wait for space after showing the answer as is the case
                # in both if and else above
                run_until_space(screen)

            else:
                run_buzzin_attempts(screen, question, answer, question_score,
                                    answered_questions, player_names, scores,
                                    daily_doubles)
            return True

        elif event == ord(" "):
            return False
def run_question(
    screen, category, question, answer, is_dd, question_score,
    selected_question, answered_questions, player_names, scores,
    daily_doubles, answer_server):

    answer_server.current_answer = answer

    if is_dd:
        draw_daily_double_splash(screen, player_names, scores)
        pick_player = pick_dd_player(screen, player_names)
        if pick_player == None:
            return False
        else:
            draw_daily_double_splash(
                screen,
                (player_names[pick_player],),
                (scores[pick_player],) )
            how_much = input_dd_player_wager(
                screen,
                MIN_DAILY_DOUBLE_WAGER,
                max(scores[pick_player], MAX_DAILY_DOUBLE_FOR_NEG) )

    pre_question = ( question if not SHOW_CATEGORY
                     else "%s for %s" % (category,
                                         question_score if not is_dd
                                         else how_much
                                         )
                     )

    draw_window_question_prompts_and_refresh(
        screen, pre_question,
        player_names, NOBODY_BUZZED,
        state=QUESTION_PRE_BUZZ_EXIT)

    while True:
        event = screen.getch()

        if event == ord('s'):
            if is_dd:
                draw_window_question_prompts_and_refresh(
                    screen, question, player_names, pick_player,
                    QUESTION_WAIT_ANSWER)
                correct = run_wait_for_right_wrong(screen)
                scores[pick_player] += (
                    how_much if correct
                    else -how_much )
                if correct:
                    draw_window_question_prompts_and_refresh(
                        screen, answer, player_names, pick_player,
                        QUESTION_ANSWERED_RIGHT)
                else:
                    draw_window_question_prompts_and_refresh(
                        screen, question, player_names, pick_player,
                        QUESTION_EVERYBODY_WRONG)
                    run_until_space(screen)
                    draw_window_question_prompts_and_refresh(
                        screen, answer, player_names, pick_player,
                        QUESTION_EVERYBODY_WRONG)
                # wait for space after showing the answer as is the case
                # in both if and else above
                run_until_space(screen)

            else:
                run_buzzin_attempts(screen, question, answer, question_score,
                                    answered_questions, player_names, scores,
                                    daily_doubles)
            return True

        elif event == ord(" "):
            return False