Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question re: objects and square grids

10 views
Skip to first unread message

Andrew Bradley

unread,
May 15, 2013, 12:56:59 PM5/15/13
to pytho...@python.org
Hello everyone.

I am having a good time programming with Python 3.3 and Pygame. Pygame seems like the perfect platform for the kind of simple games that I want to make.

What I have currently programmed is basically a drawn rectangle filled with 200 squares, each side of the squares being 43 pixels. The rectangle is 20 squares by 10 squares.

This grid is what I want to have the entire game on. There will be pieces that move certain numbers of squares, perform actions that effect pieces on certain squares, etc. The possibilities are endless.

So what I am now trying to do is organize these squares into objects that I can easily reference when programming things related to the squares.

So far, I have done this:

A1 = pygame.Rect(10, 12, 43, 43)
A2
A3
A4
B1
B2
etc.

where said integers are the precise location of the top left-most square for A1, and onward down the line. I would guess that I could continue on in such a fashion, with appropriate box names for each square. But I'm running into the problem of confirming that the code above actually does something useful. For example, I would love to be able to turn A1 a different color, but how does this work? How do I actually utilize these object variable names? Are there methods that I am not aware of, because most things I try tend to do nothing or crash the game. For example, A1.fill(BLUE) does not work.

Any general advice about how to organize my squares into something that is easy to program for would be VERY appreciated. Basically all the games I want to make involve square grids like this, so I want to know as much about them as possible.

Thank you very much for reading this,
Andrew

Dave Angel

unread,
May 15, 2013, 1:55:34 PM5/15/13
to pytho...@python.org
On 05/15/2013 12:56 PM, Andrew Bradley wrote:
> Hello everyone.
>
> I am having a good time programming with Python 3.3 and Pygame. Pygame
> seems like the perfect platform for the kind of simple games that I want to
> make.
>

Pygame indeed looks pretty good to me as well. But I haven't done
anything with it, so I can't give you specific Pygame advice.


> <SNNIP>
>
> So far, I have done this:
>
> A1 = pygame.Rect(10, 12, 43, 43)
> A2
> A3
> A4
> B1
> B2
> etc.
>

This is a code smell in Python (or any reasonable language). I'd
suggest that instead of trying to have 200 separate global variables,
you have one, maybe called grid, as follows:

