3
\$\begingroup\$

I started making a game in curses, but I feel like I am displaying the map inefficiently and ineffectively.

Here's the code (only the relevant parts):

import curses
world_map = [
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000011111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000011111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000011111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000111111111111111111110000000000000000000000000000000001111111111111111111111111000000000000000000000000000',
 '00000000000000000111111111111111111111000000000000000000000000000001111111111111111111111111000000000000000000000000000',
 '00000000000000000011111111111111111000000000000000000000000000000001111133333111111111111111000000000000000000000000000',
 '00000000000000000000011111111111100000000000000000000000000000000001111133333111111111111111000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000011111111111110000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000011111111111110000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000']
def win(stdscr):
 curses.init_color(255, 0, 0x64 * 1000 // 0xff, 0)
 curses.init_color(254, 0xff * 1000 // 0xff, 0xff * 1000 // 0xff, 0xff * 1000 // 0xff)
 curses.init_color(253, 0x82 * 1000 // 0xff, 0x8c * 1000 // 0xff, 0x51 * 1000 // 0xff)
 curses.init_color(252, 0xff * 1000 // 0xff, 0xe4 * 1000 // 0xff, 0xb5 * 1000 // 0xff)
 curses.init_color(251, 0xc0 * 1000 // 0xff, 0xc0 * 1000 // 0xff, 0xc0 * 1000 // 0xff)
 
 curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLUE) # water
 curses.init_pair(2, curses.COLOR_RED, curses.COLOR_GREEN) # grass
 curses.init_pair(3, curses.COLOR_RED, 255) # trees
 curses.init_pair(4, curses.COLOR_RED, 254) # mountains
 curses.init_pair(5, curses.COLOR_RED, 253) # swamp
 curses.init_pair(6, curses.COLOR_RED, 252) # desert
 curses.init_pair(7, curses.COLOR_RED, 251) # village
 
 colors = [curses.color_pair(1), curses.color_pair(2), curses.color_pair(3), curses.color_pair(4), curses.color_pair(5), curses.color_pair(6), curses.color_pair(7)]
 
 while True:
 
 for i in range(30):
 for j in range(119):
 stdscr.addch(i, j, ' ', colors[int(world_map[i][j])])
 
 stdscr.refresh()
def main():
 curses.wrapper(win)
if __name__ == '__main__':
 main()

Running this produces this window: enter image description here (if you couldn't tell it's just a test)

Is there a better way I could be doing this?

asked Jul 23, 2021 at 1:55
\$\endgroup\$
1
  • \$\begingroup\$ If the water is the char that appears the most you can first fill the screen with it and than color only the things that are not water. You can also compare the prev frame to the curr frame and color only the differences, it might seem slow but actually most of the time here is wasted on IO and coloring operations. \$\endgroup\$ Commented Jul 23, 2021 at 9:16

1 Answer 1

3
\$\begingroup\$

Here's a slight refactoring of your code to improve readability and reduce repetitiveness. (I don't think anything I'm doing here will do much for you in terms of performance, sadly.)

import curses as c
from itertools import product 
world_map = [
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000011111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000011111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000011111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000111111111111111111110000000000000000000000000000000001111111111111111111111111000000000000000000000000000',
 '00000000000000000111111111111111111111000000000000000000000000000001111111111111111111111111000000000000000000000000000',
 '00000000000000000011111111111111111000000000000000000000000000000001111133333111111111111111000000000000000000000000000',
 '00000000000000000000011111111111100000000000000000000000000000000001111133333111111111111111000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000001111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111133333111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111222211000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000011111111111110000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000011111111111110000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001114444411111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111115555555111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000001111111111111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
]
colors_for_initialising = [
 (n, *((i * 1000 // 0xff) for i in rgb))
 for n, *rgb in (
 (255, 0, 0x64, 0),
 (254, 0xff, 0xff, 0xff),
 (253, 0x82, 0x8c, 0x51),
 (252, 0xff, 0xe4, 0xb5),
 (251, 0xc0, 0xc0, 0xc0)
 )
]
RED, BLUE, GREEN = c.COLOR_RED, c.COLOR_BLUE, c.COLOR_GREEN
color_pairs = (
 (1, RED, BLUE), # water
 (2, RED, GREEN), # grass
 (3, RED, 255), # trees
 (4, RED, 254), # mountains
 (5, RED, 253), # swamp
 (6, RED, 252), # desert
 (7, RED, 251) # village
)
def win(stdscr):
 for color in colors_for_initialising:
 c.init_color(*color)
 for color_pair in color_pairs:
 c.init_pair(*color_pair)
 colors = [c.color_pair(i) for i in range(1, 8)]
 
 while True:
 for i, j in product(range(30), range(119)):
 stdscr.addch(i, j, ' ', colors[int(world_map[i][j])])
 stdscr.refresh()
def main():
 c.wrapper(win)
if __name__ == '__main__':
 main()

Summary of the changes I've made here:

  • Introduced an alias for curses (c) to make the code more concise. You can debate whether this change makes the code more or less readable — when you're using a module heavily, such as in this example, I generally prefer to use a shorter alias rather than having to type out the whole module name each time.
  • Also introduced aliases for curses.COLOR_RED, curses.COLOR_BLUE and curses.COLOR_GREEN later on in the code, for the same reason. Out of these three, only curses.COLOR_RED was used more than once, but I introduced aliases for the other two as well so as to keep the naming of colors consistent.
  • In your win function, you were calling curses.init_color and curses.init_pair repeatedly, which led to some repetitive code. I took the arguments for these calls out of win and put them into the global namespace, then abstracted your series of calls to init_color and init_pair into two for-loops in win.
  • I changed your colors list in win from a list-literal to a list-comprehension, making the code less repetitive, more concise and more readable.
  • I took out your nested for-loop in win and replaced it with a call to itertools.product, which does the same thing but is more concise and (arguably) more readable.
answered Jul 23, 2021 at 8:46
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.