Prolog中的填字游戏生成器

时间:2019-04-20 19:27:39

标签: prolog crossword

我决定写一个填字游戏生成器:crossword(Rows, Columns, WordList, CrosswordGrid)

预期用途:

?- crossword(6, 6, [apple, pear, grape, rum], C).
C = [
  [a, _, g, _, _, r],
  [p, _, r, _, _, u],
  [p, e, a, r, _, m],
  [l, _, p, _, _, _],
  [e, _, e, _, _, _],
  [_, _, _, _, _, _]
]

下面是旨在实现正确填字游戏的Prolog程序。通过一次在填字游戏网格中填充一个水平或垂直单词来工作。

% Prolog implementation: SWI-Prolog.
:- use_module(library(clpfd)).  % Imports transpose/2 for transposing a matrix.

% Generates a matrix (Grid) with the specified number of rows and columns.
matrix(Rows, Cols, Grid) :-
    length(Grid, Rows),
    maplist(length_list(Cols), Grid).

% Like length/2, but with parameters in reverse order.
length_list(Length, List) :- length(List, Length).

% Xs is a sublist of AsXsBs.
% e.g. sublist([3,4], [1,2,3,4,5]).
sublist(Xs, AsXsBs) :-
    append(AsXs, _, AsXsBs),
    append(_, Xs, AsXs).

% Place a word HORIZONTALLY in the grid.
place(Word, Grid) :-
    atom_chars(Word, Chars),
    member(Row, Grid),
    sublist(Chars, Row).

% Place a word VERTICALLY in the grid.
place(Word, Grid) :-
    atom_chars(Word, Chars),
    transpose(Grid, TGrid),
    member(TRow, TGrid),
    sublist(Chars, TRow).

crossword(Rows, Cols, [W|Ws], Grid) :-
    matrix(Rows, Cols, Grid),
    place(W, Grid),  % Place the first word.
    crossword(Rows, Cols, Ws, Grid).  % Place the other words.
crossword(_,_,[],_).

上面的程序在生成包含指定单词的网格时效果很好。但是,某些解决方案不是有效的填字游戏:

C = [
  [p, e, a, r, _, _],
  [r, u, m, _, _, _],
  [a, p, p, l, e, _],
  [g, r, a, p, e, _],
  [_, _, _, _, _, _],
  [_, _, _, _, _, _]
];

C = [
  [p, e, a, r, u, m],
  [a, p, p, l, e, _],
  [g, r, a, p, e, _],
  [_, _, _, _, _, _],
  [_, _, _, _, _, _],
  [_, _, _, _, _, _]
]

我现在意识到了这一点:在网格中生成一行时,程序必须考虑上下一行中的字母,因此该行中的单词不会与相邻行中的单词“冲突”。 >

但是,由于我是Prolog的初学者,因此我不知道如何解决该问题,仅将其用于解决简单的教科书练习。该程序标志着我理解Prolog的巨大飞跃。

所以问题是:

  1. 我需要在程序中进行哪些更改以消除错误的解决方案?提示是最欢迎的。

  2. 有没有更好的方法来表示填字游戏网格?

0 个答案:

没有答案