Having score display on canvas and remove repeated "Correct statements"

I am trying to have a score display on the canvas and it go up when an answer is correct but it only stays on 10. It also repeats “Correct” every few questions rather than move straight onto the next question. Any help appreciated. Code below:

I believe it is in the if statements at the bottom of the code.

import pygame, random, sys
from pygame.locals import *
import shelve
pygame.init()

N1 = 0
N2 = 0
playeranswer = 0
answer = 0
Question = 0

topscore = 0

WINDOWWIDTH = 1152
WINDOWHEIGHT = 648
TEXTCOLOR = (30, 0, 40)
BACKGROUNDCOLOR = (255, 255, 255)
FPS = 60
BALLSIZE = 10

#screen = pygame.display.set_mode((600, 600))

def terminate():
pygame.quit()
sys.exit()

def waitForPlayerToPressKey():
while True:
for event in pygame.event.get():
if event.type == QUIT:
terminate()
if event.type == KEYDOWN:
if event.key == K_ESCAPE: # Pressing ESC quits.
terminate()
return

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

#Set up pygame, the window, and the mouse cursor.
pygame.init()
mainClock = pygame.time.Clock()
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption(‘Soccer’)
pygame.mouse.set_visible(False)

Set up the fonts.

font = pygame.font.SysFont(None, 48)

#Set up sounds.

pygame.mixer.music.load(‘Gods Plan.wav’)

Set up images.

BallImage = pygame.image.load(‘ball.png’)
BallX = 370
BallY = 480
BallX_change = 0
BallRect = BallImage.get_rect()
Backpic = pygame.image.load(‘Field.png’)
Ball = BallImage

#Show the “Start” screen.
windowSurface.blit(Backpic,(0, 0))
drawText(‘Press ESC to exit’, font, windowSurface, (WINDOWWIDTH / 3) - 350, (WINDOWHEIGHT / 3) - 195)
drawText(‘Soccer’, font, windowSurface, (WINDOWWIDTH / 3) + 135, (WINDOWHEIGHT / 3))
drawText(‘Press a key to start.’, font, windowSurface, (WINDOWWIDTH / 3) + 40, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()

while True:
score = 0
windowSurface.blit(Backpic,(0, 0))
pygame.mixer.music.play (-1,0.0)

while True:
        N1 = random.randint(1, 10)
        N2 = random.randint(1, 10)
        score = score + 10
      
    
#Question number will decide what queation will be used in the equation
        Question = random.randint(1, 3)

        if int(Question) == 1:
            answer = int(N1) + int(N2)
            playeranswer = input("Whats the answer to " + str(N1) + " + " + str(N2) + " = ")

#and statement makes sure num1 is larger than num2 so there is no negative number answers
        elif int(Question) == 2 and int(N1) > int(N2):
             answer = int(N1) - int(N2)
             playeranswer = input("Whats the answer to " + str(N1) + " - " + str(N2) + " = ")
    
        elif int(Question) == 3:
            answer = int(N1) * int(N2)
            playeranswer = input("Whats the answer to " + str(N1) + " x " + str(N2) + " = ")


       # pygame.display.update()
       

        if int(answer) == int(playeranswer):
             print("Correct! Your score is " + str(score))
                drawText('Score: %s' % (score), font, windowSurface, 10, 0)
        elif int(answer) != int(playeranswer):
            print("The answer is incorrect. Game over! Your score was " + str(score))
            terminate()


        pygame.display.update()
       # drawText('Score: %s' % (score), font, windowSurface, 10, 0)

pygame.mixer.music.stop()

drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))
drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50)
pygame.display.update()
waitForPlayerToPressKey()

Is that line supposed to be commented out?

The other thing I would do, is…

while True:
    N1 = random.randint(1, 10)
    N2 = random.randint(1, 10)
    score = score + 10 # remove this line

and put the increment here:

if int(answer) == int(playeranswer):
        score += 10

Hi Rob

I commented it out as it was continuing to muck up the code.

Do you have any suggestions of what I am missing here?

Thanks

Michelle

By Michelle via Discussions on Python.org at 05May2022 12:23:

I am trying to have a score display on the canvas and it go up when an
answer is correct but it only stays on 10.

That would imply either that the score itself is not chaanging, or that
the window displaying the scroe is never updated after it is changed.
Try putting:

print("SCORE =", score)

at strategic points in your code, such as at the start of the loop, at
the end, when it is changed, and in each ifstatement branch.

It also repeats “Correct” every few questions rather than move straight
onto the next question.

That will be because of the if-statement which prints the question. The
implication is that sometimes it never prints the question.

Let’s look:

while True:
N1 = random.randint(1, 10)
N2 = random.randint(1, 10)
score = score + 10

So the score goes up unconditionally every pass through this loop. Would
it not be more normal to only increase the score for a correct answer?

      #Question number will decide what queation will be used in the equation
       Question = random.randint(1, 3)
       if int(Question) == 1:

