алгоритм Open Knight's Tour (с возвратом) в smlnj

Мне нужно написать код SML, чтобы решить задачу рыцарского тура при возврате. Шахматный конь должен пробежать всю шахматную доску (размер: NxN) и должен посетить каждую клетку ровно один раз (нет необходимости возвращаться в первую клетку в конце).

Я уже написал все функции для создания пустой доски, для установки или получения квадратов на доске, для получения списка возможных следующих ходов коня. Но я понятия не имею, как написать рекурсивную функцию на SML (я знаю, как написать этот алгоритм на C, но не на SML).

Алгоритм на C для шахматной доски 8x8

dl and dr are array : (delta to calculate next moves)   
dl = [-2,-2, -1, 1, 2,  2, 1, -1]  
dr = [-1, 1,  2, 2, 1, -1,-2, -2]


    bool backtracking(int** board, int k/*current step*/, int line, int row, int* dl, int* dr)
    {
    bool success = false;
    int way = 0;
    do{
         way++;
         int new_line = line + dl[way];
         int new_row = row + dr[way];

    if(legal_move(board, new_line, new_row))
    {
        setBoard(board,new_line, new_row,k); //write the current step number k in board
            if(k<64)
            {
                    success = backtracking(board, k+1, new_line, new_row, dl, dc);
                    if(!success)
                    {
                            setBoard(board,new_line, new_row,0);
                    }   
            }
            else
                    success = true;
    }
    }
    while(!(success || way = 8));
    return success;
    }

person Arie    schedule 12.04.2011    source источник
comment
Если вы знаете, как написать это на C, напишите / вставьте C, и мы поможем вам преобразовать его в SML.   -  person Robin Green    schedule 12.04.2011
comment
Я отредактировал свой вопрос из-за ограничений веб-сайта ... (я не могу ответить на свой вопрос в течение 24 часов, и он был слишком большим для комментария)   -  person Arie    schedule 12.04.2011
comment
Что ж, это подходящее место для его размещения - вы не должны публиковать обновления на свой вопрос в качестве ответа, а комментарии не могут содержать большие блоки кода.   -  person Robin Green    schedule 12.04.2011
comment
Ok. Я только что отредактировал условие while ... Я перевернул его.   -  person Arie    schedule 12.04.2011
comment
Думаешь, у тебя будет время мне помочь?   -  person Arie    schedule 13.04.2011


Ответы (1)


Не думайте как C! Это мерзкий образ мышления! Разработка вашего алгоритма на языке C / imperative никогда не поможет. Вам нужно сделать домашнее задание и научиться правильно думать.

Как вы будете разрабатывать программу? Он должен хранить состояние, и каждое состояние должно записывать, куда пошел рыцарь. Создайте свое состояние как кортеж доски (список пройденных квадратов записи bool) и ходов (список (int, int)). Итак, вызовы функций будут выглядеть примерно так:

exception Back
fun iter (state, []) = 
      if boardFull state then state else raise Back
  | iter (state, next::ns) =
      iter (next, states next) handle Back => iter (state, ns)

fun states (board, ps) =
    <a move is a pair (int, int); write out the list of eight moves; map a next fn down the list, and filter it by legal moves> (2 or 3 lines of code for you to write)
fun boardFull (board, pos::ps) = <foldl twice to apply the 'and' fn over the whole board> (1 line of code for you to write)
person Nicholas Wilson    schedule 08.05.2011