Skip to main content
3 of 3
deleted 33 characters in body; edited tags; edited title
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Word search generator in Python

I have made a word-search-generator with Python 3 and it works perfectly. Can you please tell me if what I have done is done in the right way? Also, please tell me how the code is performance-wise. I have tried my best to write helpful comments.

import random
from copy import deepcopy
def make(row,column):
    return [['_' for _ in range(column)] for a in range(row)] # Generates a empty array of specified width(column) and height(row)
def add_horizontally(word,array,row,column,backwards=False):
    arr = deepcopy(array) #Copy the array because we may make unwanted mutations
    word = word[::-1] if backwards else word #If backwards is true reverse the word
    somearr = list(word)
    for c in somearr:
        if((arr[row][column] != '_') & (arr[row][column] != c)): #If there already exists a character and it is not same as c then
            raise Exception("Oh the letter is already there") #Throw a error
        else:
            arr[row][column] = c #Else add the letter to the correct row and column
            column += 1 #Increase column by 1
    return arr
def add_vertically(word,array,row,column,backwards=False): #Same as add horizontally except it increases row by 1
    arr = deepcopy(array)
    word = word[::-1] if backwards else word
    somearr = list(word)
    for c in somearr:
        if((arr[row][column] != '_') &  (arr[row][column] != c)):
            raise Exception("Oh the letter is already there")
        else:
            arr[row][column] = c
            row += 1
    return arr
def add_diagonally(word,array,row,column,backwards=False): #Same as add_vertically except increase both row and cloumn by 1
    arr = deepcopy(array)
    word = word[::-1] if backwards else word
    somearr = list(word)
    for c in somearr:
        if((arr[row][column] != '_') & (arr[row][column] != c)):
            raise Exception("Oh the letter is already there")
        else:
            arr[row][column] = c
            row += 1
            column += 1
    return arr
def random_condition(rows,columns,backwards=True,diagonals=True): # Generate a random condition for the placement of word
    row = random.randint(0,rows)
    column = random.randint(0,columns)
    backward = backwards if not backwards else [True,False][random.randint(0,1)] #If backwards is false let it remain so else generate a random value
    diagonal = diagonals if not diagonals else [True,False][random.randint(0,1)] #Same as above
    return (row,column,backward,diagonal)
def check(condition,word): # Check ifthe provided condition is fitting i.e. there should be no out of index problem
    diagonal = condition[0][3]
    row_start = condition[0][0]
    column_start = condition[0][1]
    rows = condition[1]
    columns = condition[2]
    vertical = condition[3]
    if(diagonal):
        if(((rows-row_start) >= len(word)) & ((columns - column_start) >= len(word))):
            return True
        else:
            return False
    if(vertical):
        if(rows-row_start>len(word)):
            return True
        else:
            return False
    else:
        if(columns - column_start>len(word)):
            return True
        else:
            return False
def random_alpha(): # Returns a random alphabet
    return 'abcdefghijklmnopqrstuvwxyz'[random.randint(0,25)]
def randomize(arr): # After the grid is made fill the remaining places with randome characters
    return [[m if m!='_' else random_alpha() for m in a] for a in arr]
def generate(row,column,word_list,backwards=True,diagonal=True): # Uses all the above methods to make array
    if((max(len(w) for w in word_list) > row) | (max(len(w) for w in word_list) > column)): #If the word is larger than row or column length than return 'wrong'.
        return ('wrong',)
    else:
        pass
    array = make(row,column)
    row -= 1 # Because indexing starts at 0!
    column -= 1 # Because indexing starts at 0!!
    for word in word_list:
        i = True
        while(i):
            vertical = False
            conditions = random_condition(row,column,backwards=backwards,diagonals=diagonal)
            if(not conditions[3]): # If diagonal is false
                vertical = [True,False][random.randint(0,1)]
            if (check((conditions,row,column,vertical),word)):
                if(conditions[3]): # If diagonal is true 
                    try: # We may throw a error
                        array = deepcopy(add_diagonally(word,array,conditions[0],conditions[1],conditions[2]))
                        i = False
                    except Exception:
                        pass
                elif(vertical):
                    try:
                        array = deepcopy(add_vertically(word,array,conditions[0],conditions[1],conditions[2]))
                        i = False  
                    except Exception:
                        pass    
                else :
                    try:
                        array = deepcopy(add_horizontally(word,array,conditions[0],conditions[1],conditions[2]))
                        i = False
                    except Exception:
                        pass
    return randomize(array) # Fill with random characters
def text(arr): # Convert given array to text  
    str = ''
    for row in arr:
        for word in row:
            str += word + ' '
        str += '\n'
    return str
open('test.txt','w').write(text(generate(15,15,['Lord','Voldemort','likes','penpineapple','applepen']))) # To test it!

This is what I get by changing line return randomize(array) to return array:

_ _ _ _ _ _ _ _ d r o L _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ a p p l e p e n _ _ _ _ _ _
_ V _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ o _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ l _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ d _ _ _ _ _ _ _ _ _ _
e l p p a e n i p n e p _ _ _
_ _ _ _ _ _ m _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ o _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ r _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ t _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
s e k i l _ _ _ _ _ _ _ _ _ _

And on randomizing it:

s u n e p e l p p a t l e s n
j d l p p s s y n y f w l i j
m b p z n y q h y l m y p w s
a f x f n a j o q e l t p p j
d g o m p r i c t d f j a q d
r g t v l V n j c l k x e f y
o z d r v g o p t h o a n f a
L u g e c s b l v w g b i f l
i l l i k e s q d r z s p p l
s b k g y g c e x e f y n y g
p b c h u k d l b w m e e o h
q a q k h c m h i c c o p h z
h k w g u c l r m c h j r g g
k o v g k n w x y z d j e t x
e b n d x z q d z b w y z p k