-1
import csv
import random
from datetime import date
import pygame
from pygame.locals import *
import sys

mainClock = pygame.time.Clock()
pygame.init()
pygame.display.set_caption('Game')
screen = pygame.display.set_mode((900, 600), 0, 32)
# noinspection PyTypeChecker
answer_font = pygame.font.SysFont(None, 50)
# noinspection PyTypeChecker
question_font = pygame.font.SysFont(None, 30)


class QuestionAnswerControls:
    def __init__(self):
        self.score = 0
        self.questions = []
        self.answers = []
        self.correctAnswers = []

    def get_question_answer(self):

        questions_and_answers = []

        with open('questions.txt', newline='') as f:
            reader = csv.reader(f, delimiter='\t')
            for row in reader:
                questions_and_answers.append(row)

        random.shuffle(questions_and_answers)
        for q in questions_and_answers:
            self.questions.append(q[0])
            self.correctAnswers.append(q[1])
            del q[0]
            random.shuffle(q)
            self.answers.append(q)

    def get_number_of_questions(self):
        noq = int(len(self.questions))
        return noq

    def get_question(self, question_number):
        question = self.questions[question_number]
        return question

    def get_answers(self, answer_set_number):
        answer_set = self.answers[answer_set_number]
        return answer_set

    def get_correct_answer(self, correct_answer_number):
        correct_answer = self.correctAnswers[correct_answer_number]
        return correct_answer

    def increase_score(self):
        self.score += 1

    def export_scores(self):
        with open('scores.txt', mode='a') as scores:
            scores = csv.writer(scores, delimiter='\t')

            today = date.today()
            date_format = today.strftime("%d/%m/%Y")

            scores.writerow([date_format, self.score])


def draw_text(text, font, colour, surface, x, y):
    textobj = font.render(text, 1, colour)
    textrect = textobj.get_rect()
    textrect.topleft = (x, y)
    surface.blit(textobj, textrect)


click = False


def question_answer_gui():
    global click
    game_menu = True
    while game_menu:

        screen.fill((0, 0, 0))
        mx, my = pygame.mouse.get_pos()

        question_rect = pygame.Rect(100, 100, 700, 100)
        button_answer_one = pygame.Rect(100, 250, 325, 100)
        button_answer_two = pygame.Rect(475, 250, 325, 100)
        button_answer_three = pygame.Rect(100, 400, 325, 100)
        button_answer_four = pygame.Rect(475, 400, 325, 100)

        click = False
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            if event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    click = True

        for c in range(0, questionAnswerGame.get_number_of_questions()):
            screen.fill((0, 0, 0))
            question_answered = False
            question = questionAnswerGame.get_question(c)
            correct_answer = questionAnswerGame.get_correct_answer(c)
            answers = questionAnswerGame.get_answers(c)
            answer_chosen = ""

            print(question, answers, correct_answer)

            pygame.draw.rect(screen, (255, 0, 0), question_rect)
            draw_text(str(question), question_font, (255, 255, 255), screen, 200, 135)
            pygame.draw.rect(screen, (255, 0, 0), button_answer_one)
            draw_text(str(answers[0]), answer_font, (255, 255, 255), screen, 175, 285)
            pygame.draw.rect(screen, (255, 0, 0), button_answer_two)
            draw_text(str(answers[1]), answer_font, (255, 255, 255), screen, 525, 285)
            pygame.draw.rect(screen, (255, 0, 0), button_answer_three)
            draw_text(str(answers[2]), answer_font, (255, 255, 255), screen, 175, 435)
            pygame.draw.rect(screen, (255, 0, 0), button_answer_four)
            draw_text(str(answers[3]), answer_font, (255, 255, 255), screen, 525, 435)

            if button_answer_one.collidepoint((mx, my)):
                if click:
                    answer_chosen = answers[0]
                    question_answered = True
            if button_answer_two.collidepoint((mx, my)):
                if click:
                    answer_chosen = answers[1]
                    question_answered = True
            if button_answer_three.collidepoint((mx, my)):
                if click:
                    answer_chosen = answers[2]
                    question_answered = True
            if button_answer_four.collidepoint((mx, my)):
                if click:
                    answer_chosen = answers[3]
                    question_answered = True

            click = False

            print(answer_chosen)

            if answer_chosen == correct_answer:
                questionAnswerGame.increase_score()
                print("Correct")

            if question_answered:
                pygame.display.update()
                mainClock.tick(60)

        pygame.display.update()
        mainClock.tick(60)


questionAnswerGame = QuestionAnswerControls()
questionAnswerGame.get_question_answer()
question_answer_gui()

The print statements within the for c in range loop are only for testing purposes, they should not be there in the final product.

This is part of a game I am making for an A-Level Programming Project and this is just one module of it.

My issue is that the for c in range loop will loop through the entire for statement without waiting for the user to select an answer. The print(question, answers, correct_answer) statement proves this. Additionally, this for loop seems to be functioning as somewhat of a while loop. It will continually print out all the questions in order over and over again while the program is just sat there running.

What should happen is that the game displays the question and answers, the user selects an answer, their score is incremented, then the user is shown the next question, the user selects the answer etc. The program currently renders the first question correctly, the user will select an answer and then rather than going to the next question the program quickly loops through all questions and then straight back to the first question.

Please help. I need the for c in range statement to wait until the user has selected an answer to then ask the next question.

I have tried using the if statement at the end to only update the display after an answer has been chosen but that only affects rendering not the actual for loop.

Attached are some screenshots to help demonstrate the issue.

What the game looks like

What the console shows from the print statement used for debugging

George G
  • 43
  • 4
  • your only loop should be `while game_menu:` And you should have only one `screen.fill((0, 0, 0))`, only one `pygame.display.update()` and only one `mainClock.tick(60)`. And your `for`-loop should be rebuild to use only `while game_menu:` – furas Jan 03 '21 at 16:28
  • Can you elaborate on this please? I understand the part about how there should only be one screen.fill and one display.update but if I don't use the for loop then how would I set it up to fetch the questions etc and only display one at once? – George G Jan 03 '21 at 16:29
  • before `while True` set `current_question = 0` and inside `while True` use this value to diplay this single question. When user answer question then increase it `current_question += 1` to display next question in next loops. – furas Jan 03 '21 at 16:44
  • 1
    it is how I see it (but I didn't test it): https://pastebin.com/WJp2Zv2b – furas Jan 03 '21 at 17:16
  • Thank you this is really helpful, between your two last comments I did manage to create my solution, I understood what you were saying and suddenly had a thought during eating my dinner and then lone behold it worked. Your code definitely looks more elegant so I think I use a mixture of the two. Most apprecriated. – George G Jan 03 '21 at 17:55

0 Answers0