Search this site
Embedded Files
Python Jedi
  • Chapters
    • Fork/Clone
    • 1 Version Control
    • 2 Python Console
    • 3 Input/Output
    • 4 Conditionals
    • 5 Looping
    • 6 Num. Systems
    • 7 Graphics
    • 8 Lists/Strings
    • 9 Functions
    • Prisoner's Dilemma
    • 10 Classes
    • 11 Animation
    • 12 User Control
    • 13 Libraries/Modules
    • 14 Game Design
      • 14 Sprites
      • 14 Shooting
      • 14 Explosions
      • 14 Levels
      • 14 Aiming Trig
      • 14 Walls
      • 14 View Port
      • 14 Grids
    • 15 Data Analysis
Python Jedi
  • Chapters
    • Fork/Clone
    • 1 Version Control
    • 2 Python Console
    • 3 Input/Output
    • 4 Conditionals
    • 5 Looping
    • 6 Num. Systems
    • 7 Graphics
    • 8 Lists/Strings
    • 9 Functions
    • Prisoner's Dilemma
    • 10 Classes
    • 11 Animation
    • 12 User Control
    • 13 Libraries/Modules
    • 14 Game Design
      • 14 Sprites
      • 14 Shooting
      • 14 Explosions
      • 14 Levels
      • 14 Aiming Trig
      • 14 Walls
      • 14 View Port
      • 14 Grids
    • 15 Data Analysis
  • More
    • Chapters
      • Fork/Clone
      • 1 Version Control
      • 2 Python Console
      • 3 Input/Output
      • 4 Conditionals
      • 5 Looping
      • 6 Num. Systems
      • 7 Graphics
      • 8 Lists/Strings
      • 9 Functions
      • Prisoner's Dilemma
      • 10 Classes
      • 11 Animation
      • 12 User Control
      • 13 Libraries/Modules
      • 14 Game Design
        • 14 Sprites
        • 14 Shooting
        • 14 Explosions
        • 14 Levels
        • 14 Aiming Trig
        • 14 Walls
        • 14 View Port
        • 14 Grids
      • 15 Data Analysis

Fork/Clone Ch.14B Game Design: Grids

Array Backed Grids

Games like minesweeper, tic-tac-toe, and many types of adventure games keep data for the game in a grid of numbers. For example, a tic-tac-toe board can use a grid of numbers to represent the empty spots, the O’s and the X’s. This grid of numbers can also be called a two-dimensional array or a matrix. The values of the numbers in the grid represent what should be displayed at each board location. In this example, 0 represents a spot where no one has played, a 1 represents an X, and a 2 represents an O.

Here is the classic minesweeper game. The number 10 represents a mine, the number 0 represents a space that has not been clicked, and the number 9 represents a cleared space. The numbers 1 to 8 represent how many mines are within the surrounding eight squares, and is only filled in when the user clicks on the square.

starter code

     You are going to eventually create two grid games of your choice after you accomplish this Jedi Training. In this example, we will create a grid that will allow us to paint by clicking on squares to toggle them blue or white. We can change the grid value and paint it blue by clicking on it. This is a first step to making grid-based games. You will begin with the starter code in the repository.

#5-6: We first want to set some constants. We will make a playing grid of 10 rows and 13 columns.

#9-11: Each box will have a width and height of 20 pixels and a margin of 5 pixels between and around boxes.

Calculate SW and SH based on the variables we created above. If we have 10 rows, and each row is 20 high, that’s 200 pixels. If we have 10 rows, that’s also 11 margins. (Nine between the cells and two on each edge.) That is 55 more pixels for a total of 255. Write the equation so it works with our constants above. Try to do this on your own before looking at the code below.

#14-15: If we add a square width to a margin width in parentheses, we can then multiply that by the number of columns. We then have to add on one more margin width on the end to give us our screen width (SW). The equation for screen height is similar. 

#25: Change the window background to black.

Draw the Grid

Try to follow the steps to draw the grid in the on_draw() section.

STEP 1: Draw a white box in the lower-left corner. Draw the box using the height and width variables created earlier.  You will need to center the rectangle at (x, y). Define variable x and y before you use the draw_rectangle_filled function.  If correct, it should look like:

STEP 2: Use a for loop to draw COLS boxes in a row. Use column for the variable name in the for loop. The output will look like one long box until we add in the margin between boxes.

STEP 3: Adjust the drawing of the rectangle to add in the MARGIN variable. Now there should be gaps between the rectangles.

STEP 4: Add the margin before the drawing of the squares, in addition to between each square. 

STEP 5: Put this all in another for loop that also will loop for each row. Call the variable in this for loop row. Adjust the y-parameter. Now we should have a full grid of boxes.

Numpy arrays

Now we need to create a two-dimensional array to store either a 0 or a 1 for each grid space. We need to create this once, at program start-up. So this will go in the program’s __init__ method. Creating a two-dimensional array in Python is, unfortunately, not as easy as it is in some other computer languages. We are going to import the numpy library because it makes creating arrays really easy. Let's discuss how to use numpy.

#2: Here we import the numpy library. We use "as" to create a simple abbreviation to be used in our program.

To create a 2D array filled with a number, we can use:

array = np.full((10,13), 3)

The ordered pair is (rows, columns) and the number given is placed in every location. We want to fill our entire array with zeros at the beginning so we could use:

self.grid = np.full((10,13), 0)

Numpy gives us a shortcut to create an array filled with zeros and we will use that in our program.

#23: We use the .zeros method in the numpy library. We feed the method the (ROWS, COLS) ordered pair.

Two dimensional arrays are usually addressed by first their row, and then the column. This is called a row-major storage. If we used the following code we could change the 0 to a 1 in row 1 and col 5. Since in computer science we start with 0 this would actually be the second row and the sixth column. Add this line of code right after line 23. We will delete this line later after we prove a point.

self.grid[1][5] = 1

In our for loop in the drawing of the grid, we need to check if the grid space contains a 1 or a 0. If it contains a 1 set a variable called color to arcade.color.BLUE. If it is a 0 set color to arcade.color.WHITE. Then use the variable color in the draw_rectangle_filled function instead of the hard coded arcade.color.WHITE.

The full drawing code should now look something like this:

If you run the code it should display this:

Notice the square in row 2 and column 6 is colored blue. This is because it contains a 1. You can now delete the following line of code.

self.grid[1][5] = 1

Now we want to change a square to a 1 so it will turn blue if we mouse click on the square. 

#50-51: In the on_mouse_press() section we need to convert the x and y mouse coordinates into row and column grid coordinates. Remember to use the width and height of each grid location combined with the margin. It will be necessary to convert the final value to an integer. This can be done by using int or by using the integer division operator // instead of the normal division operator /.

#55: Use an if statement to make sure we are on the grid because technically we could click in the very top right corner margin which wouldn't exist because of how we calculated the row and column.

#58-61: If the grid space is 0 change it to 1 and if it is a 1 change it to 0.

Hope your code worked and it made you feel happy! 

This concludes your Chapter 14B Jedi Training. Show your program to your instructor and then discuss what two Grid Based Games you would like to work on during the next couple of weeks.

Quick Lookup:How to download and turn in Jedi Tasks
Syllabus
Marc C. Hermon - Python Jedi InstructorUrbandale High School, Urbandale, Iowahermonm@urbandaleschools.comWebsite: EngineeringU.com
Google Sites
Report abuse
Google Sites
Report abuse