1

I create a boogle game, and I need to build a function that receives in input: the letter board (list of lists), the list of legal words and an integer n.

The function must return all n-length tracks of valid words. For example n = 3 then the function must return all the paths on the three-length board which are actually valid words.

I wrote a code that returns in a particular example one route out of three routes that must be returned.

Input:

board1 = [['Q', 'O', 'Q', 'Q'],
                 ['D', 'O', 'G', 'Q'],
                 ['Q', 'O', 'Q', 'Q'],
                 ['Q', 'Q', 'Q', 'Q']]
word_dict = {'DOG': True}
n = 3
board = Board(board1)
length_n_paths(3, board, word_dict)

My Output:

[((1, 0), (1, 1), (1, 2))]

Wanted Output:

[[(1, 0), (0, 1), (1, 2)], [(1, 0), (1, 1), (1, 2)], [(1, 0), (2, 1), (1, 2)]]

I used a combination, first I found all the possible combinations of letters of length n, then I went through a coordinate coordinate and checked if each coordinate is in a valid position according to the coordinate in front of it, and then I checked if the word coming out of the letter combination is a word from the word list. If so - I will return its path in a list with the other legal words paths.

my code:

direct_lst=['Up','Down','Right','Left','Up_right','Up_left','Down_right','Down_left']

class Board:
    def __init__(self, board):
        self.board = board


    def get_board_coordinate(self):

        cord_lst = []
        row = len(self.board)
        col = len(self.board[0])
        for i in range(row):
            for j in range(col):
                cord_lst.append((i, j))
        return cord_lst

    def possible_directions(self, coordinate, next_coordinate):




        y, x = coordinate
        directions_funcs = {
            # A dictionary that matches between a letter and the direction of the desired search
            'Up': (y - 1, x),
            'Down': (y + 1, x),
            'Right': (y, x + 1),
            'Left': (y, x - 1),
            'Up_right': (y - 1, x + 1),
            'Up_left': (y - 1, x - 1),
            'Down_right': (y + 1, x + 1),
            'Down_left': (y + 1, x + 1)
        }
        it_ok = False
        for direction in direct_lst:
            if directions_funcs[direction] == next_coordinate:
                it_ok = True
        return it_ok




def is_valid_path(board, path, words):

    word = board.board[path[0][0]][path[0][1]]
    board_coordinates = board.get_board_coordinate()
    for cord in range(len(path)-1):
        if path[cord] in board_coordinates and path[cord+1] in board_coordinates:
            if not board.possible_directions(path[cord], path[cord + 1]):
                return None
            else:
                word += board.board[path[cord + 1][0]][path[cord + 1][1]]
        else:
            return None
    if word in set(words):
        return word
import itertools

def create_dict(board, n):
    new_dict = dict()
    row = len(board.board)
    col = len(board.board[0])
    for i in range(row):
        for j in range(col):
            new_dict[(i, j)] = board.board[i][j]
        result_list = list(map(list, itertools.combinations(new_dict.items(), n)))
    return result_list



def coordinates_lst_and_str_lst(board, n):

    combine = create_dict(board, n)

    all_cord_dic = dict()
    for lst in combine:
        is_it_ok = True
        cord_lst = []
        str_l = ""
        for i in range(n):

            cord_lst.append(lst[i][0])
            str_l += lst[i][1]
            try:
                if not board.possible_directions(lst[i][0], lst[i + 1][0]):
                    is_it_ok = False
                    break
            except IndexError:
                break
        if is_it_ok:

            all_cord_dic[tuple(cord_lst)] = str_l
            all_cord_dic[tuple(cord_lst)[::-1]] = str_l[::-1]
    return all_cord_dic

def length_n_paths(n, board, words):
    possible_words = coordinates_lst_and_str_lst(board, n)

    my_dict = {key:val for key, val in possible_words.items() if val in words}
    return list(my_dict.keys())

I think the problem is in the combination but I dont know how to fix it. I would be happy for any help.

  • 1
    There appears to be no reason for the extra indentation on the first function. Also, please share how you call these functions with your example data. (edit the question, don't post a comment with the changes) – Grismar Jun 12 '22 at 23:36
  • You are right, hope more understandable now. –  Jun 12 '22 at 23:43
  • Your code contains syntax errors - as shared, `direct_lst` in `possible_directions` is not defined (probably needed to be `directions_funcs`?) and `result_list` might be undefined (although perhaps it isn't with the data you provided) – Grismar Jun 12 '22 at 23:48
  • I missed the list of directions, try now it should work –  Jun 12 '22 at 23:50
  • After debugging, it's apparent that the result `possible_words` does not contain the key `(1, 0), (0, 1), (1, 2)`, so that explains why it's not part of the answer - so the question becomes why doesn't the call to `coordinates_lst_and_str_lst()` generate that tuple (and the other 'missing' one) – Grismar Jun 12 '22 at 23:53
  • As I wrote in the question, the problem is probably with the combination, that the combination does not give all the possibilities. –  Jun 12 '22 at 23:58

1 Answers1

0

After debugging, it's apparent that the result possible_words does not contain the key (1, 0), (0, 1), (1, 2), so that explains why it's not part of the answer - so the question becomes why doesn't the call to coordinates_lst_and_str_lst() generate that tuple (and the other 'missing' one)

If you break after constructing combine in coordinates_lst_and_str_lst, you will find that [((1, 0), 'D'), ((0, 1), 'O'), ((1, 2), 'G')] is not in combine, this means coordinates_lst_and_str_lst can't find it as a solution.

So, the problem must be in create_dict, which apparently isn't creating all the legal moves.

And indeed, in create_dict, you use itertools.combinations(), which gives you all the unique combinations of n items from a collection, disregarding their order, but you care about the order.

So, you don't want itertools.combinations(new_dict.items(), n), you want itertools.permutations(new_dict.items(), n). Have a closer look at the difference between combinations and permutations (of size n).

Grismar
  • 27,561
  • 4
  • 31
  • 54