|
It is currently Wed Nov 27, 2024 1:21 pm
|
|
Page 1 of 1
|
[ 3 posts ] |
|
Author |
Message |
Peanut-Lover
Site Administrator
Joined: Wed Jul 05, 2006 10:32 am Posts: 1917 Location: Brooklyn, NY
|
YAY, so last night, I finished a course on basic python programming. it was a go-at-your-own-pace kind of course. Finished a month early (2nd in the class) - had I not slacked off because of senioritis, I might have finished before April even started. So, what's the point? I have a problem with exactly *HOW* I passed that programming exam. I got the exact question that had been at the end of the lesson - standard for the course. Like always, however, I ignored all of the questions at the end of the chapter, and just tried to finish it. I got my program to work. but I don't like how they solved it. I have the question, the original code, my answer, and their answer. My questions include: 1.) Did I screw up 2.) Is mine more correct 3.) What is the fundamental difference between what I did and what they did. So, anyone with Python experience, it would be nice if you can help. If there is anyone who wants me to, I can upload all of my files, including lessons and exams. Question: Code is provided for the original Blocker game program developed in Unit 11. Modify the program so that the goal moves horizontally, one pixel per animation step, bouncing when it hits either side of the playing field. Beginning Code: Code: from tkinter import * from random import choice from time import clock
# sx and sy are the horizontal and vertical speed of the ball # in pixels per animation step block, ball, sx, sy = None, None, 5, 5
# returns position of the *center* of the ball def ballPosition(): x1, y1, x2, y2 = list(field.coords(ball)) return [(x1+x2)/2, (y1+y2)/2]
def startGame(): global startTime, ball, block # remember to delete block and ball from previous game if block: field.delete(block) block = None if ball: field.delete(ball) # place ball at random upperLeftX = choice(list(range(290))) upperLeftY = choice(list(range(290))) ball = field.create_oval(upperLeftX, upperLeftY, upperLeftX+10, upperLeftY+10, fill='blue') startTime = clock() animate()
def animate(): global sx, sy pattern = 'Elapsed time: {0:.1f} seconds' timeDisplay['text'] = pattern.format(clock()-startTime) x, y = ballPosition() hitVertical = hitBlock() and blockType == 'vertical' if x+sx>300 or x+sx<0 or hitVertical: sx *= -1 hitHorizontal = hitBlock() and blockType == 'horizontal' if y+sy>300 or y+sy<0 or hitHorizontal: sy *= -1 field.move(ball, sx, sy) if not inGoal(): root.after(20, animate) # Only one block at a time; delete one before creating the next
def leftClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x-20, event.y, event.x+20, event.y+6, fill='light green') blockType = 'horizontal'
def rightClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x, event.y-20, event.x+6, event.y+20, fill='light green') blockType = 'vertical'
# return True if the center of the ball is inside the # block’s boundary def hitBlock(): if not block: return False ballX, ballY = ballPosition() blockX1, blockY1, blockX2, blockY2 = field.coords(block) return (blockX1 <= ballX <= blockX2 and blockY1 <= ballY <= blockY2)
# return True if the center of the ball is inside the # goal area def inGoal(): ballX, ballY = ballPosition() return 0 <= ballX <= 25 and 275 <= ballY <= 300 root = Tk()
timeDisplay = Label(root) timeDisplay.pack()
field = Canvas(root, width=300, height=300, bg='light blue') field.pack()
startButton = Button(root, command=startGame, text='Go') startButton.pack()
# the goal field.create_rectangle(0, 275, 25, 300, fill='red')
field.bind('<ButtonPress-1>', leftClick) field.bind('<ButtonPress-3>', rightClick)
mainloop() My answer: Code: from tkinter import * from random import choice from time import clock
# sx and sy are the horizontal and vertical speed of the ball # in pixels per animation step block, ball, goal, sx, sy, gX, gY = None, None, None, 5, 5, 1, 0
# returns position of the *center* of the ball def ballPosition(): x1, y1, x2, y2 = list(field.coords(ball)) return [(x1+x2)/2, (y1+y2)/2]
def goalPosition(): x1, y1, x2, y2 = list(field.coords(goal)) return [(x1+x2)/2, (y1+y2)/2] def startGame(): global startTime, ball, block, goal # remember to delete block and ball from previous game if block: field.delete(block) block = None if ball: field.delete(ball) if goal: field.delete(goal) # place goal at coordinates goalX = choice (list(range(275))) goalY = 288 goal = field.create_rectangle(goalX-12, goalY-12, goalX+12, goalY+12, fill='red') # place ball at random upperLeftX = choice(list(range(290))) upperLeftY = choice(list(range(290))) ball = field.create_oval(upperLeftX, upperLeftY, upperLeftX+10, upperLeftY+10, fill='blue') startTime = clock() animate()
def animate(): global sx, sy, gX, gY pattern = 'Elapsed time: {0:.1f} seconds' timeDisplay['text'] = pattern.format(clock()-startTime) # Defining Goal movement goalX, goalY = goalPosition() if goalX+gX>287 or goalX+gX<13: gX *= -1 goalY = 275 if goalY+gY>288 or goalY+gY<288: goalY == 288 field.move(goal, gX, gY) # Defining Ball movement x, y = ballPosition() hitVertical = hitBlock() and blockType == 'vertical' if x+sx>300 or x+sx<0 or hitVertical: sx *= -1 hitHorizontal = hitBlock() and blockType == 'horizontal' if y+sy>300 or y+sy<0 or hitHorizontal: sy *= -1 field.move(ball, sx, sy) if not inGoal(): root.after(20, animate)
# Only one block at a time; delete one before creating the next
def leftClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x-20, event.y, event.x+20, event.y+6, fill='light green') blockType = 'horizontal'
def rightClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x, event.y-20, event.x+6, event.y+20, fill='light green') blockType = 'vertical'
# return True if the center of the ball is inside the # block’s boundary def hitBlock(): if not block: return False ballX, ballY = ballPosition() blockX1, blockY1, blockX2, blockY2 = field.coords(block) return (blockX1 <= ballX <= blockX2 and blockY1 <= ballY <= blockY2)
# return True if the center of the ball is inside the # goal area def inGoal(): ballX, ballY = ballPosition() goalX, goalY = goalPosition() return goalX-12 <= ballX <= goalX+12 and goalY-12 <= ballY <= goalY+12 root = Tk()
timeDisplay = Label(root) timeDisplay.pack()
field = Canvas(root, width=300, height=300, bg='light blue') field.pack()
startButton = Button(root, command=startGame, text='Go') startButton.pack()
field.bind('<ButtonPress-1>', leftClick) field.bind('<ButtonPress-3>', rightClick)
mainloop() Thier answer: Code: from tkinter import * from random import choice from time import clock
# sx and sy are the horizontal and vertical speed of the ball # in pixels per animation step block, ball, sx, sy, goalSpeed = None, None, 5, 5, 1
fieldSize, goalSize, ballSize = 300, 25, 10
# returns position of the *center* of the ball def ballPosition(): x1, y1, x2, y2 = list(field.coords(ball)) return [(x1+x2)/2, (y1+y2)/2]
def startGame(): global startTime, ball, block # remember to delete block and ball from previous game if block: field.delete(block) block = None if ball: field.delete(ball) # place ball at random upperLeftX = choice(list(range(290))) upperLeftY = choice(list(range(290))) ball = field.create_oval(upperLeftX, upperLeftY, upperLeftX+10, upperLeftY+10, fill='blue') startTime = clock() animate()
def goalLeftX(): return list(field.coords(goal))[0]
def animate(): global sx, sy, goalSpeed pattern = 'Elapsed time: {0:.1f} seconds' timeDisplay['text'] = pattern.format(clock()-startTime) x, y = ballPosition() hitVertical = hitBlock() and blockType == 'vertical' if x+sx>300 or x+sx<0 or hitVertical: sx *= -1 hitHorizontal = hitBlock() and blockType == 'horizontal' if y+sy>300 or y+sy<0 or hitHorizontal: sy *= -1 if goalLeftX()+goalSpeed<0 or goalLeftX()+goalSize+goalSpeed>fieldSize: goalSpeed *= -1 field.move(ball, sx, sy) field.move(goal, goalSpeed, 0) if not inGoal(): root.after(20, animate) # Only one block at a time; delete one before creating the next
def leftClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x-20, event.y, event.x+20, event.y+6, fill='light green') blockType = 'horizontal'
def rightClick(event): global block, blockType if block: field.delete(block) block = field.create_rectangle(event.x, event.y-20, event.x+6, event.y+20, fill='light green') blockType = 'vertical'
# return True if the center of the ball is inside the # block’s boundary def hitBlock(): if not block: return False ballX, ballY = ballPosition() blockX1, blockY1, blockX2, blockY2 = field.coords(block) return (blockX1 <= ballX <= blockX2 and blockY1 <= ballY <= blockY2)
# return True if the center of the ball is inside the # goal area def inGoal(): ballX, ballY = ballPosition() return goalLeftX() <= ballX <= goalLeftX()+goalSize and fieldSize-goalSize <= ballY <= fieldSize root = Tk()
timeDisplay = Label(root) timeDisplay.pack()
field = Canvas(root, width=fieldSize, height=fieldSize, bg='light blue') field.pack()
startButton = Button(root, command=startGame, text='Go') startButton.pack()
# the goal goal = field.create_rectangle(0, fieldSize-goalSize, goalSize, fieldSize, fill='red')
field.bind('<ButtonPress-1>', leftClick) field.bind('<ButtonPress-3>', rightClick)
mainloop() Help?
|
Fri Apr 20, 2012 2:19 pm |
|
|
WirelessBrain
Pokemon Ranger
Joined: Thu Oct 01, 2009 6:05 am Posts: 614 Location: Coming soon to a store near you!
|
Okay, first of all, i'm not going to admit expertise in Visual Python, but i know a little. I'm much better at other windows programming (C# and VB.NET).
After looking at all your code and running it, now i'll answer your questions before my own comments:
1.) Did I screw up ~ No, it does as it's supposed to and how it asks in the question. And exactly the same as their answer. 2.) Is mine more correct ~ With programming, there's no set way to do things. I'm sure you know this. The main functions behind programs are that it does as it is meant to, by any means possible, and then efficiency of the program. Look below for the proper answer to this. 3.) What is the fundamental difference between what I did and what they did. ~ As far as i can gather, the main difference isn't huge. But they used a different way of 'grabbing' the coordinates of the goal. And also, you took the y coordinates as well, which if i understand correctly, arent needed?
So technically yours is a tiny bit less efficient. But still does what it's supposed to just in a slightly different way. As i said, Python really isn't m strong point but it was fun to look at. Hope this helped. If you want to compare better, cut out duplicated bits of code between yorus and their answer.That's what i did and the differences are easily compared.
Regards
_________________ [img]http://i.imgur.com/VFUEj21.png[/img]
|
Wed Apr 25, 2012 3:56 am |
|
|
Peanut-Lover
Site Administrator
Joined: Wed Jul 05, 2006 10:32 am Posts: 1917 Location: Brooklyn, NY
|
Heh, I found out yesterday. The guy that wrote the program, was using (in his "solution") the modified form of the program, from a previous question in their solved problems (making number modifications easier). No there were other problems, which I'm bringing up when I see the guy who wrote this. We never learned the job function, so if you restart without winning, the speed is cumulative, as is the number of animation steps that the goal needs to be in the goal. Here is a heavily modified form of the program for those who look in and want to play the game. Python 3.2 is online, and this has no modules other than those native to Python (no need for extra code beyond this). Code: from tkinter import * from random import choice from time import clock
# allow the user to make the game as fast as they like, and as big as they like (minimum size 100). ballSpeed = int(input('How fast for the ball? ')) goalSpeed = int(input('How fast for the goal? ')) fieldSize = int(input('How large do you want the field to be (minimum 100)? ')) job = None while fieldSize < 100: fieldSize = int(input('How large do you want the field to be (minimum 100)? '))
# sx and sy are the horizontal and vertical speed of the ball # in pixels per animation step. gX will stand for the goal block, ball, goal, sx, sy, gX, blockSize = None, None, None, ballSpeed, ballSpeed, goalSpeed, fieldSize/20
# returns position of the *center* of the ball and goal def ballPosition(): x1, y1, x2, y2 = list(field.coords(ball)) return [(x1+x2)/2, (y1+y2)/2]
def goalPosition(): x1, y1, x2, y2 = list(field.coords(goal)) return [(x1+x2)/2, (y1+y2)/2] def startGame(): global startTime, ball, block, goal, job print('NEW GAME') # remember to delete block and ball from previous game if block: field.delete(block) block = None if ball: if job is not None: root.after_cancel(job) field.delete(ball) if goal: field.delete(goal) # place goal at random X. This must be done BEFORE coding the ball's position, or the goal will cover the ball. goalX = choice(list(range(fieldSize-25))) print('Initial goalX = ', goalX) if goalX<13: goalX = 13 if goalX>fieldSize-12: goalX = fieldSize-12 goalY = fieldSize-12 goal = field.create_rectangle(goalX-12, goalY-12, goalX+12, goalY+12, fill='red') print('coordinates(goal)', (field.coords(goal))) # place ball at random ballX = choice(list(range(fieldSize-10))) ballY = choice(list(range(fieldSize-10))) ball = field.create_oval(ballX-5, ballY-5, ballX+5, ballY+5, fill='blue') print('coordinates(ball)', ballX, ballY) # to prevent the ball from starting and the game already been won if inGoal(): print('FLUKE') startGame() startTime = clock() animate()
def animate(): global sx, sy, gX, job pattern = 'Elapsed time: {0:.1f} seconds' timeDisplay['text'] = pattern.format(clock()-startTime) # Defining Goal movement. This must be done BEFORE coding the ball's movement, or the goal will cover the ball. goalX, goalY = goalPosition() # If the goal's next move puts it to the right of 288, or left of 13 if goalX+gX>fieldSize-12 or goalX+gX<13: gX *= -1 field.move(goal, gX, 0) # Defining Ball movement x, y = ballPosition() hitVertical = hitBlock() and blockType == 'vertical' if x+sx>fieldSize-5 or x+sx<5 or hitVertical: sx *= -1 hitHorizontal = hitBlock() and blockType == 'horizontal' if y+sy>fieldSize-5 or y+sy<5 or hitHorizontal: sy *= -1 field.move(ball, sx, sy) if inGoal(): print('game over', ballPosition(), field.coords(goal)) job = None else: job = root.after(20, animate)
# Only one block at a time; delete one before creating the next
def leftClick(event): global block, blockType, blockSize if block: field.delete(block) block = field.create_rectangle(event.x-blockSize, event.y-3, event.x+blockSize, event.y+3, fill='light green') blockType = 'horizontal'
def rightClick(event): global block, blockType, blockSize if block: field.delete(block) block = field.create_rectangle(event.x-3, event.y-blockSize, event.x+3, event.y+blockSize, fill='light green') blockType = 'vertical'
# return True if the center of the ball is inside the # block’s boundary def hitBlock(): if not block: return False ballX, ballY = ballPosition() blockX1, blockY1, blockX2, blockY2 = field.coords(block) return (blockX1 <= ballX <= blockX2 and blockY1 <= ballY <= blockY2)
# return True if the center of the ball is inside the # goal area def inGoal(): ballX, ballY = ballPosition() goalX, goalY = goalPosition() return goalX-12 <= ballX <= goalX+12 and fieldSize-25 <= ballY <= fieldSize root = Tk()
timeDisplay = Label(root) timeDisplay.pack()
field = Canvas(root, width=fieldSize, height=fieldSize, bg='light blue') field.pack()
startButton = Button(root, command=startGame, text='Go') startButton.pack()
field.bind('<ButtonPress-1>', leftClick) field.bind('<ButtonPress-3>', rightClick)
mainloop()
More modifications to come
|
Wed Apr 25, 2012 6:10 am |
|
|
|
|
Page 1 of 1
|
[ 3 posts ] |
|
Who is online |
Users browsing this forum: No registered users and 18 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|