pythonarraysloopswordsearch

-Python- WordSearch: Placing words to handle overlap properly


I have been working on a program that will run from command line that reads a file with words in it, and then generate a WordSearch game from those words.

I have defined several functions, but the one I am having the issue with is the word_place function. This function is supposed to take my grid or 2D array that is originally filled with periods:

width = 20
height = 20
grid = [['.' for i in range(0,width)] for j in range(0,height)]

And places the words randomly either backwards or forwards, vertically, horizontally, or diagonally, and in a random spot as long as it fits the width and height of the puzzle.

def word_place(word,grid):
global width, height

word = random.choice([word,word[::-1]])

direction = random.choice([[1,0],[0,1],[1,1]])
xsize = width if direction[0] == 0 else width - len(word)
ysize = height if direction[1] == 0 else height - len(word)

x = random.randrange(0,xsize)
y = random.randrange(0,ysize)

for i in range(0,len(word)):
    grid[y + direction[1]*i][x + direction[0]*i] = word[i]

return grid

As you can probably see though, if the words happen to intersect, whichever word was placed last will write over the character of the word it intersects.

What I want the program to do is to check each "coordinate" of my 2D array.

For example, say the first letter of the word happens to be at grid[5][8], it should check and see if there is a period in that position. If so then it will check the next square and so on.

Basically if the letter of the word I'm trying to place is == to a . or whatever letter is already in the index then it is okay to place, otherwise it should scrap that, and give the word a new starting coordinate and try again.

Sorry if this is long or unclear.. let me know if you need more information!


Solution

  • This may be a place for a for-else construct:

    while True:
        x = random.randrange(0,xsize)
        y = random.randrange(0,ysize)
    
        for i in range(0,len(word)):
            if grid[y + direction[1]*i][x + direction[0]*i] not in ['.',word[i]]:
                break
        else:
            break
    for i in range(0,len(word)):
        grid[y + direction[1]*i][x + direction[0]*i] = word[i]
    

    this continues changing x and y until the initial for loop runs without breaking. The first for loop will break any time that a value in the grid is not either a free space or the letter that it would need to be (word[i]).