У меня возникает ощущение, что я в корне неправильно понимаю, как пишется Haskell. Мой код предназначен для использования в качестве оценочной функции для примитивного ИИ для игры Отелло. По сути, я хочу, чтобы мой код циклически проходил по списку фигур, каждый кусок представлен кортежем, состоящим из Position (Int, Int) и Col (Color, Black или White), и учитывая предполагаемый ход, определяйте, насколько хорош этот ход. is.
То, как я оцениваю ценность хода, основано на нескольких факторах:
- Есть ли на доске фигура по прямой линии от предполагаемой позиции одного цвета?
- Если предыдущее требование верно, сколько кусков противоположного цвета находится между этими двумя частями?
Так как Haskell не имеет l oop структуры, кажется, мне нужно реализовать это рекурсивно, так как мой код выглядит следующим образом:
eval :: Position -> [(Position, Col)] -> Col -> GameState -> Int -> Int
eval move pieces moveColour gameState score = do
let moveX = fst move
let moveY = snd move
let piece = head(pieces)
let pieceColour = snd piece
let pieceX = fst fst piece
let pieceY = snd fst piece
if (moveColour == pieceColour) then
if (moveX == pieceX) then
if (moveY > pieceY) then
let newScore = score + (countOtherColour 0 moveY pieceY (pieces gameState) moveColour 0)
--recurse
if (tail(pieces) == []) then
return newScore
else
return eval move tail(pieces) moveColour gameState newScore
else
let newScore = score + (countOtherColour 0 pieceY moveY (pieces gameState) moveColour 0)
--recurse
if (tail(pieces) == []) then
return newScore
else
return eval move tail(pieces) moveColour gameState newScore
else
if (moveY == pieceY) then
if (moveX > pieceX) then
let newScore = score + (countOtherColour 1 moveX pieceX (pieces gameState) moveColour 0)
--recurse
if (tail(pieces) == []) then
return newScore
else
return eval move tail(pieces) moveColour gameState newScore
else
let newScore = score + (countOtherColour 1 pieceX moveX (pieces gameState) moveColour 0)
--recurse
if (tail(pieces) == []) then
return newScore
else
return eval move tail(pieces) moveColour gameState newScore
else
--recurse
if (tail(pieces) == []) then
return score
else
return eval move tail(pieces) moveColour gameState score
else
--recurse
if (tail(pieces) == []) then
return score
else
return eval move tail(pieces) moveColour gameState score
countOtherColour :: Int -> Int -> Int -> [(Position, Col)] -> Col -> Int -> Int
countOtherColour xyFlag upper lower pieces turnColour score = do
--if xyFlag == 0 it's y aligned if 1 it's x aligned
let piece = head(pieces)
let pieceColour = other (snd piece)
let x = fst fst piece
let y = snd fst piece
if (pieceColour == turnColour) then
if (xyFlag == 0) then
if (upper > x && x > lower) then
let newScore = score+1
--recurse
if (tail(pieces) == []) then
return newScore
else
return countOtherColour xyFlag upper lower tail(pieces) turnColour newScore
else
--recurse
if (tail(pieces) == []) then
return score
else
return countOtherColour xyFlag upper lower tail(pieces) turnColour score
else
if (upper > y && y > lower) then
let newScore = score+1
--recurse
if (tail(pieces) == []) then
return newScore
else
return countOtherColour xyFlag upper lower tail(pieces) turnColour newScore
else
--recurse
if (tail(pieces) == []) then
return score
else
return countOtherColour xyFlag upper lower tail(pieces) turnColour score
else
--recurse
if (tail(pieces) == []) then
return score
else
return countOtherColour xyFlag upper lower tail(pieces) turnColour score
Однако этот код не компилируется. Я получаю «ошибку синтаксического анализа», если «» в первой строке, которая гласит:
if (tail(pieces) == []) then
Это приводит меня к мысли, что что-то фундаментальное в том, как я структурировал этот код, неверно. Я хотел бы уточнить, что я НЕ ищу кого-то, кто решит реализацию для меня, только для того, чтобы кто-то объяснил мне, как моя реализация имеет недостатки, и общее руководство о том, как я могу реализовать рекурсию внутри правильный способ структурировать мой код.
Если вы прочитали это далеко, спасибо, и я с нетерпением жду ваших ответов.