Python curses: addstr() from file prints blanks for the remainder of the line
Question: I'm writing a very simple farming game in Python using curses. At this point I
have been successful in allowing the player (just a "@" character) to move
around within a window.

I have a few files with ascii-art that I print to the window as things to
populate the world in which the player can move around. For example, I have a
file, named "house", that contains:

    
    
     _ . ^ . _
    /____.____\
    |         |
    | ## _ ## |
    |_""_H_""_|
    

I have a Thing class as follows:

    
    
    class Thing(object):    
    
        def __init__(self, Xstart, Ystart, looksLike, list, window):
            self.Xstart = Xstart
        self.Ystart = Ystart
        self.X = Xstart
        self.Y = Ystart
    
        self.looksLike = looksLike
    
        self.boundries = []
        self.find_boundries()
    
        list.append(self)
    
        self.draw(window)
    
    
    def find_boundries(self):
    
        file = open(self.looksLike).readlines()
        for line in file:
            for char in line:
            if char == '\n':
                pass
            elif char == ' ':   # skip all whitespace
                self.X += 1
            else:
                    self.boundries.append([self.X, self.Y])
                self.X += 1
    
            self.Y += 1
            self.X = self.Xstart
    
        self.X = self.Xstart    # reset x & y to starting coordinates
        self.Y = self.Ystart
    
    
    def draw(self, window):
    
        #file = open(self.looksLike).readlines()
    
        #for line in file:
        #    window.addstr(self.Y, self.X, line)
        #    self.Y += 1
    
    #self.Y = self.Ystart
    
        file = open(self.looksLike).read()
    
        for char in file:
            window.addch(self.Y, self.X, char)
        if char == '\n':
                self.Y += 1
        self.X = self.Xstart
        else:
        self.X += 1
    
    self.X = self.Xstart    
    self.Y = self.Ystart
    

Thus the constructor for my Thing class takes a filename as an argument
(looksLike) and the draw method opens the file, reads it, and prints its
contents to the window. I can, then, create a house object, pass my "house"
file as an argument, and my ascii house will be printed to the window.

The problem is that once the object is printed to the window, when I move the
player to the right of the printed object the player disappears. Above, below,
and to the left of the printed object, however, the player stays in view. For
example,

    
    
     _ . ^ . _
    /____.____\
    |         |
    | ## _ ## |
    |_""_H_""_|
                      @
    

In this position the "@" character is visible, but if I move one space up, it
disappears. If I continue moving the player up, the "@" will reappear after it
moves beyond the topmost character of the house.

I assume this issue is due to the nature of both addstr() and addch() ( I have
tried both) printing whitespace until the end of the window, but I have been
unable to find any documentation on this.

I have considered creating a new window for each object printed, but this
seems like it would get quite cumbersome when more than a few objects are
printed to the window. Also, I hope to define borders around the objects
printed to the screen that are shapes other than just squares or rectangles.

Is there anyway to print from a file to the window without the trailing
whitespace and without creating a new window for each printed object?


Answer: Onfortunately I have never used curses, and I cannot see your player class.

Nevertheless maybe this snippet might give you some ideas (press 'x' to exit
game) (use WASD to move the player) (requires ANSI-enabled console:

    
    
    #! /usr/bin/python3
    
    class _GetchUnix:
        def __init__(self):
            import tty, sys
    
        def __call__(self):
            import sys, tty, termios
            fd = sys.stdin.fileno()
            old_settings = termios.tcgetattr(fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
            return ch
    
    getch = _GetchUnix ()
    
    house = ''' _ . ^ . _ 
    /____.____\\
    |         |
    | ## _ ## |
    |_""_H_""_|'''
    
    class Screen:
        def __init__ (self, width, height, background):
            self.width = width
            self.height = height
            self.bg = '\x1b[{}m'.format (40 + background)
            self.clear = '\x1b[0m'
            self.objects = []
    
        def __iadd__ (self, obj):
            self.objects.append (obj)
            obj.screen = self
            return self
    
        def render (self):
            print ('\x1b[1;1H', end = '')
            for y in range (self.height):
                for x in range (self.width):
                    print (self.bg + ' ' + self.clear, end = '')
                print ()
            for obj in self.objects: obj.render ()
            print ('\x1b[{};1H'.format (self.height) )
    
    class Object:
        def __init__ (self, graphics, foreground, background, x, y):
            self.graphics = graphics.split ('\n')
            self.fg = '\x1b[{}m'.format (30 + foreground)
            self.bg = '\x1b[{}m'.format (40 + background)
            self.clear = '\x1b[0m'
            self.x = x
            self.y = y
    
        def render (self):
            for y, line in enumerate (self.graphics):
                print ('\x1b[{};{}H'.format (self.y + y, self.x), end = '')
                print (self.fg + self.bg + line + self.clear)
    
        def collide (self, x, y):
            if y < self.y: return False
            if x < self.x: return False
            if y > self.y + len (self.graphics) - 1: return False
            if x > self.x + len (self.graphics [y - self.y] ): return False
            return True
    
        def move (self, dx, dy):
            nx, ny = self.x + dx, self.y + dy
            if ny < 1: return
            if ny > self.screen.height: return
            if nx < 1: return
            if nx > self.screen.width: return
            for obj in self.screen.objects:
                if obj == self: continue
                if obj.collide (nx, ny): return
            self.x, self.y = nx, ny
    
    house = Object (house, 0, 7, 6, 3)
    player = Object ('@', 1, 3, 10, 10)
    s = Screen (40, 20, 3)
    s += house
    s += player
    while True:
        c = getch ()
        if c == 'x': break
        if c == 'w': player.move (0, -1)
        if c == 's': player.move (0, 1)
        if c == 'a': player.move (-1, 0)
        if c == 'd': player.move (1, 0)
        s.render ()
    

Here a screen shot:

![enter image description here](http://i.stack.imgur.com/emNyL.png)

