Kurze Pause

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
Benutzeravatar
Kebap
User
Beiträge: 803
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Früher hab ich am C64 im Supermarkt immer aus Spaß einen kurzen Zweizeiler programmiert, der dann da lustige Labyrinthe auf die Bildschirme zauberte.

Wenn ich das in Python probiere, scrollt das viel zu schnell durch. Wie kann ich eine kurze Pause in die Schleife einbauen? Möglichst Hardware-agnostisch?

Also die erste Idee wäre einfach eine sinnlose Schleife hochzählen lassen, aber deren Dauer ist ja vorher gar nicht so einfach zu bemessen.

Code: Alles auswählen

import random
while True: 
  print(random.choice("/\\"), end="")
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
Kebap
User
Beiträge: 803
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Ah, ich gebe mir einfach mal selbst die Antwort: Es gibt dafür time.sleep()

Code: Alles auswählen

import random
from time import sleep
while True: 
  print(random.choice("/\\"), end="")
  sleep(0.05)
OK, jetzt pausiert aber die komplette Ausgabe. Sprich, man sieht das Labyrinth erst nach Keyboard Interrupt und nicht sofort Zeichen für Zeichen aufbauen.

Warum? Wie kann ich das heilen?

Nächste Frage: Wieso kann ich Befehle nicht mehr in eine Zeile quetschen? Früher ging das doch mit Doppelpunkt? Jetzt funken Annotationen dazwischen.

Code: Alles auswählen

    while True: print(random.choice("/\\"), end="") : sleep(0.05)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: illegal target for annotation
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
noisefloor
User
Beiträge: 4327
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

zum letzten Punkt: der 2. Doppelpunkt im Einzeiler ist syntaktisch falsch bzw. da kommt der Fehler her. Schon immer, dass kann so auch früher nicht funktioniert haben. Da muss wenn ein ; hin.

Gruß, noisefloor
imonbln
User
Beiträge: 213
Registriert: Freitag 3. Dezember 2021, 17:07

Du musst statt des zweiten Doppelpunkts ein Semikolon verwenden. Zudem kennt print den Parameter flush, mit dem du dafür sorgst, dass stdout sofort dargestellt wird.

Code: Alles auswählen

while True: print(random.choice("/\\"), end='',flush=True); time.sleep(0.05)
Benutzeravatar
Kebap
User
Beiträge: 803
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Ihr habt Recht. Der Doppelpunkt stammt wohl noch aus BASIC. :mrgreen: Danke auch für den Hinweis auf Flush.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
__blackjack__
User
Beiträge: 14415
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kebap: Das Programm was Du wahrscheinlich meinst ist dieser Klassiker, zu dem es auch ein Buch gibt, das _das_ als Titel hat:

Code: Alles auswählen

10 PRINT CHR$(205.5+RND(1));:GOTO 10
Und / und \ sind da nur ein schlechter Ersatz für die Grafikzeichen im PETSCII-Zeichensatz. Das kann man heute ziemlich Originalgetreu mit Unicode-Zeichen nachstellen. Die beiden diagonalen Linien liegen als Codepoint nämlich auch genau nebeneinander, so dass man den gleichen ”Trick” im Code verwenden kann mit 9585 statt mit 205:

Code: Alles auswählen

import random, time
while True: print(chr(int(9585.5 + random.random())), end="", flush=True); time.sleep(0.02)
“The city's central computer told you? R2D2, you know better than to trust a strange computer!” — C3PO
Benutzeravatar
Kebap
User
Beiträge: 803
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Boah, danke, diese Zeichen sind VIEL besser!

Vorher:

Code: Alles auswählen

\\\//\\\\\/\\\/\\//////\/\//\\/\/\\//\/\\//\\\\\\/\////\/////\\//\\//\\\//\\/\/
\\\//////\////\\\\/\////\\//\\/\/\\\/\\\///\/\/\////\///\\\\//\\\/\//\/\\////\\
//\\/\\//\\//\/\/\\/\/\\\\/\//\//\\/\\\/\//\\\\/\\/\\//\///\////\//\/\//\\\/\//
\/\/\\\\\//\///\\\\\///\//\//\/\\\///\///\\/\\\\//\\\////\\\\\/\\\\\//\//\//\\/
/\//////\\\///\///////\/\\/\//\\//\/\\\\/////\/\\/\\\/\//\//\/\\/\\//\\//\\//\/

Dank __blackjack__ nun:

Code: Alles auswählen

╲╱╲╲╱╱╱╲╱╲╲╲╲╲╲╱╱╲╲╱╱╲╱╱╲╲╱╱╲╲╲╱╱╲╱╱╲╲╱╱╱╱╲╲╱╱╱╲╱╲╱╲╱╲╲╲╱╲╲╱╱╲╱╲╲╲╱╲╱╲╱╲╲╱╲╱╲╲╲
╱╲╱╲╲╲╲╲╲╲╱╲╲╱╱╱╱╱╲╱╱╲╲╱╲╱╱╲╲╲╱╱╲╱╲╲╱╱╱╲╱╱╱╲╲╱╱╱╲╲╱╱╲╲╱╱╲╱╱╲╱╱╲╲╱╱╲╲╲╱╲╲╲╲╱╱╲╱╲
╲╲╲╲╱╲╱╱╲╲╱╲╲╲╱╲╱╱╲╲╱╱╲╱╱╱╲╱╲╱╱╲╱╲╲╱╲╲╲╲╲╱╱╲╲╲╲╱╲╱╱╲╱╱╲╱╲╱╱╲╱╱╱╲╲╱╱╱╲╲╱╲╱╱╱╱╱╲╲
╱╲╲╱╲╲╲╱╱╲╲╱╲╲╲╲╱╲╱╱╱╲╱╲╲╱╱╱╱╱╱╲╱╲╱╱╱╱╲╱╱╱╲╲╲╱╱╱╲╲╱╲╲╱╲╲╲╲╲╱╱╲╲╲╱╲╲╱╱╲╱╲╱╲╲╱╲╲╲
╲╱╲╲╲╱╲╱╱╱╱╱╲╱╱╱╱╱╲╲╱╲╲╲╱╲╲╱╲╲╱╱╲╱╲╱╱╲╲╱╲╲╱╱╱╱╲╲╲╲╲╲╲╱╱╲╲╱╱╱╲╱╲╱╱╲╱╲╱╱╱╱╱╱╱╲╱╱╱
Danke auch für den Hinweis auf das Buch, das ich sicherlich bisher nicht kannte, aber auch sehr gut aussieht:
https://direct.mit.edu/books/oa-monograph/5343/10-PRINT-CHR-205-5-RND-1-GOTO-10
Dank Creative Commons kann man sich dort direkt eine PDF Version ziehen und selbst drin blättern. :ugeek:

Ich war dem Trugschluss aufgesessen, ich hätte mir das ganz allein ausgedacht. Vielleicht irgendwo aufgeschnappt. Spannend!

Und nein, ich hatte das damals nicht mit CHR und Kommazahlen gelöst, sondern mit den ausgeschriebenen Zeichen, die ja auf Tastendruck vorlagen.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
__blackjack__
User
Beiträge: 14415
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das mit CHR$ und der Kommazahl steht im Handbuch vom C64. Dort als Dreizeiler — vor der Ausgabe von den beiden Zeichen wird noch der Bildschirm geleert:

Code: Alles auswählen

10 PRINT "{CLR}"
20 PRINT CHR$(205.5 + RND(1));
30 GOTO 20
{CLR} steht für die CLR/HOME-Taste. Wird auf dem C64 als reverses Herz dargestellt.

Eine Variante die nicht darauf angewiesen wäre, dass die beiden Zeichen in PETSCII direkt aufeinander folgen:

Code: Alles auswählen

10 A$(0)="╱":A$(1)="╲"
20 PRINT A$(2*RND(1));
30 GOTO 20
Die beiden Grafikzeichen gibt man auf dem C64 mit Shift+N und Shift+M ein.

Ich habe es mal ganz grob mit der Stoppuhr ermittelt: Der C64 gibt beim Originalprogramm so ca. 64 Zeichen pro Sekunde aus. Also ein ``time.sleep(0.015625)`` zwischen den Zeichen.
“The city's central computer told you? R2D2, you know better than to trust a strange computer!” — C3PO
nezzcarth
User
Beiträge: 1808
Registriert: Samstag 16. April 2011, 12:47

Hatte mich der Einleitung jetzt irgendwie auf "echte" Labyrinthe in C64-Basic gefreut, was ja auch eine schöne Programmieraufgabe mit ganz verschiedenen Ansätzen ist. Wüsste allerdings auch nicht, wie das mit den Zeichen gehen soll und in zwei Zeilen eh nicht. Schickes ASCII-Art ist es natürlich trotzdem :)
Benutzeravatar
DeaD_EyE
User
Beiträge: 1353
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Der Code von den Ansätzen sieht aus wie Lua. Damit hab ich letztens einen Dobot MG400 programmiert. Kann ich aber nicht empfehlen, wenn man den Roboter im Lehrbetrieb nutzen will (offline programmieren und testen nicht möglich).
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 14415
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DeaD_Eye: Der Code ist in Ruby geschrieben.

Ich frage mich jetzt gerade ob bei den Ansätzen auch der dabei ist, der in David Ahl's „101 BASIC Computer Games“ von 1974 abgedruckt ist: https://archive.org/details/101basiccom ... 6/mode/1up
“The city's central computer told you? R2D2, you know better than to trust a strange computer!” — C3PO
Pedroski55
User
Beiträge: 58
Registriert: Freitag 25. Juli 2025, 00:20

Früher hab ich am C64 im Supermarkt immer aus Spaß einen kurzen Zweizeiler programmiert, der dann da lustige Labyrinthe auf die Bildschirme zauberte.
Ehemaliger Supermarktterrorist also!

Die gnädigen Herren (ich merke keine Damen hier anwesend) sollten es besser wissen als jemanden, der auch noch neu in der Welt der Schlange ist, dazu zu ermuntern, endlose while-Schleifen anzufangen! Ihr gehört, und seid hiermit, getadelt!

Code: Alles auswählen

10 GOTO /dev/null 
20 GOTO 10

Code: Alles auswählen

from random import choice
from time import sleep

# kann beliebig variert werden 20, 60 ergibt ein schönes Rechteck.
def art(hoch, breit):
    for i in range(hoch):
        print( ''.join([choice("|_/\\¯") for j in range(breit)]))
        sleep(0.05)
Art for art's sake, money for God's sake
nezzcarth
User
Beiträge: 1808
Registriert: Samstag 16. April 2011, 12:47

@__blackjack__: Ich habe den Algorithmus nicht durchgearbeitet (wie wird man bei diesen vielen Sprüngen heutzutage nicht wahsinnig? :o ), jedoch sehe ich in der Beispielausgabe in dem Scan abgetrennte Bereiche, z. B. unten Links und unten mittig. Diese würde in einem regulären Labyrinth, das mit einem der gängigen Algorithmen generiert wurde, eher nicht vorkommen. Insofern ist es zumindest keine "korrekte" Implementierung eines "Standard-Algorithmus".

@DeaD_EyE: Ich kann wenig Negatives für lua sagen. Manche Sachen sind ungewohnt, aber ich programmiere da ganz gerne drin.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1353
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

