Python basic pong game, '>' not supported between instances of 'method' and 'int' - pong

I just started python a few days ago as my first programming language, so the problem I bumped into probably isn't a big deal. I'm sorry if it's a simple syntax error. I am building a basic pong game using the turtle module and bumped into a problem making the ball bump off the paddle. When the ball's ycor goes between the paddle's ycor I expect the ball to bump off, but the ball seems to stick to the paddle, and I receive a message saying
Traceback (most recent call last):
File "C:\Users\USER-PC\Desktop\Python\Pong game practice.py", line 92, in
if ball.xcor() > 330 and (ball.ycor() < paddle_b.ycor() + 50 and ball.ycor > paddle_b.ycor() - 50):
TypeError: '>' not supported between instances of 'method' and 'int'
I suppose that the error occured in the following parts.
while True:
wn.update()
# Move the ball
ball.setx(ball.xcor() + ball.dx)
ball.sety(ball.ycor() + ball.dy)
# Border checking
if ball.ycor() > 290:
ball.sety(290)
ball.dy *= -1
if ball.ycor() < -290:
ball.sety(-290)
ball.dy *= -1
if ball.xcor() > 390:
ball.setx(0)
ball.dx *= -1
if ball.xcor() < -390:
ball.setx(0)
ball.dx *= -1
# Paddle and ball collisions
if ball.xcor() > 330 and (ball.ycor() < paddle_b.ycor() + 50 and ball.ycor > paddle_b.ycor() - 50):
ball.setx(340)
ball.dx *= -1
Thank you for any guidance or help.

The very issue you have is in the next place
ball.ycor > paddle_b.ycor() - 50
ball.ycor is a python method, when paddle_b.ycor() - 50 is an int, that what the interpreter warned you about. You just need to add brackets to actually call the method.
ball.ycor() > paddle_b.ycor() - 50

Related

Manually configuring a scheduling for learning rate in `pytorch_lightning`

I would like to manually configure the learning rate scheduling using pytorch_lightning in the following way:
for epoch in range(0, 600):
if (epoch + 1) % 200 == 0:
for g in optimizer.param_groups:
g['lr'] *= 0.5
What I have tried is the following:
def training_step(self, batch, batch_idx):
X,y = batch
preds = self.forward(X)
loss = self.loss(preds,y)
self.log('train_loss', loss, prog_bar=False)
self.train_losses.append(loss)
if self.current_epoch % 200 == 0 :
opt = self.optimizers()[0]
return loss
but I get back the following
TypeError: 'LightningAdamW' object is not subscriptable
EDIT:
I've simply found the solution by doing:
if self.current_epoch % 200 == 0 :
for g in self.optimizers().param_groups:
g['lr']*=0.5
return loss
My last perplexity is: is this something I should add in some Callback instead of leaving it directly into the training step?

How do I add a 1 second delay?

Hey I'm making this game and i need a 1 or more second delay?
Got any ideas?
heres where i need a delay in between tx3 = 1000 and cheesyx = 1000.
if x < 300 and y < 300 and not duringfight:
win.blit(cheesyt3, (tx3, ty3))
if x < 250 and y < 250 and not duringfight:
tx3 = 1000
cheesyx = 1000
if cheesyx == 1000:
deathx -= 5
if deathx == 600:
deathx += 5
deathmove = False
wmx = 1000
win.blit(deathtext, (dtext, 400))
if x > 400:
dtext = 1000
win.blit(deathhanpup, (deathx, deathy))
deathy = 1000
Since time.sleep doesnt work that well with pygame, you can use the time module to compare the current time with the last execution, and execute your code in a (event)loop only after more than a second has passed.
import time
last_execution = time.time()
if time.time() - last_execution > 1:
last_execution = time.time
execute_code_you_want()
Pygame time
In pygame, time.sleep(1) doesn't work well, so you could do pygame.time.delay(1), that works fine.
Link: https://www.pygame.org/docs/ref/time.html#pygame.time.delay.

How Do I move my mouse with flexible speed

I read something about pywin32 with give's you the possibility to move the curser to One Point to another.
How would I Click on one point and move it with a specific speed to another direction without the cursor "jumping" to that direction?
I want a result where you could see what points it has passed.
OS is Windows.
Say you have two points, a start and a stop; you can calculate the line equation between them and just call win32api.SetCursorPos multiple times to animate the movement.
import win32api, time
def moveFromTo(p1, p2):
# slope of our line
m = (p2[1] - p1[1]) / (p2[0] - p1[0])
# y intercept of our line
i = p1[1] - m * p1[0]
# current point
cP = p1
# while loop comparison
comp = isGreater
# moving left to right or right to left
inc = -1
# switch for moving to right
if (p2[0] > p1[0]):
comp = isLess
inc = 1
# move cursor one pixel at a time
while comp(cP[0],p2[0]):
win32api.SetCursorPos(cP)
cP[0] += inc
# get next point on line
cP[1] = m * cP[0] + i
# slow it down
time.sleep(0.01)
def isLess(a,b):
return a < b
def isGreater(a,b):
return a > b
moveFromTo([500,500],[100,100])

Changing a variable based on a user's input

I am trying to have xpos and ypos change based on the direction the player enters. The program succeeds in asking Where to? but the position does not change. The script also always defaults to the last condition (puts("You're drunk.")).
For example:
> n
0
1
However, my output is:
> n
You're drunk.
0
0
This is my current code:
north = "n"
west = "w"
south = "s"
east = "e"
xpos = 0
ypos = 0
puts("WHERE TO?")
compass = gets
if compass == north
ypos = ypos + 1
elseif compass == west
xpos = xpos - 1
elseif compass == south
ypos = ypos - 1
elseif compass == east
xpos = xpos + 1
else
puts("You're drunk.") #if the player does not submit a proper direction
puts(xpos) #for debugging. prints zero when called showing the player has not moved
puts(ypos)
end
As others have pointed out, it's probably the missing chomp and the elseif.
Just a suggestion, but this cries out for a case statement:
case compass
when 'north'
ypos = ypos + 1
when 'west'
xpos = xpos - 1
when 'south'
ypos = ypos - 1
when 'east'
xpos = xpos + 1
else
puts("You're drunk.") #if the player does not submit a proper direction
puts(xpos)#for debugging. prints zero when called showing the player has not moved
puts(ypos)
end
It looks like you have two main issues, at least that I can see. First, elseif should be elsif. I'm surprised you aren't getting a syntax error on that.
Second, Kernel::gets returns the next line entered, up to and including the linebreak. This means that you have to remove the linebreak at the end, so that comparing with strings that don't have \r\n or \n, depending on your platform, can be compared. This is very simple: Just replace
compass = gets
with
compass = gets.chomp
(String#chomp reference)
Alternatively, if you'd like to get rid of all whitespace before and after, you could use
compass = gets.strip
(String#strip reference)

Loop doesn't terminate upon checking a condition

This loop does not terminate after I type x. I'm really new to Ruby, and so far, it is so much different than what I learned before - quite interesting,
total = 0
i = 0
while ((number = gets) != "x")
total += number.to_i
i += 1
end
puts "\nAverage: " + (total / i).to_s
Any help is greatly appreciated.
Because gets gives you the newline as well. You need to chomp it.
Try:
while ((number = gets.chomp) != "x")
and you'll see it starts working:
pax> ruby testprog.rb
1
5
33
x
Average: 13

Resources