I'm writing a program that draws a grid of squares based on an inputted number of rows and columns, takes an inputted row, column, and color index (indexes from a color look-up table), and draws another square on the grid with the specified color and location. This loops until an empty value is entered.
I created a bitmap array for the color index values of the grid, with each nested list representing a row of squares, and the initial value for each square set to 0.
I want to update a single value in the array each time a new color square is drawn.
I've tried updating the value in the array using
bitmap[row_index][col_index] = clut_index
in the input loop, and also
bitmap[row][col] = colorindex
in the function drawing the colored square.
Each time, instead of updating one value in the array, it updates all the values in the array with the same list index, so that each row/list ends up with the same values.
for example, an input of
5 6
for the grid size, and
0 2 3
2 5 1
4 0 5
for the colored squares should end up with a result of
[[0, 0, 3, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0], [5, 0, 0, 0, 0, 0]]
but ends up with a result of
[[5, 0, 3, 0, 0, 1], [5, 0, 3, 0, 0, 1], [5, 0, 3, 0, 0, 1], [5, 0, 3, 0, 0, 1], [5, 0, 3, 0, 0, 1]]
The squares draw on the grid just fine, but the bitmap list doesn't update correctly.
How do I update only one value in the array at a time? Here is my code, I've bolded the parts regarding the bitmap array. I'm very sorry that the program is long and rather messy:
from turtle import *
from array import *
#inputting the number of rows and columns to make the grid
grid_dimensions = input("Please input the number of rows and number of columns, separated by a space:")
grid_list = grid_dimensions.split(" ")
rows = int(grid_list[0])
columns = int(grid_list[1])
# setting the window size as an aspect ratio of the rows and columns
# this is to make sure that each grid cell is a square
# window has a max size of 800 pixels
if rows > columns:
window_w = (800/rows)*columns
window_h = 800
elif rows < columns:
window_w = 800
window_h = (800/columns)*rows
else:
window_w = 800
window_h = 800
# creating window and coordinate grid
# coordinates are in pixels, grid is the same size as the window
setup(window_w, window_h)
setworldcoordinates(0, 0, window_w, window_h)
# setting the side length of the square as the size of each grid cell
square_length = window_w/columns
# creating a color look-up table of RGB color values
clut = [(1.0, 1.0, 1.0), (0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0), (0.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0, 1.0)]
# creating a bitmap array of the color index value for each square in the grid
# populating the array by setting each value to zero
rowline = []
bitmap = []
for col in range(columns):
rowline.append(0)
for row in range(rows):
bitmap.append(rowline)
# moves the pen to the starting position of each square
def movepos(x, y):
penup()
setpos(x, y)
pendown()
# draws the square based on the row and column positions on the grid
# uses the static square size
def drawsquare(row, col, square_size):
movepos(col*square_size, row*square_size)
for i in range(4):
forward(square_size)
left(90)
# calls the function to draw a square in a loop for the number of columns and rows
def drawgrid(row_number, col_number, square_size):
for row in range(row_number):
for col in range(col_number):
drawsquare(row, col, square_size)
# "colors in the grid cell" by drawing a colored square at a specific row and column position
def colorpixel(row, col, colorindex, square_size):
fillcolor(clut[colorindex])
begin_fill()
drawsquare(row, col, square_size)
end_fill()
# drawing the initial empty grid
drawgrid(rows, columns, square_length)
# creates an empty list to put the input values into
# creates a starting value for the loop
# takes the first set of row, column, and color input values to draw a colored square
index_input = input("Please input a row number, a column number, and a color number separated by spaces, then hit Enter. To finish coloring, hit Enter without entering any values: ")
# loops to draw multiple colored squares
# loop breaks when an empty value is entered
while index_input:
input_list = index_input.split(" ")
row_index = int(input_list[0])
col_index = int(input_list[1])
clut_index = int(input_list[2])
bitmap[row_index][col_index] = clut_index
colorpixel(row_index, col_index, clut_index, square_length)
index_input = input("Please input another row number, a column number, and a color number separated by spaces, then hit Enter. To finish coloring, hit Enter without entering any values: ")
#prints the bitmap array
print(bitmap)
done()
CodePudding user response:
I believe the problem is here:
for row in range(rows):
bitmap.append(rowline)
Every row in the matrix is the same list, we need to make them unique lists:
for row in range(rows):
bitmap.append(list(rowline)) # force a copy
This is not a Python turtle issue, but rather a generic Python programming issue.