I have previous experience with Java and web development, but have recently been learning Python. To help me learn this language, I have been working on creating a program that will solve the Dragon Fjord A-Puzzle-A-Day calendar puzzle (https://www.dragonfjord.com/product/a-puzzle-a-day/)). I want the program to be run in command line. So far I have made the board and pieces, but am struggling with implementing a function to place a piece. I would love some feedback on the place() function in the following code, thanks!
import numpy as np
#numpy
#make the empty board
board = np.zeros((7,7))
board[0:2,6]=9
board[6,4:7]=9
#make a dictionary with a numpy array and a boolean stating if the piece is used or not
pieces = {1: [np.array([[1,0],[1,0],[1,1],[0,1]]),0],
2: [np.array([[0,0,2],[2,2,2],[2,0,0]]),0],
3: [np.array([[3,3,3],[3,0,0],[3,0,0]]),0],
4: [np.array([[4,0],[4,4],[4,0],[4,0]]),0],
5: [np.array([[5,5,5],[5,5,5]]),0],
6: [np.array([[6,6],[6,6],[6,0]]),0],
7: [np.array([[0,0,0,7],[7,7,7,7]]),0],
8: [np.array([[8,0,8],[8,8,8]]),0]}
#place a piece on the board
def place(p,x,y):
def overlap(p,x,y):
for i in range(0,pieces[p][0].size):
for j in range(0,pieces[p][0][0].size):
print("j is {0}".format(j))
if board[x+i,y+j] != 0 and pieces[p][0][i,j] != 0:
return True
return False
#check if piece is used and it would overlap
if pieces[p][1] != 1 and not overlap(p,x,y):
for i in range(0,pieces[p][0].size):
for j in range(0,pieces[p][0][0].size):
#index across the rows and columns replacing
board[x+i,y+j]=pieces[p][0][i,j]
pieces[p][1] = 1
#rotate a piece left
def rotatel(p):
pieces[p] = np.rot90(pieces[p])
#rotate a piece right
#this function is kinda arbitrary but im gonna keep it for now incase it comes in handy later
def rotater(p):
rotatel(p)
rotatel(p)
rotatel(p)
#testing placing
print(board)
place(1,1,1)
print(board)
My idea was to use numpy, as it seemed like a good tool for making and changing arrays. I think that a list of lists could also be used, with very similar results. The main problem shouldn't be with numpy implementation, but appears to be an index error.
Here is the error that is thrown if it helps at all:
line 24, in overlap
if board[x+i,y+j] != 0 and pieces[p][0][i,j] != 0:
IndexError: index 7 is out of bounds for axis 0 with size 7
board
has the shape (7,7). By using board[x+i,y+j]
, you get an error, if either x+i
or y+j
are larger or equal to 7 (Python arrays start at index 0). In your case, the error is raised, because at that point x
is 1 and i
is 6, thus trying to access index 7, which does not exist.
I think the main issue here is that you used the size
parameter incorrectly when using pieces[p][0].size
. The array you access via pieces[p][0]
is (for p = 1, as in your example):
[[1,0],[1,0],[1,1],[0,1]]
However, the size
of this array is not 4, as I think you assumed, but the total number of elements (here: 8). So in your for-loop, i
goes up to 7, with the crash happening already at i=6. To get the number of sub-arrays, you can use pieces[p][0].shape[0]
.
shape
gives you the tuple (4,2)
of which you then access the first value. Note that you have to change this twice in your code!
With that change, the code runs through, but your current implementation will still fail when trying to use place()
for larger values of x
and y
as you then again try to access board
with indices 7 or larger. You should check if that part of the piece would be outside of your board before trying to access the board at that index.