Anonymous user
Generate random chess position: Difference between revisions
m
→{{header|Haskell}}
Line 568:
type ChessBoard = [(Square, Pos)]
data PieceRank = King | Queen | Rook | Bishop | Knight | Pawn
deriving (Enum, Bounded, Show, Eq, Ord)
data PieceColor = Black | White
deriving (Enum, Bounded, Show, Eq, Ord)
data Square = ChessPiece PieceRank PieceColor | EmptySquare
deriving (Eq, Ord)
Line 579:
instance Show Square where
show (ChessPiece King
show (ChessPiece Queen Black)
show (ChessPiece Rook
show (ChessPiece Bishop Black) = "♝"
show (ChessPiece Knight Black) = "♞"
show (ChessPiece Pawn
show (ChessPiece King
show (ChessPiece Queen White)
show (ChessPiece Rook
show (ChessPiece Bishop White) = "♗"
show (ChessPiece Knight White) = "♘"
show (ChessPiece Pawn
show EmptySquare = " "
instance Random PieceRank where
randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of
(x, g'') -> (toEnum x, g'')▼
random g = randomR (minBound, maxBound) g
instance Random PieceColor where
randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of
random g = randomR (minBound, maxBound) g
fullBoard :: PieceCount
fullBoard =
[ (ChessPiece King Black , 1)
, (ChessPiece Queen Black , 1)
, (ChessPiece Rook Black , 2)
, (ChessPiece Bishop Black, 2)
, (ChessPiece Knight Black, 2)
, (ChessPiece Pawn Black , 8)
, (ChessPiece King White , 1)
, (ChessPiece Queen White , 1)
, (ChessPiece Rook White , 2)
, (ChessPiece Bishop White, 2)
, (ChessPiece Knight White, 2)
, (ChessPiece Pawn White , 8)
, (EmptySquare , 32)
]
emptyBoard :: ChessBoard
emptyBoard = [ (EmptySquare, (x, y)) | x <- ['a' .. 'h'], y <- [1 .. 8] ]
replaceSquareByPos :: (Square, Pos) -> ChessBoard -> ChessBoard
replaceSquareByPos e@(s, p) = map (\
isPosOccupied :: Pos -> ChessBoard -> Bool
isPosOccupied p = occupied .
where
occupied _
isAdjacent :: Pos -> Pos -> Bool
Line 638 ⟶ 636:
let upOrDown = (pred y == y'' || succ y == y'')
leftOrRight = (pred x == x'' || succ x == x'')
in (x'' == x && upOrDown)
|| (pred x == x'' && upOrDown)
|| (succ x == x'' && upOrDown)
|| (leftOrRight && y == y'')
fen :: Square -> String
fen (ChessPiece King
fen (ChessPiece Queen Black)
fen (ChessPiece Rook
fen (ChessPiece Bishop Black) = "b"
fen (ChessPiece Knight Black) = "n"
fen (ChessPiece Pawn
fen (ChessPiece King
fen (ChessPiece Queen White)
fen (ChessPiece Rook
fen (ChessPiece Bishop White) = "B"
fen (ChessPiece Knight White) = "N"
fen (ChessPiece Pawn
boardSort :: (Square, Pos) -> (Square, Pos) -> Ordering
boardSort (_, (x, y)) (_, (x'', y'')) | y < y'' = GT
| y
| y
toFen :: ChessBoard -> String
toFen [] = " w - - 0 1" <> []
toFen b = scanRow (map fst $ take 8 b) 0
where
scanRow []
scanRow []
scanRow (x
scanRow (x : xs) n = show n <> nextPiece x xs
-- impure functions
randomPos :: ChessBoard -> IO Pos
randomPos b = pos >>= \p -> if isPosOccupied p b then randomPos b else pos
where
then randomPos b ▼
else pos ▼
▲ where pos = (,) <$> chr <*> num
▲ chr = getStdRandom $ randomR ('a','h')
randomPiece :: IO Square
randomPiece = ChessPiece <$> rank <*> color
where
where rank = getStdRandom random▼
rank
placeKings :: ChessBoard -> IO ChessBoard
placeKings b = do
p1 <- randomPos b
p2 <- randomPos b
if p1 `isAdjacent` p2 || p1 == p2
then placeKings b
else pure
$ replaceSquareByPos ((ChessPiece King Black), p2) b
)
placePawns :: ChessBoard -> IO ChessBoard
placePawns b = num >>= go b
where
go b'' 0 = pure b''▼
pos
pawn@(ChessPiece _ color) <- randomPawn
if
|| isPosOccupied
||
|| firstPos color
then go
else go (replaceSquareByPos (pawn, pos) b'') (pred n)
promoted Black = 1▼
firstPos White = 1
num
placeRemaining :: ChessBoard -> IO ChessBoard
placeRemaining b = do
n <- num (sum $ map snd remaining)
putStrLn $ "Placing " <> show n
<> " more random positions after placing 2 kings and "
<> (show $ totalPawns b) <> " pawns. "
go remaining b n
where
remaining
(\case
((ChessPiece King _), _) -> False▼
((ChessPiece Pawn
(EmptySquare
)
fullBoard
)
go _
piece
else go (consume piece
where
draw :: ChessBoard -> IO ()
Line 763 ⟶ 770:
showXAxis
line
mapM_
'a' -> putStr (show y
_ -> putStr (" | " <> show p)
)
sorted
showXAxis
Line 774 ⟶ 782:
-- mapM_ print $ sortBy (comparing fst) $ filter (\(s, _) -> s /= EmptySquare) b
where
line
▲ putStr " "
putStr " "
main :: IO ()
main = placeKings emptyBoard >>= placePawns >>= placeRemaining >>= draw</lang>
{{out}}
Run 1
|