User-define function not working in Python - python

#imports
import turtle
import time
delay = 0.1
#design
window = turtle.Screen()
window.title("Snake Game by LZ")
window.bgcolor("#cce0ff")
window.setup(width=700, height=750)
window.tracer(0)
head = turtle.Turtle()
head.speed(0)
head.shape("circle")
head.color("black")
head.penup()
head.goto(0,0)
head.direction = "stop"
#functions
def go_up():
head.direction = "up"
def go_down():
head.direction = "down"
def go_left():
head.direction = "left"
def go_right():
head.direction = "right"
def motion():
if head.direction == "up":
y = head.ycor()
head.sety(y + 10)
def motion():
if head.direction == "down":
y = head.ycor()
head.sety(y - 10)
def motion():
if head.direction == "left":
x = head.xcor()
head.setx(x - 10)
def motion():
if head.direction == "right":
x = head.xcor()
head.setx(x + 10)
#keyboard bindings
window.listen()
window.onkeypress(go_up, "Up")
window.onkeypress(go_down, "Down")
window.onkeypress(go_left, "Left")
window.onkeypress(go_right, "Right")
#main game loop
while True:
window.update()
motion()
time.sleep(delay)
window.mainloop()
Here's my problem: I created a very simple Python program where if you press the → key, a black circle will move towards the right and if you press ↑ key, it will move upwards. Somehow, only the → is responding/functioning while the other three keys aren't.
My user-define functions (go_up, go_down, go_left, go_right) all seem alright, but I just don't understand why only go_right is working while the others aren't. Could anyone help me?

You redefine the motion() function every time you declare it. So when referring to it you only actually refer to the last one.
Try adding your conditions to 1 function as an if/else block
def motion():
if head.direction == "up":
y = head.ycor()
head.sety(y + 10)
elif head.direction == "down":
y = head.ycor()
head.sety(y - 10)
elif head.direction == "left":
x = head.xcor()
head.setx(x - 10)
elif head.direction == "right":
x = head.xcor()
head.setx(x + 10)

Related

I was using turtle for making snake game but facing problem while making functions of the program as it is not moving

#importing
import turtle
import random
import time
def snake_game():
#making head global so it can be used in other functions
global head
#scores
score = 0
high_score = 0
#setting up screen
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor('yellow')
wn.setup(width=600, height=600)
wn.tracer(0)
# making snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("black")
head.penup()
head.goto(0,0)
head.direction = "stop"
#snake food
food= turtle.Turtle()
food.speed(0)
food.shape("square")
food.color("red")
food.penup()
food.goto(0,100)
segments = []
#scoreboards
sc = turtle.Turtle()
sc.speed(0)
sc.shape("square")
sc.color("black")
sc.penup()
sc.hideturtle()
sc.goto(0,260)
sc.write("score: 0 High score: 0", align = "center", font=("ds-digital", 24, "normal"))
#keyboard bindings
wn.listen()
wn.onkeypress(go_up, "w")
wn.onkeypress(go_down, "s")
wn.onkeypress(go_left, "a")
wn.onkeypress(go_right, "d")
#MainLoop
while True:
wn.update()
#check collision with border area
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
#hide the segments of body
for segment in segments:
segment.goto(1000,1000) #out of range
#clear the segments
segments.clear()
#reset score
score = 0
#reset delay
delay = 0.1
sc.clear()
sc.write("score: {} High score: {}".format(score, high_score), align="center", font=("ds-digital", 24, "normal"))
#check collision
if head.distance(food) <20:
# move the food to random place
x = random.randint(-290,290)
y = random.randint(-290,290)
food.goto(x,y)
#add a new segment to the head
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("black")
new_segment.penup()
segments.append(new_segment)
#shorten the delay
delay -= 0.001
#increase the score
score += 10
if score > high_score:
high_score = score
sc.clear()
sc.write("score: {} High score: {}".format(score,high_score), align="center", font=("ds-digital", 24, "normal"))
#move the segments in reverse order
for index in range(len(segments)-1,0,-1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x,y)
#move segment 0 to head
if len(segments)>0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
for segment in segments:
if segment.distance(head)<20:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
#hide segments
for segment in segments:
segment.goto(1000,1000)
segments.clear()
score = 0
delay = 0.1
#update the score
sc.clear()
sc.write("score: {} High score: {}".format(score,high_score), align="center", font=("ds-digital", 24, "normal"))
time.sleep(delay)
wun.mainloop()
def go_up():
if head.direction != "down":
head.direction = "up"
def go_down():
if head.direction != "up":
head.direction = "down"
def go_left():
if head.direction != "right":
head.direction = "left"
def go_right():
if head.direction != "left":
head.direction = "right"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y+20)
if head.direction == "down":
y = head.ycor()
head.sety(y-20)
if head.direction == "left":
x = head.xcor()
head.setx(x-20)
if head.direction == "right":
x = head.xcor()
head.setx(x+20)
Well it was working fine as a normal program as long as the code in the function snake_game was the main program it was moving, but I have to append this game with other games. I have to call this game using a function, so when I converted it to a function it didn't move . The code is running and squares dots are also coming but on pressing keys the snake is not moving. I don't know where it went wrong.