maxrows = 10
maxcols = 20
grid = []
for row in range(maxrows):
rowdata = []
for column in range(maxcols):
arg1 = ...
arg2 = ...
arg3 = ...
arg4 = ...
rowdata.append(pygame.Rect(arg1, arg2, arg3, arg4)
grid.append(rowdata)


Now, this can be done shorter with list comprehensions, but I figured
this would be clearer for you. I also may have the 10 and 20 reversed,
but you can work that out.

You'd need to make four formulae to get the four arguments to the Rect
call, using row and column respectively. Remember that row and column
will be numbered from zero, not from one.

But now, you can either address a single rect by
grid[4][8]

or you can do something to all of them, or to an entire row, or to an
entire column, pretty easily.


While you're testing your formulae, you might want to replace the
rowdata.append line with something like:

rowdata.append( (arg1, arg2, arg3, arg4) )


And perhaps your maxrows, maxcols might be lower while you're testing.

And you can just print grid to see how those arguments are looking.

--
DaveA

Ian Kelly

unread,
May 15, 2013, 2:01:06 PM5/15/13
to Python
On Wed, May 15, 2013 at 10:56 AM, Andrew Bradley <abrad...@gmail.com> wrote:
> Hello everyone.
>
> I am having a good time programming with Python 3.3 and Pygame. Pygame seems
> like the perfect platform for the kind of simple games that I want to make.
>
> What I have currently programmed is basically a drawn rectangle filled with
> 200 squares, each side of the squares being 43 pixels. The rectangle is 20
> squares by 10 squares.

It's more work, but I would recommend making the squares scalable in
some manner, instead of arbitrarily hard-coding them at 43 pixels.
What are you going to do when somebody has a 4K monitor and wants to
run the game full screen?

> This grid is what I want to have the entire game on. There will be pieces
> that move certain numbers of squares, perform actions that effect pieces on
> certain squares, etc. The possibilities are endless.
>
> So what I am now trying to do is organize these squares into objects that I
> can easily reference when programming things related to the squares.
>
> So far, I have done this:
>
> A1 = pygame.Rect(10, 12, 43, 43)
> A2
> A3
> A4
> B1
> B2
> etc.

This is a tedious, repetitive, and error-prone way to build all the
squares. Instead of having a separate variable for each square,
consider putting them in a collection and building them up using
nested loops. For example, the above could look something like:

squares = []
for row in range(10):
row_squares = []
for column in range(20):
rect = Rect(column * width + x_offset, row * height + y_offset,
width, height)
row_squares.append(rect)
squares.append(row_squares)

Then the A1 rect is accessible as squares[0][0], A2 as squares[0][1],
B1 as squares[1][0], etc. Alternatively, you could store the rects in
a dict and use "A1", "B1", etc. as the keys, but I think you will find
that the game logic will be simpler if you use integers internally for
your rows and columns, rather than the square labels.

> where said integers are the precise location of the top left-most square for
> A1, and onward down the line. I would guess that I could continue on in such
> a fashion, with appropriate box names for each square. But I'm running into
> the problem of confirming that the code above actually does something
> useful. For example, I would love to be able to turn A1 a different color,
> but how does this work? How do I actually utilize these object variable
> names? Are there methods that I am not aware of, because most things I try
> tend to do nothing or crash the game. For example, A1.fill(BLUE) does not
> work.

A Rect only stores position and size information and provides methods
for processing the same. It doesn't know anything about drawing. Use
the pygame.draw or pygame.gfxdraw functions for that. For example, to
fill a part of the screen as indicated by the position of a rect:

BLUE = (0, 0, 255)
pygame.draw.rect(screen, BLUE, squares[0][0])

That said, you probably don't just want to color a square blue. You
probably also want to remember that the square is blue for when you
are redrawing it later. You need to track not just the position of
each square, but also their state. This means that each object in
your "squares" container should not just be a rect, but some broader
object that contains square data, *including* a rect. Something like
this:

class Square:

def __init__(self, rect):
self.rect = rect
self.color = (0, 0, 0)
self.contents = None
# ... and whatever else you need to track

Then when you fill the squares container, you would fill it with
instances of your Square class instead of plain Rects, which gives you
a place to keep track of the square's color, among other things. The
drawing code above then might look something like this:

pygame.draw.rect(screen, some_square.color, some_square.rect)

Dave Angel

unread,
May 15, 2013, 3:57:52 PM5/15/13
to pytho...@python.org
On 05/15/2013 02:14 PM, Andrew Bradley wrote:

Please reply on the list, not privately, unless it's something like a
simple thank-you. Typically, you'd do a reply-all, then delete the
people other than the list itself. Or if you're using Thunderbird, you
could just reply-list.

> Thank you very much for your response: it seems excellent, but I'm
afraid I
> do not understand it fully. Your code here:
>
> maxrows = 10
> maxcols = 20
> grid = []
> for row in range(maxrows):
> rowdata = []
> for column in range(maxcols):
> arg1 = ...
> arg2 = ...
> arg3 = ...
> arg4 = ...
> rowdata.append(pygame.Rect(arg
> 1, arg2, arg3, arg4)
> grid.append(rowdata)
>
> Seems very good, but keep in mind I just started programming last
week, and
> this is hard for me to wrap my head around. Do I really just write grid =
> []? or is this like a def grid(): function?

This code was intended to replace the 200 lines you started, A1=
pygame... A2= A3= etc. I'd have put them inside a function, but this
is just one of the things I'd have initialized in such a function. grid
is a list of lists, not a function.


> What do you mean by rowdata = []?

[] is the way you define an empty list. Another way might be:
rowdata = list()


> And how exactly would I make the formula for a rect call?

Well, for row==0 and col==0, you say you wanted 10, 12, 43, and 43 for
the four parameters. But you never said how you were going to
(manually) calculate those numbers for other cells. Only once you've
decided that can you fill in "formulas" for arg1 and arg2. I suspect
that arg3 and arg4 are simply 43 and 43 respectively, since you want all
the cells to be the same size.

taking my clue from Ian, I might try:

x_offset = 10
y_offset = 12
width = height = 43
arg1 = column * width + x_offset
arg2 = row * height + y_offset
arg3 = width
arg4 = height

That assumes that there is no gap between cells in this grid. If you
want a gap, then the width value used in the arg1 formula would be more
than 43 (width). Likewise the height value used in the arg2 formula
would be more than 43 (height).

> If there's a good website for these kind of details, I would
appreciate that too.

You cannot begin to write a non-trivial program in Python without
understanding lists pretty thoroughly. Perhaps you should start with
Alan Gauld's tutorial, which doesn't assume previous programming experience.
http://www.alan-g.me.uk/

I haven't studied it, as Python was about my 35th programming language.
But he's very active on Python-tutor, and explains things very well.
So his website is probably very good as well.

Now, as you can see from Ian's message, writing a game using pygame will
require quite a bit of other understanding. He demonstrates with
classes to represent cells, which is indeed what I'd do. But I suspect
you're not nearly ready to consider writing classes. (You use classes
all the time. For example, 5 is an instance of class int.)


--
DaveA


--
DaveA

Andrew Bradley

unread,
May 15, 2013, 4:35:57 PM5/15/13
to Dave Angel, pytho...@python.org
Now I want to show you what I have written:

row = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
column = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
SQUARESIZE = 43

grid = []
for row in range(10):
    row_squares = []
    for column in range(20):
        rect = Rect(12 + column * SQUARESIZE, 10 + row * SQUARESIZE, SQUARESIZE, SQUARESIZE)
        row_squares.append(rect)
    grid.append(row_squares)

It appears to be working (that is, the program still runs without crashing). So now, how can I utilize this new grid list? Thank you for the help so far, I feel like the entire grid is now being worked out.
-Andrew



Andrew Bradley

unread,
May 15, 2013, 6:48:07 PM5/15/13
to Dave Angel, pytho...@python.org
ok, now I have tested this more thoroughly, and it seems i can only do the grid[x][y] function up to grid[9][9], when i really should be able to be doing up to grid[10][20].
What exactly is the function of this row_squares list?

Dave Angel

unread,
May 15, 2013, 8:17:48 PM5/15/13
to pytho...@python.org
Please put new comments AFTER the part you're quoting. In other words,
don't top-post. Also please trim off the stuff that's no longer
relevant, so people don't have to read through it all wondering where
your implied comments are.

On 05/15/2013 06:48 PM, Andrew Bradley wrote:
> ok, now I have tested this more thoroughly, and it seems i can only do the
> grid[x][y] function up to grid[9][9], when i really should be able to be
> doing up to grid[10][20].

No, you shouldn't expect it to go to 10,20. Remember I said that Python
is zero-based. So it goes from 0 to 9 inclusive, and from 0 to 19
inclusive. Upper left corner is grid[0][0], while lower right is
grid[9][19]. Check to make sure that range works, which I think it will.


> What exactly is the function of this row_squares list?

It's a temporary to hold one row. You could delete it after the outer
loop ends, if you like. Normally, if this whole thing were inside a
function, the variable would go away when the function ended, and you'd
be returning the grid list only.

You could have avoided the separate name by doing some tricky syntax.
But I'm trying to show you the clearest way of doing things from a
beginner perspective.

>
>
>
> On Wed, May 15, 2013 at 4:35 PM, Andrew Bradley <abrad...@gmail.com>wrote:
>
>> Now I want to show you what I have written:
>>
>> row = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
>> column = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
>> 18, 19, 20)

