I'm trying to print a lot of strings from a list, in a for loop. It works fine but it's too slow, is there any way to make it faster.
import time
import os
board = {
1:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
2:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
3:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
4:[' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
5:['#','#','#','#','#','#','#','#','#','#','#','#'],
}
while True:
os.system('clear')
v = 1
while v < 6:
or i in board[v]:
print(i, end = ' ')
v = 1
print('')
In the end it works fine, but it prints too slowly (It makes the text flash). Is there any way to speed it up so it looks consistent?
CodePudding user response:
There is a whole story on refreshing the screen in games. The idea is not to clear the screen between frames.
import time
import os
import atexit
def clear():
print ("{}[2J{}[;H".format(chr(27), chr(27)), end="")
return
def move_to(row,col):
print("{}[{};{}H".format(chr(27), row, col), end="")
return
def hide_cursor():
print('{}[?25l'.format(chr(27)), end="")
return
def show_cursor():
print('{}[?25h'.format(chr(27)), end="")
return
atexit.register(show_cursor)
board = {
1:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
2:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
3:[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
4:[' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
5:['#','#','#','#','#','#','#','#','#','#','#','#'],
}
clear()
hide_cursor()
while True:
move_to(0,0)
v = 1
while v < 6:
for i in board[v]:
print(i, end = ' ')
v = 1
print('')
show_cursor()
then you can refresh only parts of the screen which have changed.
This only works where terminal supports ANSI Escape sequences but that's seems ok since you already use "clear".
CodePudding user response:
The text flashing happens also with C
while using a small matrix like yours (I have the same problem here
).
I don't think this will optimize your code so much, but I would suggest you to use a list
over a dict
in this scope:
board = [0,
[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
[' ','@',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '],
['#','#','#','#','#','#','#','#','#','#','#','#']
]
This will do the same thing, a dict
is useless in this case since you are using int
s as keys.
CodePudding user response:
did you try comprehension?
board = {
1: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
2: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
3: [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
4: [' ', '@', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
5: ['#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'],
}
[[print(i, end=' ') for i in board[v 1]] for v in range(len(board))]
CodePudding user response:
If the board state really is managed this way, you can print line by line rather than char by char:
for row in board:
print(''.join(row))
Or calculate the whole block and issue a single print command immediately after the clear, and only if it actually changed.
def format_board(board):
return '\n'.join(''.join(row) for row in board)
while True:
if format_board(board) != board_lastchange_string:
os.system('clear')
print(format_board(board))
# if you update the board somewhere, save
# `format_board(board)` to `board_lastchange_string`