Koordinaten Abfrage funktioniert nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

Hallo,

Ich habe letzt mit der zusatzbibliothek Turtle angefangen.
Ich wollte snake programmieren.
Mein bisheriger Code sieht so aus:

Code: Alles auswählen

from turtle import*
from random import*
shape("circle")
import time

speed(0)
hideturtle()
penup()
goto(500,-500)


snake = Turtle()
snake.shape("square")
snake.speed(0)
snake.hideturtle()
snake.penup()
snake.goto(300, -300)
snake.pendown()

for i in range(4):
    snake.lt(90)
    snake.fd(600)


snake.penup()
snake.goto(0, 0)
snake.showturtle()

def rechts():
    snake.setheading(0)

onkeypress(rechts, "Right")
listen()

def links():
    snake.setheading(180)

onkeypress(links, "Left")
listen()

def oben():
    snake.setheading(90)

onkeypress(oben, "Up")
listen()

def unten():
    snake.setheading(270)

onkeypress(unten, "Down")
listen()



for i in range(10):
    essenx = randint(-299,299)
    esseny = randint(-299,299)
    essen = Turtle()
    essen.shape("circle")
    essen.color("red")
    essen.speed(0)
    essen.penup()
    essen.goto(essenx,esseny)

    while snake.ycor() < 300 and snake.ycor() > -300 and snake.xcor() > -300 and snake.xcor() < 300:
        snake.fd(5)
        if essen.xcor() == snake.xcor() and essen.ycor() == snake.ycor():
            essen.hideturtle()
            essen.penup()
            essen.goto(500,500)



    snake.hideturtle()
    snake.goto(0,0)
    snake.write("Game Over!", align="Center")
    time.sleep (3)
    break

Das ist der Code zu dem Spiel Snake den ich bisher schon geschrieben habe.

Code: Alles auswählen

if essen.xcor() == snake.xcor() and essen.ycor() == snake.ycor():
            essen.hideturtle()
            essen.penup()
            essen.goto(500,500)
Hier sollte der essens Punkt nachdem essen eigentlich verschwinden.
Wenn man ihn aber aufrisst passiert nichts.
Ich würde mich freuen wenn mir jemand helfen kann.

Lg Boggel
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boggel: Du würfelst für das Essen für die Koordinaten Zahlen zwischen -299 und 299 und hast eine Schlange die sich vom Nullpunkt aus immer in 5er-Schritten bewegt. Nun überleg mal welche Koordinaten die Schlange damit erreichen kann und an welche Stellen sie *nicht* kommen kann. Und vergleiche die beiden Mengen „mögliche Essenskoordinaten“ und „mögliche Schlangenkoordinaten“ miteinander. Da sollte Dir etwas auffallen. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

@_blackjack_ hast recht. Ich habe jetzt fd(1) gesetzt nur das Problem dabei ist, dass man exrem langsam ist.
Wie kann man das denn lösen?
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boggel: Weiterhin 5 als Schrittweite nehmen und das Essen halt nur auf Koordinaten verteilen wo x und y durch 5 teilbar sind.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

@_blackjack_: und wie kann ich nur zufallszahlen die durch fünf teilbar sind erstellen?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Boggel: indem Du sie mit fünf multiplizierst ... 8)
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und natürlich nicht vergessen den Wertebereich für die Zufallszahlen entsprechend einschränken.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

Ich habe das jetzt so abgäendert: essenx = randrange(-280, 280, 5) und: esseny = randrange(-280, 280, 5). Eigtl. müsste das jetzt funktionieren tut es aber nicht. Ich könnte es jetzt so machen wie ihr gesagt habt mit 5 multipliezieren aber ich wollte einfach nur wissen ob das generel auch so funktioniert wie ich es geschrieben habe, da das ja wesentlich einfacher ist.
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boggel: Lass Dir doch einfach mal die Koordinaten vom Essen und der Schlange vor dem ``if`` ausgeben, dann siehst Du ja ob die passen bzw. eben auch nicht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

Sorry das ich mich lange nicht gemeldet habe.
Habe den Code jetzt verändert. Die Schlange bewegt sich in 5-er Schritten und die essens Koordinaten sind immer durch 5 teilbar.

Code: Alles auswählen

from turtle import*
from random import*
shape("circle")
import time

speed(0)
hideturtle()
penup()
goto(500,-500)


snake = Turtle()
snake.shape("square")
snake.speed(0)
snake.hideturtle()
snake.penup()
snake.goto(300, -300)
snake.pendown()

for i in range(4):
    snake.lt(90)
    snake.fd(600)


snake.penup()
snake.goto(0, 0)
snake.showturtle()

def rechts():
    snake.setheading(0)