No point in initializing them to tuples, since you're not going to use
those. Besides, in a moment row and column become ints, and this just
confuses things. The range() function below builds a temporary list
which looks just like what you tediously typed in (except it's square
brackets instead of round).

>> SQUARESIZE = 43
>>
>> grid = []
>> for row in range(10):
>> row_squares = []
>> for column in range(20):
>> rect = Rect(12 + column * SQUARESIZE, 10 + row * SQUARESIZE,
>> SQUARESIZE, SQUARESIZE)
>> row_squares.append(rect)
>> grid.append(row_squares)
>>
>> It appears to be working (that is, the program still runs without
>> crashing).

Sorry, but that's no criteria. Question is whether it's doing what you
want. Are the rows 20 across and are there 10 of them? Do the values
of each individual rect look right? print is your friend.

>> So now, how can I utilize this new grid list? Thank you for the
>> help so far, I feel like the entire grid is now being worked out.
>> -Andrew
>>

That's a Pygame question, and I told you at the beginning, I can't
really help with that. I'd like to learn, but not this week.

Others - can you show some minimal code to use these grid parameters to
color selected squares of the pygame window?

--
DaveA

Andrew Bradley

unread,
May 15, 2013, 8:53:05 PM5/15/13
to Dave Angel, pytho...@python.org


