project - trivia game

S

Shawn Minisall

For my final project, I'm trying to do a GUI based game similar to are
you smarter then a 5th grader. I've been working on it and am stuck
with some code someone helped me with to randomize the A,B,C,D letters
that the correct answer is assigned too. The code that does this is
highlighted in bold and the code that assigns it to a variable is also
in bold so I can test it in the console window. Problem is, it's always
stuck at letter A and doesn't always give the correct answer. The
correct answer is always position 1 in my make math question list.
Could someone please help?

thanks

BTW, to whoever asked me why I don't use functions b4, I'm using them
now that I've learned how to... :p ;)

from graphics import *
from random import *

def drawMainMenu(win):
#define and draw the buttons
mainMenuList = []
mainMenuList.append (CreateRect(4,6,7,8,"grey",win))
mainMenuList.append (CreateRect(3.5,6.5,5,6,"grey",win))
mainMenuList.append (CreateRect(3.5,6.5,3,4,"grey",win))
mainMenuList.append (CreateRect(3.1,7,1,2,"grey",win))
mainMenuList.append (CreateRect(8,10,0,1,"grey",win))

#define and draw the main menu
mainMenuList.append (CreateText(5,9.5,"MAIN MENU","times roman", 30,
"normal", "red",win))
mainMenuList.append (CreateText(2,8.5,"Please pick a subject from
below: ","times roman", 14, "normal", "purple",win))
mainMenuList.append (CreateText(5,7.5,"MATH","times roman", 28,
"italic", "blue",win))
mainMenuList.append (CreateText(5,5.5,"SCIENCE","times roman", 28,
"italic", "yellow",win))
mainMenuList.append (CreateText(5,3.5,"HISTORY","times roman", 28,
"italic", "pink",win))
mainMenuList.append (CreateText(5,1.5,"GEOGRAPHY","times roman", 28,
"italic", "green",win))
mainMenuList.append (CreateText(9,.5,"Quit","times roman", 20,
"italic", "black",win))

return(mainMenuList)

def UndrawMenu (menulist):
for i in range(len(menulist)):
menulist.undraw()


def CreateText(x,y,myString,myFace,mySize, myStyle, myColor,win):
myText = Text(Point(x,y), myString)
myText.setFace(myFace)
myText.setSize(mySize)
myText.setStyle(myStyle)
myText.setTextColor(myColor)
myText.draw(win)
return myText

def CreateRect(x1,x2,y1,y2,myFill,win):
myRect = Rectangle(Point(x1,y1,), Point(x2,y2))
myRect.setFill(myFill)
myRect.draw(win)
return myRect

def isValidClick(x1,x2, y1, y2, p1, win):
if p1.getX()>=x1 and p1.getY()>=y1 and p1.getX()<=x2 and p1.getY()<=y2:
return True
else:
return False

def drawQuestion (subject, question, answers, win):
menuList = []

#define and draw the entry boxes
entchoice = Entry(Point(6.4,6.5), 1)
entchoice.setText("A")
entchoice.setTextColor ("blue")
entchoice.draw(win)

menuList.append(entchoice)
menuList.append(CreateText(5,9.5,question,"times roman", 18,
"normal", "red",win))
menuList.append(CreateText(2,8.5,"A. " + answers[0],"times roman",
16, "normal", "purple",win))
menuList.append(CreateText(7.5,8.5,"B. " + answers[1],"times roman",
16, "normal", "purple",win))
menuList.append(CreateText(2,7.5,"C. " + answers[2],"times roman",
16, "normal", "purple",win))
menuList.append(CreateText(7.5,7.5,"D. " + answers[3],"times roman",
16, "normal", "purple",win))
menuList.append(CreateText(4.7,6.5,"Please enter your
choice:","times roman", 16, "normal", "purple",win))

#draw answer box and text
answerButton = Rectangle(Point(7,5.5), Point(3,4))
answerButton.setFill("grey")
answerButton.draw(win)
answerButton = Text(Point(5,4.8),"Answer")
answerButton.setTextColor("black")
answerButton.setSize(22)
answerButton.draw(win)
menuList.append(answerButton)

return(menuList)


def main():

#Declare and initialize variables



#make math question list
mathlist = []
question = ["An equilateral triangle has how many sides?", "3", "4"
, "1", "5"]
mathlist.append(question)
question = ["How many inches are in a foot?", "12", "6", "3", "9"]
mathlist.append(question)
question = ["One Kilogram equals how many grams?", "1000", "230",
"450", "100"]
mathlist.append(question)
question = ["Which means nine hundred sixty three thousandths?",
".963", ".0963", ".0.0963", "9.63"]
mathlist.append(question)
question = ["A fathom is a unit of measurement for which of the
following?", "depth", "space", "time", "distance"]
mathlist.append(question)
question = ["What is 111, plus 112, plus 113?", "336", "332", "331",
"333"]
mathlist.append(question)

#show the rules of the game window
win = GraphWin("RULES OF THE GAME",600,600)
win.setBackground("orange")
win.setCoords(0.0,0.0,10.0,10.0)

txtrules1 = CreateText(5,9.5,"The rules of the game are as
follows:","times roman", 16, "normal", "red",win)
txtrules2 = CreateText(5,8.5,"The game will be made up of 10
questions, 2 from each grade 1-5.","times roman", 12, "normal", "black",win)
txtrules3 = CreateText(5,7.5,"You will be able to pick 2 subjects
you want to answer for each grade.","times roman", 12, "normal",
"black",win)
txtrules4 = CreateText(5,6.5,"The subjects you can pick from are
Math, Science, History and Geography.","times roman", 12, "normal",
"black",win)
txtrules5 = CreateText(5,5.5,"No more then 3 questions can be
answered from each subject.","times roman", 12, "normal", "black",win)
txtrules6 = CreateText(5,2.5,"HAVE FUN AND GOOD LUCK!","times
roman", 26, "normal", "yellow",win)


#define window and set coords
win =GraphWin("Are You Smarter Then a Fifth Grader???",800,800)
win.setBackground("orange")
win.setCoords(0.0,0.0,10.0,10.0)
mainMenuList = drawMainMenu(win)



#getMouse
p1 = win.getMouse()
while(isValidClick(8,10,0,1,p1,win)==False):
if (isValidClick(4,6,7,8,p1,win)==True):
currentList = mathlist
subject = "Math"

elif (isValidClick(3.5,6.5,5,6,p1,win)==True):
UndrawMenu(mainMenuList)

elif (isValidClick(3.5,6.5,3,4,p1,win)==True):
UndrawMenu(mainMenuList)

elif (isValidClick(3.1,7,1,2,p1,win)==True):
UndrawMenu(mainMenuList)

UndrawMenu(mainMenuList)

* #Picks random question
qNum = randrange(0, len(currentList))
qList = currentList[qNum]

aList = []
tmpList = qList[1:5]

#Randomizes answers
while(len(tmpList) > 0):
rNum = randrange(0, len(tmpList))
aList.append(tmpList[rNum])
tmpList.pop(rNum)*

currentScreen = drawQuestion(subject, qList[0], aList, win)
currentList.pop(qNum)

#getMouse
p1 = win.getMouse()
while(isValidClick(7,3,5.5,4,p1,win)==True):
print "hello"

*
pResult = (currentScreen[0].getText())
print pResult

cResult = (currentScreen[2].getText())
print cResult*

#compare player's answer to correct answer
#if correct/incorrect do a print statement
#add/take away from score

UndrawMenu(currentScreen)


#Quit
win.close()
 
D

Dennis Lee Bieber

For my final project, I'm trying to do a GUI based game similar to are
you smarter then a 5th grader. I've been working on it and am stuck
with some code someone helped me with to randomize the A,B,C,D letters
that the correct answer is assigned too. The code that does this is
highlighted in bold and the code that assigns it to a variable is also
in bold so I can test it in the console window. Problem is, it's always
stuck at letter A and doesn't always give the correct answer. The
correct answer is always position 1 in my make math question list.
Could someone please help?

Not having a copy of your graphics library, I restricted myself to
just the mechanics of randomizing the questions and responses (and since
there is only one "category" at present, I run through it completely --
see below for commentary on multiple categories). Getting the mechanics
working with a text-based prototype probably should have been done first
-- it can often be easier to map a text interface into a GUI than
starting with a GUI with no working behavior...


-=-=-=-=-=- Beware line wrapping
import time
import random

# q -> question;
# c -> choices (a four element list in any order)
# a -> answer (correct answer -- must match the entry in "c"
exactly)
mathlist = [ {"q" : "An equilateral triangle has how many sides?",
"c" : [ "1", "3", "4", "5"],
"a" : "3"},
{"q" : "How many inches are in a foot?",
"c" : [ "3", "6", "9", "12"],
"a" : "12"},
{"q" : "One Kilogram equals how many grams?",
"a" : "1000",
"c" : [ "100", "230", "450", "1000"]},
{"a" : "0.963",
"c" : [ "0.0963", "0.963", "9.63", "963000.0" ],
"q" : "Which means nine hundred sixty three
thousands?"},
{"q" : "A fathom is a unit of measurement for which of
the following?",
"a" : "depth",
"c" : [ "distance", "time", "space", "depth"]},
{"q" : "What is 111, plus 112, plus 113?",
"c" : [ "331", "332", "333", "336"],
"a" : "336"} ]

MAXSCORE = len(mathlist)
score = 0

#shuffle the questions
random.shuffle(mathlist)
for qca in mathlist:
question = qca["q"]
choices = qca["c"]
random.shuffle(choices) #shuffle the choices
answer = qca["a"]

#display question and choice menu
print "\n\n\n\t\tScore: %s correct out of %s" % (score, MAXSCORE)
print "\n\nThe question is:\n\n\t%s\n" % question
# you'd normally assign the four choices as the text labels of the
four
# gui buttons, and wouldn't need a loop for invalid user input --
the
# only valid input IS one of the four buttons.
print "\n\nYour choices are:\n\n\tA: %s\tB: %s\n\tC: %s\tD: %s\n" %
tuple(choices)
while True:
pick = raw_input("\nEnter the letter of your choice: ")
letter = pick.upper()[0] #only want the one CAPITAL letter
if letter in "ABCD": break
print "\n*****\t'%s' is not a valid choice, try again" % letter

#determine if correct result picked
# in a GUI situation, I'd expect the buttons to be filled with the
text
# of the choices, so no trick with indexing into the choices list
is needed.
# just compare the button label text directly against the correct
answer
ix = "ABCD".find(letter)
if choices[ix] == answer:
print "Congratulations, you picked the correct answer"
score += 1
else:
print "Sorry, the correct answer is: %s" % answer
time.sleep(2.5)

print "Your FINAL score was: %s out of %s, or %s%%" % (score, MAXSCORE,
(100.0 * score /
MAXSCORE))
-=-=-=-=-=-=-

Given a system with multiple categories, you probably need to either
add a flag "used" initialized to False, and set it to True if a question
has been shown, then when the category is chosen again, loop until the
selected question was "not used" (you'd use random.choice() to get a
candidate)

while True
qca = random.choice(category_list)
if not qca["used"]: break

OR you initialize each category list using random.shuffle, as above code
does, then when the category is picked you retrieve the last item from
the list and remove it from the list.

#initialization
random.shuffle(cat1_list)
random.shuffle(cat2_list)
....etc.

#during game
if len(category_list): #still has questions
qca = category_list.pop()
else:
# the category is empty

--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
D

Dennis Lee Bieber

Talking to myself, it would seem <G>

I went into a bought of OO'ing today and came up with this -- still
text based...

-=-=-=-=-=-=-=-
import random
import time

# define classes for "QCA" (Question, Choices, Answer);
# question Category; and overall Game data control
class QCA(object):
def __init__(self, question, choices, answer):
"""
choices is a string with each choice separated by a tilde ~
character
answer is a string that must be in choices after splitting on ~
"""
self.question = question
self.answer = answer
self.choices = choices.split("~")
random.shuffle(self.choices)
def reset(self):
random.shuffle(self.choices)
def check(self, answer):
return self.answer == answer

class Category(object):
def __init__(self, name):
self.name = name
self.available = []
self.used = []
def reset(self):
self.available.extend(self.used)
self.used = []
for qca in self.available:
qca.reset()
random.shuffle(self.available)
def isActive(self):
return len(self.available)
def addQuestion(self, qca):
self.available.append(qca)
def getQuestion(self):
qca = self.available.pop()
self.used.append(qca)
return qca

class Game(object):
def __init__(self):
self.categories = []
self.reset()
def reset(self):
self.answered = 0
self.tried = 0
self.activeQuestion = None
def addCategory(self, category):
self.categories.append(category)
def getCategories(self):
return [(c.name, c.isActive()) for c in self.categories]
def getQuestion(self, catName):
for c in self.categories:
if c.name == catName:
self.activeQuestion = c.getQuestion()
return self.activeQuestion
def updateScore(self, answer):
self.tried += 1
if self.activeQuestion.check(answer):
self.answered += 1
return True
return False
def getScore(self):
return (self.answered, self.tried)
#
# populate the game data
game = Game()
qpool = Category("Mathematics")
qpool.addQuestion(QCA("An equilateral triangle has how many sides?",
"1~3~4~5",
"3"))
qpool.addQuestion(QCA("How many inches are in a foot?",
"3~6~9~12",
"12"))
qpool.addQuestion(QCA("One Kilogram equals how many grams?",
"100~250~1000~2000",
"1000"))
qpool.addQuestion(QCA("Which means nine hundred sixty three thousands?",
"0.0963~0.963~9,630.0~963,000.0",
"0.963"))
qpool.addQuestion(QCA("A fathom is a unit of measurement for which of
the following?",
"distance~time~space~depth",
"depth"))
qpool.addQuestion(QCA("What is 111, plus 112, plus 113?",
"331~332~334~336",
"336"))
game.addCategory(qpool)

#repeat from qpool = Category(???) for each final category

# now that the game data is populated, add the display/control
functionality
def displayScore(correct, total):
print "\n\n\n\tYour Score: %s out of %s (%s%%)" % (correct,
total,
(100.0 * correct
/ total))

def handleQuestion(qca):
print "\n\n\nThe question is:\n\n\t%s" % qca.question
print "\n"
for i, choice in enumerate(qca.choices):
print "\t%s\t%s" % (i+1, choice)
print
while True:
itm = int(raw_input("Enter your choice (1..%s): " %
len(qca.choices)))
if 0 < itm < len(qca.choices) + 1:
return qca.choices[itm - 1]
else:
print "*****\t%s is not a valid choice, try again" % itm

def selectCategory(categories):
"""
categories is a list of (name, boolean) tuples; if the boolean is
false,
this category has no more questions available and should not be
enabled
(in a GUI static button layout, disable the button; in text, remove
it from
the menu of choices presented to the player)
"""
print "\n\n\nSelect from the following categories\n\n"
select = []
selected = None
for i, (name, active) in enumerate(categories):
if active:
print "\t%s\t%s" % (i+1, name)
select.append(name)
if select:
print
while True:
itm = int(raw_input("Enter your choice (1..%s): " %
len(select)))
if 0 < itm <= len(select):
selected = select[itm - 1]
break
else:
print "*****\t%s is not a valid choice, try again" % itm
else:
print "\n\tAll questions have been attempted -- game is over"
return selected

def playGame(g):
g.reset() #ensure game data has been reset
while True:
category = selectCategory(g.getCategories())
if not category: break #no categories left to select from
qca = g.getQuestion(category)
answer = handleQuestion(qca)
result = g.updateScore(answer)
if result:
print "That is CORRECT!"
else:
print "I'm sorry, that is incorrect."
print "\tThe correct answer was: %s" % qca.answer
displayScore(*g.getScore())
time.sleep(2.5)

if __name__ == "__main__":
playGame(game)
-=-=-=-=-=-=-=-
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top