I get the feeling I'm fundamentally misunderstanding something about the way in which Haskell is written. My code is intended to serve as an evaluation function for a primitive AI for the game Othello. Essentially I want my code to cycle through a list of pieces, each piece represented by a tuple composed of a Position (Int, Int) and a Col (Colour, either Black or White), and given a prospective move identify how good the move is.
The way I'm judging the value of a move is based on a few factors:
- Is there a piece on the board in a straight line from the intended position of the same colour?
- If the previous requirement is true, how many pieces of the opposite colour are inbetween those two pieces?
Since Haskell has no loop structures it seems like I need to implement this recursively, as such my code is as follows:
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
However, this code does not compile. I get a "parse error on "if"" on the first line that reads:
if (tail(pieces) == []) then
This leads me to believe that something fundamental about the way in which I've structured this code is faulty. I would like to clarify I'm NOT looking for someone to solve the implementation for me, only for someone to explain to me how my implementation is flawed, and a general guide on how I can implement recursion within the correct way to structure my code.
If you've read this far thank you, and I look forward to reading your replies.
Aucun commentaire:
Enregistrer un commentaire