Skip to content

Course 8: Seven 2D Arrays - 2D arrays and grids

Course overview

In this course, students learn the two-dimensional arrays (2D arrays). A 2D array is a grid structure made of rows and columns, used to represent grid-shaped datasuch as game maps, inventory slots, and spreadsheets. Once you master this concept, you can build block-based games like Minecraft, as well as chess, Sudoku, and more.

Estimated time: 12-24 hours

The time required depends on the student's grade level, prior experience, and learning speed, and varies greatly. It also differs between just learning the basic concepts and moving on, versus additional practice problems or creative projects: taking those on makes a difference too. The times above are an average range, so please proceed flexibly at your child's pace.

What abilities will it build?

tabular data. Excel sheets, database tables, CSV files - 80% of the world's data is a two-dimensional structure made of rows and columns. Handling this structure freely is the heart of data analysis.

What principles will you learn?

  • (table data) By making a row×column structure with a 2D array, they learn how to organize data into a table like Exceland access specific cells. data[row][col]is the same concept as a cell address in Excel.
  • (processing all data) By iterating over every cell with nested loops, they learn how to apply an operation to the whole table. "Find the sum of every row," "find the cells that meet a condition" - these are basic data analysis tasks.
AI-era thinking: computing (problem-solving) | data-driven | probabilistic thinking

Computational Thinking

Skill Description Example activity
🔲 Grid thinking Organize data in a row×column structure Represent a game map as a 2D array
📍 Coordinate access Specify a position with (row, col) grid[2][3] → row 3, col 4
↔️ Value swapping Swap the values of two positions Move inventory items
🔄 Full traversal Visit and process every cell Render the whole map

Mathematical connections

Math concept Programming application Learning benefit
Matrix grid[i][j] Matrix element notation a_ij
Coordinate plane (x, y)(col, row) Two-dimensional coordinate system
Multiplication principle 3 rows × 4 cols = 12 cells Calculate the total number of elements
Index conversion 1D ↔ 2D conversion i = row * cols + col

2D array = matrix

Math matrix:           Programming 2D array:

| 1  2  3 |          grid = [
| 4  5  6 |              [1, 2, 3],
| 7  8  9 |              [4, 5, 6],
                         [7, 8, 9]
a₂₃ = 6              ]
                     grid[1][2] = 6

Index calculation

Expression Meaning Example (3×4 array)
grid[0][0] First row, first column Top-left
grid[2][3] Third row, fourth column Bottom-right
grid[row][col] General access Same as a_ij in math

The 2D array traversal process

flowchart LR
    A[row = 0] --> B[col 0→n]
    B --> C[row = 1]
    C --> D[col 0→n]
    D --> E[...]
    E --> F[Done]

Coordinate conversion formulas

2D → 1D conversion (flatten):
index = row × num_cols + col

e.g.: position (1, 2) in a 3×4 array
index = 1 × 4 + 2 = 6

1D → 2D conversion (fold):
row = index // num_cols
col = index % num_cols

e.g.: index=6, num_cols=4
row = 6 // 4 = 1
col = 6 % 4 = 2 → (1, 2)

Real-life 2D structures

Example Row Column Access method
Movie theater seats Rows A~J Numbers 1~20 seat[row][col]
Excel sheet 1, 2, 3... A, B, C... cell[row][col]
Chessboard 1~8 a~h board[rank][file]
Pixel image height Width pixel[y][x]
💻 Code examples & visualization

Example 1: Creating and accessing a 2D array

# Create a 3x4 2D array
grid = [
    [1, 2, 3, 4],     # row 0
    [5, 6, 7, 8],     # row 1
    [9, 10, 11, 12]   # row 2
]

# Access a specific position
print(grid[0][0])  # 1  (row 0, col 0)
print(grid[1][2])  # 7  (row 1, col 2)
print(grid[2][3])  # 12 (row 2, col 3)

# Change a value
grid[1][1] = 99
print(grid[1][1])  # 99

2D array visualization:

          col 0   col 1   col 2   col 3
        ┌───────┬───────┬───────┬───────┐
row 0   │   1   │   2   │   3   │   4   │
        ├───────┼───────┼───────┼───────┤
row 1   │   5   │  99   │   7   │   8   │
        ├───────┼───────┼───────┼───────┤
row 2   │   9   │  10   │  11   │  12   │
        └───────┴───────┴───────┴───────┘

grid[1][2] = grid[row][col] = 7