SQUARESIZE = 43

grid = []
for row in range(10):
     row_squares = []
     for column in range(20):
         rect = Rect(12 + column * SQUARESIZE, 10 + row * SQUARESIZE,
SQUARESIZE, SQUARESIZE)
         row_squares.append(rect)
     grid.append(row_squares)

It appears to be working (that is, the program still runs without
crashing).

Sorry, but that's no criteria.  Question is whether it's doing what you want.  Are the rows 20 across and are there 10 of them?  Do the values of each individual rect look right?  print is your friend.

Yes, I have gotten rid of that part with the 1, 2, 3, 4, etc., and now the code appears to be working up to [9][19]. Thank you very much. The coordinates all do look correct, and there are 200 rectangles when I do list(grid).


So now, how can I utilize this new grid list? Thank you for the
help so far, I feel like the entire grid is now being worked out.
-Andrew


That's a Pygame question, and I told you at the beginning, I can't really help with that.  I'd like to learn, but not this week.

Others - can you show some minimal code to use these grid parameters to color selected squares of the pygame window?


Yes, I would very much like some help or general advice now about utilizing this grid thing. How can I refer to these square's new numerical values to do things with them? Will I be using things like "grid[0][1]" in specific functions and methods to refer to squares now? That is what I would like to do, somehow.

I apologize if these questions are too rudimentary--I am trying to wrap my head around how this language works in a more general sense so I can start applying it to things.
-Andrew

Dave Angel

unread,
May 15, 2013, 9:20:31 PM5/15/13
to pytho...@python.org
On 05/15/2013 08:53 PM, Andrew Bradley wrote:
>>
>>
>> <SNIP>
>>
>> So now, how can I utilize this new grid list? Thank you for the
>>>> help so far, I feel like the entire grid is now being worked out.
>>>> -Andrew
>>>>
>>>>
>> That's a Pygame question, and I told you at the beginning, I can't really
>> help with that. I'd like to learn, but not this week.
>>
>> Others - can you show some minimal code to use these grid parameters to
>> color selected squares of the pygame window?
>>
>>
> Yes, I would very much like some help or general advice now about utilizing
> this grid thing. How can I refer to these square's new numerical values to
> do things with them? Will I be using things like "grid[0][1]" in specific
> functions and methods to refer to squares now?

Yes, exactly. Any place in your code (the part I cannot help with) that
you need to specify a rect, you can specify something like grid[3][18].
Eventually, as Ian pointed out, you'll want to store more information
about each cell. But at that time, you could have a more complex object
(that YOU define) instead of just a rect. I just don't think you're
ready for defining such an object.

Larry Hudson

unread,
May 16, 2013, 2:54:37 AM5/16/13
to
On 05/15/2013 05:53 PM, Andrew Bradley wrote:
<snip>

> I apologize if these questions are too rudimentary--I am trying to wrap my head around how this
> language works in a more general sense so I can start applying it to things.
> -Andrew

Check out the book "Making Games with Python & Pygame" at http://inventwithpython.com/pygame/
It's a book you can buy or you can download the pdf or e-reader versions for free.

Also on the same site, "Invent Your Own Computer Games with Python"

Both are pretty good introductions to Python programming, "Invent..." is for non-graphic games,
and may be the better to start with. Don't try to get too advanced too fast -- you'll only get
frustrated and discouraged. But definitely do keep at it -- it's well worth the effort.

-=- Larry -=-

0 new messages