When generating a letter soup with random letters like putting the words without matching?

1

I think I was explicit. The size of the grid is given in a .txt file in the first line and then the words that I should put in the generated font soup. The problem is that when I make the soup the words coincide in their positions which is not what is intended. Someone can help me? The function that matters is the word_name. I just put the rest of the code to understand it better. Here I leave the code:

import random
import string
fi=input('Insira o nome do ficheiro de entrada(entry.txt): ')
fo=input('Insira o nome do ficheiro de saida(.txt): ')
tamanho_grelha=[]
words=[]
matriz=[]

def ler_ficheiro(arquivo):
       file=open(arquivo)

       n=file.readline()
       lista=n.split()
       lista=list(map(int,lista))  #coloca o tamanho da sopa em uma lista
       for i in lista:
           tamanho_grelha.append(i)

       for line in file:
          line=line.replace("\n","") #coloca as palavras em uma lista
          words.append(line)
       file.close()


 def gerar_grelha():
       n=tamanho_grelha[0]
       p=tamanho_grelha[1]
       for i in range(n):
          matriz.append([])
          # EDIÇÂO: identei o loop abaixo - 
          # creio que havia uma erro de identação aqui
          # ao colar o programa no stackoverflow
          for j in range(p):
              matriz[i].append(random.choice(string.ascii_lowercase)) #escolhe uma letras aleatorias para a  matriz

def por_palavra(palavra,grelha,w):
      n=tamanho_grelha[0]
      p=tamanho_grelha[1]
      palavra = random.choice([palavra,palavra[::-1]]) #escolher se a palavra será invertida ou não
                #horizontal,vertical,diagonal
      d = random.choice([[1,0],[0,1],[1,1]]) #decide o sentido da palavra

      xtamanho = n  if d[0] == 0 else n  - len(palavra)
      ytamanho = p if d[1] == 0 else p - len(palavra)

      x= random.randrange(0,xtamanho)
      y= random.randrange(0,ytamanho)  #posição

     for i in range(0,len(palavra)):

           grelha[y+d[1]*i][x+d[0]*i]=palavra[i]
           return grelha
def escreve_ficheiro(in_file,out_file):
   leitura=open(in_file)
   escrita=open(out_file,'w')
   ler_ficheiro(in_file)
   gerar_grelha()
   escrita.write(str(len(words)) + "\n")
   for i in words:
       escrita.write(i + "\n")
   for palavra in words:
       grelha=por_palavra(palavra,matriz)
    l="\n".join(map(lambda row:"".join(row),grelha))
   escrita.write(l)

    leitura.close()
    escrita.close()


escreve_ficheiro(fi,fo) #chama a função

For example, this output:

             spepvawio  
             ofclrmhhh  
             cclvlaijl  
             rirosrtne  
             finaiegom  
             whrzzldur  
             fyceaonee  
             ywuygelbv  
             clsalilyg     
    
asked by anonymous 18.01.2017 / 21:34

2 answers

1

As you have already noticed, it is not possible (or very difficult, but possible) for the "por_palavra" function to see if you are overwriting a word already in place with the information in the grid if it is already filled. Another problem in the "por_palavra" function is that if the word does not fit in the chosen position and direction, it can not abort and try to get another position.

The idea I had solves both problems at the same time: pass the created grid, but "empty" (that is, with spaces or a marker in place of random letters) while placing the words - this way, in the case of the word to be over another letter is just to restart the process of "por_palavra" for the same word. After the words are placed, simply fill in the rest of the grid, changing only the empty positions by random letters -

I've rewritten the required functions - you'll need small adaptations in your program to use them - but basically call the "create_grid" function before several calls to "for_word" and finally the function "fill_grid ". Its function "gera_grelha" ceases to exist.

def cria_grelha(tamanho_grelha):
    # Python tem desdobramento de sequências no assignment
    # essa única linha atribui os valores para n e p
    n, p = tamanho_grelha
    matriz = [ [" " for j in range(p)]  for i in range(n) ]  
    return matriz


def por_palavra_interno(tamanho_grelha, palavra,grelha):
      n, p = tamanho_grelha
      palavra = random.choice([palavra,palavra[::-1]]) #escolher se a palavra será invertida ou não
                #horizontal,vertical,diagonal
      d = random.choice([[1,0],[0,1],[1,1]]) #decide o sentido da palavra

      xtamanho = n  if d[0] == 0 else n  - len(palavra)
      ytamanho = p if d[1] == 0 else p - len(palavra)

      x= random.randrange(0,xtamanho)
      y= random.randrange(0,ytamanho)  #posição

      for i, letra in enumerate(palavra):
           char = grelha[y+d[1]*i][x+d[0]*i]
           if char != " " and char != letra:
               # Se atingiu um espaço já preenchido - reiniciar o processo.
               # (A segunda condição permite que palavras que se 
               # cruzam com letras repetidas sejam criadas)
               return False
           grelha[y+d[1]*i][x+d[0]*i] letra
       return True


def por_palavra(tamanho_grelha, palavra, grelha):
    contador = 0
    while not por_palavra_interno(tamanho_grelha, palavra, grelha):
        contador += 1
        if contador > 1000:
            raise ValueError("Não foi possível posicionar a palavra {}".format(palavra))


def preenche_grelha(tamanho_grelha, grelha):
    for i in range(tamanho_grelha[0]):
        for j in range(tamanho_grelha[1]):
            if grelha[i][j] == " ":
                grelha[i][j]= random.choice(string.ascii_lowercase)

( note ): There were some misidentifications in your code, the Python program was not even valid as it was, and one of the indentations generated a logic error. - If you created the grid, you should have the program with the correct indentation there. Take a lot of care with indentation in Python - if your editor is shuffling the indentation, change the editor if it is in Windows try the sublimetext or notepad ++ - No try programming in Python without an editor with proper indentation support

)

    
19.01.2017 / 05:31
-1

Hello friend, I do not know if I understood your question correctly, but from what I understand, you want to read a file and from it generate a set of random words and add them in a matrix without any repetition of words added in the lines. If this is the case, you can create the word as a list and then check if the value already exists in the array before allocating, for example:

palavra = ['a', 'b', 'c']
if not valor in matriz:
    lista.append(valor)    

Now to do this, you would have to change or adjust some things in your code, type how you are adding the values in your array:

grelha[y+d[1]*i][x+d[0]*i]=palavra[i]

I do not know if it's feasible for you or if this idea makes sense to your problem, but I hope I have helped.

    
19.01.2017 / 02:43