Index calculation:
grid[row][col] → a specific position in the 2D array


Example 2: Full traversal with nested loops

grid = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# Print every element
for row in range(3):
    for col in range(3):
        print(f"grid[{row}][{col}] = {grid[row][col]}")

Execution order:

row=0: col=0 → grid[0][0]=1
       col=1 → grid[0][1]=2
       col=2 → grid[0][2]=3

row=1: col=0 → grid[1][0]=4
       col=1 → grid[1][1]=5
       col=2 → grid[1][2]=6

row=2: col=0 → grid[2][0]=7
       col=1 → grid[2][1]=8
       col=2 → grid[2][2]=9

Traversal order (arrows):
┌───┬───┬───┐
│ 1 → 2 → 3 │ ─┐
├───┼───┼───┤  │
│ 4 → 5 → 6 │ ←┘─┐
├───┼───┼───┤    │
│ 7 → 8 → 9 │ ←──┘
└───┴───┴───┘


Example 3: Minecraft-style map

from ursina import *

app = Ursina()

# Map data (0=air, 1=dirt, 2=stone, 3=water)
world = [
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 0, 0, 0, 0, 1, 1],
    [2, 2, 1, 1, 1, 1, 2, 2],
    [2, 2, 2, 3, 3, 2, 2, 2],
    [2, 2, 2, 2, 2, 2, 2, 2]
]

colors = {
    0: None,          # Air (transparent)
    1: color.brown,   # Dirt
    2: color.gray,    # Stone
    3: color.blue     # Water
}

# 2D array → 3D world
for row in range(len(world)):
    for col in range(len(world[0])):
        block_type = world[row][col]

        if block_type != 0:  # If it's not air
            Entity(
                model='cube',
                color=colors[block_type],
                position=(col, -row, 0)
            )

EditorCamera()
app.run()

Map data → visualization:

2D array:                  3D world:

[0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0]             ██          ██
[1,1,0,0,0,0,1,1]   →    ██████████████████
[2,2,1,1,1,1,2,2]        ████████████████████
[2,2,2,3,3,2,2,2]        ████████████████████
[2,2,2,2,2,2,2,2]        ████████████████████

██ = dirt (brown)    ▓▓ = stone (gray)    ░░ = water (blue)


Example 4: Inventory grid

# 4x5 inventory (None = empty slot)
inventory = [
    ["sword", "shield", None, None, None],
    ["potion", "potion", "potion", None, None],
    [None, None, None, None, None],
    [None, None, None, None, "key"]
]

# Check a specific slot
def check_slot(row, col):
    item = inventory[row][col]
    if item:
        print(f"[{row}][{col}]: {item}")
    else:
        print(f"[{row}][{col}]: empty slot")

check_slot(0, 0)  # [0][0]: sword
check_slot(2, 2)  # [2][2]: empty slot
check_slot(3, 4)  # [3][4]: key

# Move an item (swap)
def move_item(from_pos, to_pos):
    r1, c1 = from_pos
    r2, c2 = to_pos
    # Swap the values of two positions
    inventory[r1][c1], inventory[r2][c2] = \
    inventory[r2][c2], inventory[r1][c1]

move_item((0, 0), (2, 2))  # Move the sword to (2,2)

Inventory visualization:

       col 0   col 1   col 2   col 3   col 4
     ┌───────┬───────┬───────┬───────┬───────┐
row 0│  ⚔️   │  🛡️   │       │       │       │
     ├───────┼───────┼───────┼───────┼───────┤
row 1│  🧪   │  🧪   │  🧪   │       │       │
     ├───────┼───────┼───────┼───────┼───────┤
row 2│       │       │       │       │       │
     ├───────┼───────┼───────┼───────┼───────┤
row 3│       │       │       │       │  🔑   │
     └───────┴───────┴───────┴───────┴───────┘

After moving the item:
     ┌───────┬───────┬───────┬───────┬───────┐
row 0│       │  🛡️   │       │       │       │
     ├───────┼───────┼───────┼───────┼───────┤
row 2│       │       │  ⚔️   │       │       │
     └───────┴───────┴───────┴───────┴───────┘


Example 5: Terrain generation (height map)

from ursina import *
import random

app = Ursina()

# Create a height map (random)
size = 10
height_map = []