You don’t need int(Question) here. Question is already an int`. So
you can just go:

if Question == 1:
           answer = int(N1) + int(N2)
           playeranswer = input("Whats the answer to " + str(N1) + " + " + str(N2) + " = ")

With modern Python you can use a format string, like this:

playeranswer = input(f"Whats the answer to {N1} + {N2} = ")

There’s nothing wrong with what you had, this is just easier to read.

      #and statement makes sure num1 is larger than num2 so there is no negative number answers
       elif int(Question) == 2 and int(N1) > int(N2):
            answer = int(N1) - int(N2)
            playeranswer = input("Whats the answer to " + str(N1) + " - " + str(N2) + " = ")
       elif int(Question) == 3:
           answer = int(N1) * int(N2)
           playeranswer = input("Whats the answer to " + str(N1) + " x " + str(N2) + " = ")

This is probably where your duplicate “Correct” comes from. What happens
when N1<=N2? To my eye it will not take this branch and therefore not
compute the new answer and not ask the user for playeranswer.

I’d probably write this entire if-statement like this:

if Question == 1:
    ... for question 1 ...
elif Question == 2:
    ... for question 2 ...
elif Question == 3:
    ... for question 3 ...
else:
    raise RuntimeError("this should never happen")

When your code’s correct, the RuntimeError will never fire, but if you
make mistakes it will be very obvious. So the pattern here is: enumerate
every choice, and have a catch-all at the end to catch anything we
failed to enumerate.

Since your if-statement makes it possible to have Question==2 but to
not use that branch because N1<=N2, it would fall through to the
RuntimeError and explode, which at least is very obvious.

By making each condition simple, you always take the “2” branch for
Question==2. The it just remains to decide what to do. if you do not
want negative number you’ve got 2 choices: you could reject this random
choice and do another loop:

if N1<=N2:
    print(f"whoops! N1:{N1} <= N2:{N2}, trying again!")
    continue

or just swap them:

if N1<=N2:
    N1, N2 = N2, N1

and keep going. Pick one, or invent a third method.

      # pygame.display.update()
       if int(answer) == int(playeranswer):

Again, you don’t need int(answer) because answer is already an
int. You do need int(playeranswer) because the return value from
input() is a string, the text the user typed.

            print("Correct! Your score is " + str(score))
               drawText('Score: %s' % (score), font, windowSurface, 10, 0)
       elif int(answer) != int(playeranswer):

You don’t need an elif here: you know that int(answer) != int(playeranswer) because the if-part failed. You can just say
else:.

Cheers,
Cameron Simpson cs@cskk.id.au

I’d follow what Cameron has suggested here.

I’ve hacked your code down to the basics and the issue seems to be that when you get two questions that produce the same answer, the logic fails to recognize that it’s a different question, and skips right over it, hence:

If you want me to post up the hacked code, just ask, and I’ll do that, no worries.

Hi Rob,

That would be excellent. It has been really frustrating me the last few days.

Thanks heaps
Michelle

Here you go:

import random

N1 = 0
N2 = 0
playeranswer = 0
answer = 0
Question = 0

topscore = 0

score = 0

while True:
    N1 = random.randint(1, 10)
    N2 = random.randint(1, 10)
    #score = score + 10 <-- this has been movered to line 43


#Question number will decide what queation will be used in the equation
    
    Question = random.randint(1, 3)

    if int(Question) == 1:
        print("Question: ",Question)
        answer = int(N1) + int(N2)
        playeranswer = input("Whats the answer to " + str(N1) + " + " + str(N2) + " = ")

#and statement makes sure num1 is larger than num2 so there is no negative number answers
    elif int(Question) == 2 and int(N1) > int(N2):
        print("Question: ",Question)
        answer = int(N1) - int(N2)
        playeranswer = input("Whats the answer to " + str(N1) + " - " + str(N2) + " = ")

    elif int(Question) == 3:
        print("Question: ",Question)
        answer = int(N1) * int(N2)
        playeranswer = input("Whats the answer to " + str(N1) + " x " + str(N2) + " = ")


    if int(answer) == int(playeranswer):
        score += 10
        print("Correct! Your score is " + str(score))
        print('Score: %s' % (score))
    elif int(answer) != int(playeranswer):
        print("The answer is incorrect. Game over! Your score was " + str(score))
        
        print('\n','\n','\n')
       
        print('end') # break point here

You can see this better, if you pop this in just before the break point

print('Answer: ',int(answer))

Thanks for your help Rob. This definitely works better but still seems to multiply the correct statements on occasion.

Question: 1
Whats the answer to 9 + 10 = 19
Correct! Your score is 50
Score: 50
Correct! Your score is 60
Score: 60
Question: 2
Whats the answer to 10 - 1 =

You’re welcome.

Coding a GUI app is not too different from coding a shell app: nail the logic first.

Once that’s running sweet, it becomes pretty much a function that you can call when you build the GUI version. The GUI adds the ‘whistles & bells’, so to speak.