How to draw a line of characters in a grid (nested lists)
Given a w x h sized grid, produc开发者_Go百科ed in the following way
self.grid = [ ['-'] * self.w ] * self.h
I wish to "draw" a "line" of characters between two points in said grid. The following code is what I've come up with
def line( self, char, (x1, y1), (x2, y2) ):
self.point( char, (x1, y1) )
x = x1 + cmp( x2, x1 )
y = y1 + cmp( y2, y1 )
while x != x2 or y != y2:
self.point( char, (x, y) )
x = x + cmp( x2, x )
y = y + cmp( y2, y )
self.point( char, (x2, y2) )
Where the point() function simply fills in a single point in the grid with char.
This works like a charm for straight lines and perfect diagonals. It works for "crooked" lines too, in the sense that it doesn't throw errors, but it doesn't exactly look like a line between two points, more like... I don't know, a hockey stick.
For example, given a 10x7 grid and the call
line( 'X', (1,1), (5,9) )
I get
----------
-X--------
--X-------
---X------
----X-----
-----XXXXX
----------
What I'd like is probably something more like
----------
-X--------
---X------
-----X----
-------X--
---------X
----------
How would I do this, while not breaking it for straight lines and perfect diagonals in the process? Do I need two distinct pieces of code to handle the two cases, or can one algorithm do both?
You should be using Bresenham's line algorithm, if you insist on programming this yourself at all. Furthermore, be careful about initialising the grid like this:
grid = [ ['-'] * self.w ] * self.h
because of edning up with self.h
copies of the same list:
grid = [ ['-'] * 3 ] * 3
grid[0][0] = 'X'
print grid
# [['X', '-', '-'], ['X', '-', '-'], ['X', '-', '-']]
Use
grid = [['-'] * self.w for ignored in xrange(self.h)]
or Numpy arrays instead.
精彩评论