onkeypress(rechts, "Right")
listen()

def links():
    snake.setheading(180)

onkeypress(links, "Left")
listen()

def oben():
    snake.setheading(90)

onkeypress(oben, "Up")
listen()

def unten():
    snake.setheading(270)

onkeypress(unten, "Down")
listen()



for i in range(10):
    essenx = randrange(-280, 280, 5)
    esseny = randrange(-280, 280, 5)
    essen = Turtle()
    essen.shape("circle")
    essen.color("red")
    essen.speed(0)
    essen.penup()
    essen.goto(essenx,esseny)

    print(essenx)
    print(esseny)


    while snake.ycor() < 300 and snake.ycor() > -300 and snake.xcor() > -300 and snake.xcor() < 300:
        snake.fd(5)
        if essen.xcor() == snake.xcor() and essen.ycor() == snake.ycor():
            essen.hideturtle()
            essen.penup()
            essen.goto(500,500)



    snake.hideturtle()
    snake.goto(0,0)
    snake.write("Game Over!", align="Center")
    time.sleep (3)
    break

Funktioniert aber immer noch nicht :C
Ich habe keine Ahnung was ich falsch mache.
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Boggel: Das Problem sind Gleitkommazahlen und die Ungenauigkeiten die man sich damit einfängt:

Code: Alles auswählen

In [26]: import turtle

In [27]: turtle.left(90)

In [28]: turtle.forward(1)

In [29]: turtle.position()

Out[29]: (0.00,1.00)

In [30]: turtle.position()[0] == 0
Out[30]: False

In [31]: turtle.position()[0]
Out[31]: 6.123233995736766e-17

In [32]: format(turtle.position()[0], '0.50f')
Out[32]: '0.00000000000000006123233995736766035868820147291983'
Da Du eigentlich nur mit ganzen Zahlen operieren möchtest, könntest Du die Koordinaten von der Schlange und dem Essen einfach mit `int()` umwandeln, bevor Du sie vergleichst. Man könnte sich da eine Funktion für schreiben. Insgesamt könnte das Programm mehr Funktionen und weniger globale Variablen vertragen. Im besten Fall gar keine globalen Variablen.

Sternchen-Importe sind Böse™. Während das beim `turtle`-Modul noch vorgesehen ist, würde ich da beim `random`-Modul von abraten. Eigentlich bei allen Modulen, aber bei `turtle` haben die Autoren des Moduls wenigstens dafür gesorgt das man nur ”erwünschtes” auf diese Weise importiert, und nicht einfach *alles* aus dem Modul.

Importe sollten am Anfang des Moduls, vor anderem Code stehen. Das ``shape("circle")`` sollte also nach dem Import von `time` stehen.

`listen()` muss man nur einmal aufrufen.

Das definieren von benannten Funktionen für die Richtungsänderungen der Schlange kann man sich mit `functools.partial()` ersparen.

Vergleichsoperatoren kann man in Python verketten. Statt ``snake.ycor() < 300 and snake.ycor() > -300`` kann man wie man das aus der Mathematik kennt auch ``-300 < snake.ycor() < 300`` schreiben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Boggel
User
Beiträge: 23
Registriert: Samstag 15. Dezember 2018, 12:56

Hallo Blackjack,

erstmal danke für die Umfangreiche Verbesserung meines Programmes. (es gibt nicht immer so nette Leute)
Ich habe jetzt die Koordinaten Umgewandelt. Außerdem habe ich nach erneuten Scheitern eine Ausgabe hinzugefügt, welche mir die Koordinaten der Schlange und des Essens jederzeit mitteilt.

Code: Alles auswählen

    while snake.ycor() < 300 and snake.ycor() > -300 and snake.xcor() > -300 and snake.xcor() < 300:
        snake.fd(2)
        int(essenx)
        int(esseny)
        int(snake.xcor())
        int(snake.ycor())
        print("1", essenx)
        print("2", esseny)
        print("3", snake.xcor())
        print("4", snake.ycor())


Dadurch habe ich entdeckt, dass die 4. Koordinate Sprich die Y Koordinate meiner Schlange immer noch Gleitkommazahlen sind.
Aus irgendeinen Grund wurden bei einem Versuch alle Zahlen korrekt zu Integern umgewandelt. Dann hat es auch super geklappt aber wie gesagt das war nur einmal.

Mfg Boggel
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Hallo Boggel,
int() ist eine Funktion, die einen Integerwert zurück liefert
also musst du diesen Integerwert wieder deiner Variablen zuweisen essenx = int(essenx)
Ich empfehle dir ganz stark, dir die Grundlagen von Python anzueignen, da fehlt einfach die Basis.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten