0

I was writing some code for a "map chooser" and want it to cycle through maps in a line

Here's the code:

maps = ["moon", "earth", "mars", "venus", "jupiter", "saturn", "uranus", "neptune", "houses", "floodland"]
while True:
    map = random.choice(maps)
    sys.stdout.write(map)
    sys.stdout.write("\r")
    time.sleep(1)

Desired result is it cycling through all the maps in a single line, choosing a map, showing it, choosing another map, removing the other map and showing the new map in the same line and so on. What I actually get is the maps getting mixed up with each other like, I get earthland when it cycles through FloodLand and Earth.

What is the problem and how I can resolve it?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Roy
  • 13
  • 2
  • When I'm randomly choosing one item, it's supposed to cycle through them, like, "earth", "floodland", etc but what I get is earthland and other mixed up entries. And, when I mean mixed up, I mean the entries are containing text from other entries – Roy Apr 20 '22 at 09:24

3 Answers3

1

If I understood your question correctly you actually need to use "\n" - line break and not "\r" carriage return. Carriage return - makes your code overwrite text every iteration.

Try this:

maps = ["moon", "earth", "mars", "venus", "jupiter", "saturn", "uranus", "neptune", "houses", "floodland"]
while True:
    current_map = random.choice(maps)
    sys.stdout.write(current_map)
    sys.stdout.write("\n")
    time.sleep(1)

EDIT

My modified version, another variant:

import random
import time

maps = ["moon", "earth", "mars", "venus", "jupiter", "saturn", "uranus", "neptune", "houses", "floodland"]
random.shuffle(maps)

while (rand_map := maps.pop() if maps else None):
    print('\033[2K\033[1G{}'.format(rand_map), end='\r', flush=True)
    time.sleep(1)

var211
  • 596
  • 5
  • 10
  • You are using the \n linebreak, it shows everything in a newline. This not what I want. I want it to choose a map, show it, and choose another map, remove the old map, show the new map and so on. – Roy Apr 20 '22 at 09:52
  • I see, sorry for the not relevant answer. Made another variant just for the record and for fun. – var211 Apr 21 '22 at 16:46
0
from random import randint

map_length= len(maps)

for _ in range(map_length):
    index = int(randint(0,map_length))
    print(maps[index])
0

The problem arise when using sys.stdout.write("\r"). You are basically telling the program to go at the beginning of the line and write the new map from there. When you wrote a longer map before you have some leftovers character at the end when writing a new one.

The fix really depends on the terminal you're printing on. If you can afford an additional variable this solution should work almost everywhere:

maps = ["moon", "earth", "mars", "venus", "jupiter", "saturn", "uranus", "neptune", "houses", "floodland"]
last_print_len = 0
while True:
    current_map = random.choice(maps)
    empty = last_print_len - len(current_map) if last_print_len > len(current_map) else 0
    sys.stdout.write(current_map + " " * empty + "\r")
    last_print_len = len(maps)
    time.sleep(1)

If not, you can try something like:

maps = ["moon", "earth", "mars", "venus", "jupiter", "saturn", "uranus", "neptune", "houses", "floodland"]
while True:
    current_map = random.choice(maps)
    sys.stdout.write('\033[2K\033[1G')    # Erase and go at the beginning of line  
    sys.stdout.write(current_map + "\r")
    time.sleep(1)
Deusy94
  • 733
  • 3
  • 13