A grid as a game board
Many games are played on a grid: chess, tic-tac-toe, minesweeper, sudoku, battleship. A matrix is a natural way to keep such a board in a program. Each item is one square, and its two indexes are the square's row and column.
Here is a small sea for a game of battleship, where 0 is water and 1 is part of a ship. The program prints it with symbols a player can read:
sea = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 1, 1],
]
for row in sea:
for square in row:
if square == 1:
print("#", end="")
else:
print("~", end="")
print()
~~~~~
~###~
~~~~~
#~~~~
#~~##end="" keeps the squares of a row on the same line, and the print() after the inner loop ends the row.
Asking the board
Questions about the game become small functions. How many ship squares are there, and does a shot at a given row and column hit?
def ship_squares(sea: list) -> int:
count = 0
for row in sea:
count += row.count(1)
return count
def is_hit(sea: list, row_index: int, column_index: int) -> bool:
return sea[row_index][column_index] == 1
sea = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 1, 1],
]
print("Ship squares:", ship_squares(sea))
print(is_hit(sea, 1, 2))
print(is_hit(sea, 2, 2))
Ship squares: 7
True
FalseStrings on the board
For some games, strings say more than numbers. This tic-tac-toe board holds "X", "O" and "." for an empty square. A row is a win when its three squares hold the same piece, and that piece isn't the empty ".":
def row_winner(board: list, row_index: int) -> str:
row = board[row_index]
if row[0] != "." and row[0] == row[1] and row[1] == row[2]:
return row[0]
return ""
board = [
["O", "X", "."],
["X", "X", "X"],
["O", ".", "O"],
]
print(row_winner(board, 1))
print(row_winner(board, 2) == "")
X
TrueThe function returns the winning piece, or an empty string when the row isn't a win. Printing an empty string prints an empty line, so the example compares it with "" instead.