__blackjack__ hat geschrieben: Mittwoch 10. Juni 2026, 12:45 @DeaD_Eye: Der Code ist in Ruby geschrieben.
Oh. Sieht aber aus 1 m Entfernung gleich aus.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
Kebap
User
Beiträge: 803
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Kebap hat geschrieben: Dienstag 9. Juni 2026, 08:56 Ich hatte das damals nicht mit CHR und Kommazahlen gelöst, sondern mit den ausgeschriebenen Zeichen, die ja auf Tastendruck vorlagen.
Während ich versuche, das zu rekonstruieren, ist mir aufgefallen, dass c64 Basic gar keinen ELSE Zweig kennt. Also mal überlegen, wie ich das wohl schaffte.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
Dennis89
User
Beiträge: 1742
Registriert: Freitag 11. Dezember 2020, 15:13

@kebap Du kannst sowas schreiben:

Code: Alles auswählen

10 REM If condition is ture, go to line 200 
20 IF x > 1 THEN 200;
30 REM That is the else-part
40 ...
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 14415
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kebap: Wenn man in strukturiertem BASIC ”denkt”, also so etwas wie

Code: Alles auswählen

IF C THEN
    REM THEN PART
ELSE
    REM ELSE PART
END IF
REM AFTER END IF
Dann ist das generisch in klassichem BASIC so etwas:

Code: Alles auswählen

10 IF C THEN 40
20 REM ELSE PART
30 GOTO 50
40 REM THEN PART
50 REM AFTER END IF
Die beiden Zweige können hier auch beliebig lang sein. Im Grunde ist das so wie man das auch in Assembler strukturieren würde.

Falls der THEN-Zweig nur sehr kurz ist, und hinter das THEN in die Zeile passt, kann man das kürzen auf:

Code: Alles auswählen

10 IF C THEN {THEN PART}:GOTO 30
20 REM ELSE PART
30 REM AFTER END IF
Der ELSE-Zweig kann hier beliebig lang sein. Eventuell kann es also auch sinnvoll sein, die Bedingung zu negieren wenn man einen kurzen ELSE- aber langen THEN-Zweig hat.

Und wenn dabei am Ende verkettete Sprünge auftreten, kann man die natürlich ”rückwärts ersetzen”, also wenn man ein ``GOTO {end if}`` hat, was direkt zu einem ``GOTO {endlosschleife}`` führt, kann man das erste auch gleich durch ``GOTO {endlosschleife}`` ersetzen.

Aber einfacher ist es die beiden Zeichen einfach in ein Array zu stecken oder in eine Zeichenkette und dann über den zufällig ausgewürfelten Index zu wählen. Mit dem Array hatte ich das ja schon gezeigt. Wenn die Zeichencodes nicht zusammenhängend sind, wie beispielsweise bei der Erweiterung von Pedroski55, dann ist das die naheliegende Lösung. Hier mit Zeichenkette und MID$():

Code: Alles auswählen

10 A$="│▁╱╲▔":N=LEN(A$)
20 PRINT MID$(A$,RND(1)*N+1,1);
30 GOTO 20
@nezzcarth: Diese Umsetzung von strukturierter Programmierung in klassisches BASIC muss man einfach nur rückwärts denken um mit den ganzen GOTOs klar zu kommen. Früher notfalls auf Papier. Heute schreibe ich das dann eher in QBasic, also in strukturiertes BASIC um. Erster Schritt alle Zeilennummern entfernen, die nicht Ziel von Sprüngen sind, denn die braucht man ja letztendlich gar nicht. Und dann nach und nach IF/ELSE-GOTOs durch IF/ELSE/END IF ersetzen und Schleifen-GOTOs durch DO…LOOP, und alles hübsch einrücken. Bei Übriggebliebenen GOTOs und bei GOSUBs die Zeilennummern durch sprechende Labels ersetzen, und Variablennamen sprechender machen, und schon ist das meiste viel besser verständlich.

Wirklich hässlich sind Programme bei denen das nicht so einfach geht, weil FOR…NEXT nicht paarweise auftreten oder Schleifen nicht sauber ineinander verschachtelt sind.
“The city's central computer told you? R2D2, you know better than to trust a strange computer!” — C3PO
Antworten