for row in range(size):
    height_row = []
    for col in range(size):
        # Simple height calculation (center is highest)
        center_dist = abs(row - size//2) + abs(col - size//2)
        height = max(0, 5 - center_dist + random.randint(-1, 1))
        height_row.append(height)
    height_map.append(height_row)

# Height map → 3D terrain
for row in range(size):
    for col in range(size):
        height = height_map[row][col]

        for y in range(height):
            Entity(
                model='cube',
                color=color.green if y == height-1 else color.brown,
                position=(col, y, row)
            )

EditorCamera()
app.run()

How the height map works:

Height map (number = block height):
┌───┬───┬───┬───┬───┐
│ 1 │ 2 │ 2 │ 2 │ 1 │
├───┼───┼───┼───┼───┤
│ 2 │ 3 │ 4 │ 3 │ 2 │
├───┼───┼───┼───┼───┤
│ 2 │ 4 │ 5 │ 4 │ 2 │  ← center is highest
├───┼───┼───┼───┼───┤
│ 2 │ 3 │ 4 │ 3 │ 2 │
├───┼───┼───┼───┼───┤
│ 1 │ 2 │ 2 │ 2 │ 1 │
└───┴───┴───┴───┴───┘

3D visualization (side view):
                ██
             ████████
          ████████████
       ████████████████
    ████████████████████


What is a 2D array?

Concept explanation

A 2D arrayis a structure where there is a list inside a list:

grid = [
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]
]
Real-life example Programming Applications
Chessboard (8×8) Storing piece positions
Excel sheet Data tables
Movie theater seats Managing reservation status
Pixel image Storing color values

Project 1: Digging Grid - Accessing and modifying a 2D array

Item Content
What will you learn? Accessing a specific position in a 2D array
Core Concepts Indexing, row/column concepts

grid[row][col]with Access the value at a specific positiondoes this. grid[0][0] is the first column of the first row. Students row and column concepts solidly. This connects to matrices and coordinate planes in math, and directly connects. In games, you use this approach to check the type of the tile a player is standing on, or to modify that tile.


Modifying values

Item Content
What will you learn? Changing a specific cell in a grid
Core Concepts Dynamic modification, state changes

grid[2][3] = 5with Change the value at a specific position. In a game, when you mine a block, grid[y][x] = 0 (empty space). Students experience that data can change in real time. They see this change reflected on the screen immediately, watching the block disappear. They understand the connection between data (an array of numbers) and visual representation (3D blocks).


Project 2: Inventory Grid - Inventory system

Item Content
What will you learn? Building a game inventory
Core Concepts Data management, UI integration

An inventory is an item storage in the form of a 2D gridIt is. inventory[row][col] that stores which item is in each cell . Students learn how to connect a data structure with a user interface (UI). They implement the interactions of picking up, placing, and moving items. This is a core system found in most gamesIt is.


Moving items

Item Content
What will you learn? Moving data within a grid
Core Concepts Swapping, drag and drop

To move an item from cell A to cell B, you swap the two values. Moving into an empty cell and swapping with another item use different logic. Students learn how to translate user actions into data manipulation. They also build the habit of checking boundary conditions (so they don't go out of array bounds). This is an important practiceIt is.


Project 3: Minecraft Terrain - Terrain generation

Item Content
What will you learn? Procedural terrain generation
Core Concepts Algorithms, noise, procedural generation

Automatically generate Minecraft-style block terrain. You store a block type (stone, dirt, air) at each position in the 2D array. Students learn the procedural generation concept of generating content with algorithms. Using height maps, noise functions, and more, they create natural-looking terrain. Even with the same algorithm, a different world depending on the seed value is generated.


Nested loops and 2D arrays

Item Content
What will you learn? Traversing an entire grid
Core Concepts Nested loops, traversal, batch processing
for row in range(height):
    for col in range(width):
        process(grid[row][col])

With this pattern, you visit every cell in the grid. The outer loop handles rows, and the inner loop handles columns. Students understand how to unfold a 2D structure into a 1D order . This is the most widely used pattern in image processing, game map rendering, data analysis, and more. It is also a first encounter with the concept of time complexity - O(n×m).


When you finish this course...

Learning outcomes

Students will be able to:

  • A 2D arrayCan create and access
  • Nested loopsCan process an entire grid with
  • Gaming Maps and inventoriesCan represent
  • Procedural terrain generationUnderstands the basics of
  • Matrices, images, tables, and more Grid-shaped dataCan work with
  • Ready to take on a more complex game logic (movement, collisions, etc.)