How to open a window for a certain user discord.py

I'm coding a discord bot that you can play games with by typing a command such as !pong and it will open a window to play the classic pong game. The problem is, whenever any user other than me types the command(such as !snake), it opens the window for me, not for them. How can i make the window open for them?
Here is my code:
#client.command()
async def snake(ctx):
await ctx.send(f"Open snake game for {ctx.author.name}...")
# Score
score = 0
high_score = 0
# Set up the screen
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("green")
wn.setup(width=600, height=600)
wn.tracer(0) # Turns off the screen updates
# Snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("black")
head.penup()
head.goto(0,0)
head.direction = "stop"
# Snake food
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("red")
food.penup()
food.goto(0,100)
segments = []
# Pen
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write("Score: 0 High Score: 0", align="center", font=("Courier", 24, "normal"))
# Functions
def go_up():
if head.direction != "down":
head.direction = "up"
def go_down():
if head.direction != "up":
head.direction = "down"
def go_left():
if head.direction != "right":
head.direction = "left"
def go_right():
if head.direction != "left":
head.direction = "right"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x - 20)
if head.direction == "right":
x = head.xcor()
head.setx(x + 20)
# Keyboard bindings
wn.listen()
wn.onkeypress(go_up, "w")
wn.onkeypress(go_down, "s")
wn.onkeypress(go_left, "a")
wn.onkeypress(go_right, "d")
# Main game loop
while True:
wn.update()
# Check for a collision with the border
if head.xcor()>290 or head.xcor()<-290 or head.ycor()>290 or head.ycor()<-290:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
# Hide the segments
for segment in segments:
segment.goto(1000, 1000)
# Clear the segments list
segments.clear()
# Reset the score
score = 0
# Reset the delay
delay = 0.1
pen.clear()
pen.write("Score: {} High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))
# Check for a collision with the food
if head.distance(food) < 20:
# Move the food to a random spot
x = random.randint(-290, 290)
y = random.randint(-290, 290)
food.goto(x,y)
# Add a segment
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("grey")
new_segment.penup()
segments.append(new_segment)
# Shorten the delay
delay -= 0.001
# Increase the score
score += 10
if score > high_score:
high_score = score
pen.clear()
pen.write("Score: {} High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))
# Move the end segments first in reverse order
for index in range(len(segments)-1, 0, -1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x, y)
# Move segment 0 to where the head is
if len(segments) > 0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x,y)
move()
# Check for head collision with the body segments
for segment in segments:
if segment.distance(head) < 20:
time.sleep(1)
head.goto(0,0)
head.direction = "stop"
# Hide the segments
for segment in segments:
segment.goto(1000, 1000)
# Clear the segments list
segments.clear()
# Reset the score
score = 0
# Reset the delay
delay = 0.1
# Update the score display
pen.clear()
pen.write("Score: {} High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))
time.sleep(delay)
wn.mainloop()`
Can anyone help me?
You cannot have it open for them. You can only have it open for the person hosting the bot, if you would like this to work you would need them to download the bot themselves and run it. You could learn to make a browser-based game(will require knowledge of HTML/CSS/js) and generate a new link so they can play on their own browser.
The problem is that you are waiting for key presses here:
wn.listen()
wn.onkeypress(go_up, "w")
wn.onkeypress(go_down, "s")
wn.onkeypress(go_left, "a")
wn.onkeypress(go_right, "d")
While you should be waiting for messages using bot.wait_for(). You can read the official documentation for more information.

What does this error means: "UnboundLocalError: local variable 'pos' referenced before assignment"

So I'm working at a project in Sublime using Python, trying to make a snake game and it keeps giving me this error: "UnboundLocalError: local variable 'pos' referenced before assignment".I've searched for an answer on other forums but couldn't find anything helpful. May u guys help me please
There is the code that I've done so far:
import turtle
import time
import random
global pos
delay = 0.1
wn = turtle.Screen()
wn.title("Snake")
wn.bgcolor("purple")
wn.setup(width=600, height=600)
head=turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("orange")
head.penup()
head.goto(0, 0)
head.direction = "stop"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x - 20)
if head.direction == "right":
x = head.xcor()
head.setx(x + 20)
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("green")
food.penup()
food.goto(-110, 70)
def ball_move():
if head.distance("food")<20:
x = random.randit(-290, 290)
y = random.randit(-290, 290)
food.goto(x, y)
def go_up():
head.direction = "up"
def go_down():
head.direction = "down"
def go_left():
head.direction = "left"
def go_right():
head.direction = "right"
wn.listen()
wn.onkey(go_up, "Up")
wn.listen()
wn.onkey(go_down, "Down")
wn.listen()
wn.onkey(go_left, "Left")
wn.listen()
wn.onkey(go_right, "Right")
while True:
wn.update()
move()
ball_move()
time.sleep(delay)
turtle.mainloop()
The complete error message
Traceback (most recent call last):
File "test3.py", line 88, in <module>
ball_move()
File "test3.py", line 51, in ball_move
if head.distance("food")<20:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/turtle.py", line 1858, in distance
return abs(pos - self._position)
UnboundLocalError: local variable 'pos' referenced before assignment
points to the problem which is this line:
if head.distance("food")<20:
The distance() method expects a position or another turtle as an argument, not a string. In your code, it should read:
if head.distance(food) < 20:
Which, once fixed, immediately fails with your next error:
random.randit() -> random.randint()

Get snake (list of turtles) to restart after self collision?

How would I get my turtle to restart in the middle of screen once it collides with it's own body?
from turtle import Screen, Turtle
import random
import time
DELAY = 100
def move():
if direction == 'up':
y = turtle.ycor()
turtle.sety(y + 20)
elif direction == 'down':
y = turtle.ycor()
turtle.sety(y - 20)
elif direction == 'left':
x = turtle.xcor()
turtle.setx(x - 20)
elif direction == 'right':
x = turtle.xcor()
turtle.setx(x + 20)
screen.update()
screen.ontimer(move, DELAY)
if turtle.xcor()>490 or turtle.xcor()<-490 or turtle.ycor()>490 or turtle.ycor()<-490:
time.sleep(1)
turtle.goto(0,0)
turtle.direction = "stop"
for section in sections
section.goto(1000, 1000)
sections.clear()
if turtle.distance(food) < 20:
x = random.randint(-390, 390)
y = random.randint(-390, 390)
food.goto(x, y)
new_section = Turtle()
new_section.speed(0)
new_section.shape("square")
new_section.color("orange", "grey")
new_section.penup()
sections.append(new_section)
for index in range(len(sections)-1,0, -1):
x = sections[index-1].xcor()
y = sections[index-1].ycor()
sections[index].goto(x, y)
if len(sections) > 0:
x = turtle.xcor()
y = turtle.ycor()
sections[0].goto(x, y)
def up():
global direction
direction = 'up'
def down():
global direction
direction = 'down'
def left():
global direction
direction = 'left'
def right():
global direction
direction = 'right'
screen = Screen()
screen.title(" Snakebite mini Game")
screen.bgcolor('brown')
screen.setup(width=800, height=700)
screen.tracer(0)
turtle = Turtle()
turtle.shape('turtle')
turtle.speed(0)
turtle.penup()
food = Turtle()
food.shape('circle')
food.color("red", "yellow")
food.speed(0)
food.penup()
food.goto(0,100)
sections = []
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()
The basic answer is something like:
if any(turtle.distance(section) < 20 for section in sections):
turtle.goto(0, 0)
direction = 'stop'
...
But be warned, this means that doing a 180 is now a fatal move!
Complete code rework with optimizations, style tweaks and changes to make it more playable:
from turtle import Screen, Turtle
from random import randint
DELAY = 100
def up():
global direction
direction = 'up'
turtle.setheading(90)
def down():
global direction
direction = 'down'
turtle.setheading(270)
def left():
global direction
direction = 'left'
turtle.setheading(180)
def right():
global direction
direction = 'right'
turtle.setheading(0)
def move():
global direction
x, y = old_position = turtle.position()
if direction == 'up':
turtle.sety(y + 20)
elif direction == 'down':
turtle.sety(y - 20)
elif direction == 'left':
turtle.setx(x - 20)
elif direction == 'right':
turtle.setx(x + 20)
if direction != 'stop':
if sections:
if any(turtle.distance(section) < 20 for section in sections):
turtle.goto(0, 0)
direction = 'stop'
for section in sections:
section.hideturtle()
sections.clear()
else:
last_position = sections[-1].position()
if len(sections) > 1:
for index in range(len(sections) - 1, 0, -1):
sections[index].goto(sections[index - 1].position())
sections[0].goto(old_position)
old_position = last_position
if not (-390 < turtle.xcor() < 390 and -390 < turtle.ycor() < 390):
turtle.goto(0, 0)
direction = 'stop'
for section in sections:
section.hideturtle()
sections.clear()
if turtle.distance(food) < 20:
food.goto(randint(-380, 380), randint(-380, 380))
new_section = Turtle()
new_section.shape('square')
new_section.speed('fastest')
new_section.color('orange', 'grey')
new_section.penup()
new_section.goto(old_position)
sections.append(new_section)
screen.update()
screen.ontimer(move, DELAY)
screen = Screen()
screen.title("Snakebite mini Game")
screen.bgcolor('brown')
screen.setup(width=800, height=800)
screen.tracer(False)
turtle = Turtle()
turtle.shape('triangle')
turtle.speed('fastest')
turtle.color('orange', 'grey')
turtle.penup()
food = Turtle()
food.shape('circle')
food.speed('fastest')
food.color('red', 'yellow')
food.penup()
food.goto(randint(-380, 380), randint(-380, 380))
sections = []
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()

Why does it say my mainloop is unreachable?

import turtle
import time
delay = 0.1
ms = turtle.Screen()
ms.title("hungry snake Game by #Rafa")
ms.bgcolor("green")
ms.setup(width=600, height=600)
ms.tracer(0)
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("black")
head.penup()
head.goto(0, 0)
head.direction = "stop"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x + 20)
if head.direction == "right":
x = head.xcor()
head.setx(x - 20)
# main game loop
while True:
ms.update()
move()
time.sleep(delay)
//Here is where am having trouble with the code?
ms.mainloop()
The real error here is the use of while True: and sleep() in an event-driven environment like turtle. We can replace the infinite loop and the time.sleep() with a turtle ontimer() method:
from turtle import Screen, Turtle
DELAY = 100 # milliseconds
def move():
if direction == 'up':
y = turtle.ycor()
turtle.sety(y + 20)
elif direction == 'down':
y = turtle.ycor()
turtle.sety(y - 20)
elif direction == 'left':
x = turtle.xcor()
turtle.setx(x - 20)
elif direction == 'right':
x = turtle.xcor()
turtle.setx(x + 20)
screen.update()
screen.ontimer(move, DELAY)
def up():
global direction
direction = 'up'
def down():
global direction
direction = 'down'
def left():
global direction
direction = 'left'
def right():
global direction
direction = 'right'
screen = Screen()
screen.title("Hungry Snake Game")
screen.bgcolor('green')
screen.setup(width=600, height=600)
screen.tracer(0)
turtle = Turtle()
turtle.shape('square')
turtle.speed('fastest')
turtle.penup()
direction = 'stop'
screen.onkey(up, 'Up')
screen.onkey(down, 'Down')
screen.onkey(left, 'Left')
screen.onkey(right, 'Right')
screen.listen()
# main game loop
move()
screen.mainloop()

Categories

Resources