Just a note to let you know: it's virtually impossible to use a linked-list-of-linked-list or two-dimensional-array board representation as the basis of a serious AI. It's just too inefficient (see <a href="http://www.cis.uab.edu/hyatt/boardrep.html">http://www.cis.uab.edu/hyatt/boardrep.html</a> for some other options).<br>
<br>That said, if you want to use this as the basis of being able to play through games or something, it's great.<br><br><div class="gmail_quote">On Wed, Oct 28, 2009 at 2:11 AM, Joe Fredette <span dir="ltr"><<a href="mailto:jfredett@gmail.com">jfredett@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Awesome, have you cabal-ized it? If not, it's pretty simple (look up 'cabal' on the haskellwiki). Then you can upload it to hackage to be toyed with.<br>
<br>
One thing that might be a cool direction to go w/ your project (sounds like you intend to make a chess playing program, this is somewhat orthogonal to that goal) is to build a "playback" machine. For instance, I play chess with people by email on a fairly regular basis. Specifically, we submit moves to one another in semi-standard[1] algebraic chess notation. So I might see a game like:<br>
<br>
<br>
1. Kb3 e5<br>
2. d3 d6<br>
...<br>
n. a4->a5 e6->d7<br>
<br>
Where the first move is White, moving his knight to B-3, then black moves his pawn from e7 to e5. etc.<br>
a move followed by a * is a check, followed by two stars is a mate. etc. You can poke at the wiki page for ACN for the appropriate syntax. My suggestion is that- often times we go many days in between moves, and so I don't keep track (in my head) of the last few moves he made, which can sometimes indicate weak points/general strategies. It would be _really_ nice to be able to replay old board positions at will, given this ACN notation of the game. Might be a nice (simple) use case for Parsec, and I imagine that most chess engines will have something like that (assuming they operate on STDIN/OUT) -- even if the syntax may be different. This will give you the "backend" to plug it onto anyway.<br>
<br>
Anywho, good luck with your project, it looks nice!<br>
<br>
/Joe<br>
<br>
PS, Just noticed the little function you use to display the board (and stuff). You may want to poke around the 2d Pretty printers on hackage, they may make it easier/more extensible to render the board. Also, `cout`? Someone's got a bit o' the ++ in 'em... :)<br>
<br>
<br>
<br>
[1] Okay, we mostly make it up, but it's _consistently_ arbitrary...<div><div></div><div class="h5"><br>
<br>
On Oct 28, 2009, at 1:56 AM, iæfai wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
I have just recently finished a 'ChessBoard' module that is meant to represent a chess board. I could use some opinions and/or suggestions on the module.<br>
<br>
To give an example of how this can be used right now, and was my immediate goal, you can do this:<br>
<br>
*ChessBoard> putStr $ cout defaultBoard<br>
+----+----+----+----+----+----+----+----+<br>
| RB | NB | BB | QB | KB | BB | NB | RB |<br>
+----+----+----+----+----+----+----+----+<br>
| PB | PB | PB | PB | PB | PB | PB | PB |<br>
+----+----+----+----+----+----+----+----+<br>
| | | | | | | | |<br>
+----+----+----+----+----+----+----+----+<br>
| | | | | | | | |<br>
+----+----+----+----+----+----+----+----+<br>
| | | | | | | | |<br>
+----+----+----+----+----+----+----+----+<br>
| | | | | | | | |<br>
+----+----+----+----+----+----+----+----+<br>
| PW | PW | PW | PW | PW | PW | PW | PW |<br>
+----+----+----+----+----+----+----+----+<br>
| RW | NW | BW | QW | KW | BW | NW | RW |<br>
+----+----+----+----+----+----+----+----+<br>
<br>
I have not determined exactly how I will be making moves, but the logic will not be in my program. I am going to be using a chess engine in another process (I haven't chosen a chess engine yet that works on both windows and mac through stdin/stdout).<br>
<br>
The module itself follows, I appreciate any thoughts you might have.<br>
<br>
<br>
module ChessBoard where<br>
<br>
import Data.Sequence<br>
import Data.Foldable<br>
import Data.Maybe<br>
import Data.List as List<br>
<br>
class NiceLook a where<br>
cout :: a -> String<br>
<br>
<br>
data Piece = Bishop | Rook | Knight | King | Queen | Pawn | NoPiece<br>
deriving (Show, Eq)<br>
<br>
instance NiceLook Piece where<br>
cout Bishop = "B"<br>
cout Rook = "R"<br>
cout Knight = "N"<br>
cout Queen = "Q"<br>
cout Pawn = "P"<br>
cout King = "K"<br>
cout _ = " "<br>
<br>
data Colour = Black | White | NoColour<br>
deriving (Show, Eq)<br>
<br>
instance NiceLook Colour where<br>
cout Black = "B"<br>
cout White = "W"<br>
cout NoColour = " "<br>
<br>
-- error "..." might be useful<br>
<br>
data Square = Square Piece Colour<br>
deriving (Show, Eq)<br>
<br>
instance NiceLook (Square) where<br>
cout (Square p c) = (cout p) ++ (cout c)<br>
<br>
data Row = Row (Seq Square)<br>
deriving (Show, Eq)<br>
<br>
instance NiceLook (Row) where<br>
cout (Row s) = "|" ++ foldMap (\x -> " " ++ cout x ++ " |") s -- thnx Saizan<br>
<br>
makeRow n = case (List.length n) of<br>
8 -> Row (fromList n)<br>
_ -> error "Row is not 8 squares"<br>
<br>
makeColouredSquares n c = makeRow $ map makeSquare (zip n (replicate 8 c))<br>
<br>
makeSquare (n,c) = Square n c<br>
<br>
pawns = [Pawn, Pawn, Pawn, Pawn, Pawn, Pawn, Pawn, Pawn]<br>
back = [Rook, Knight, Bishop, Queen, King, Bishop, Knight, Rook]<br>
blank = [NoPiece, NoPiece, NoPiece, NoPiece, NoPiece, NoPiece, NoPiece, NoPiece]<br>
<br>
data Board = Board (Seq Row)<br>
deriving (Show, Eq)<br>
<br>
instance NiceLook (Board) where<br>
cout (Board c) = borderOutput ++ "\n" ++ (foldMap (\x -> cout x ++ "\n" ++ borderOutput ++ "\n") c)<br>
<br>
defaultBoard = Board (makeColouredSquares back Black <|<br>
makeColouredSquares pawns Black <|<br>
makeColouredSquares blank NoColour <|<br>
makeColouredSquares blank NoColour <|<br>
makeColouredSquares blank NoColour <|<br>
makeColouredSquares blank NoColour <|<br>
makeColouredSquares pawns White <|<br>
makeColouredSquares back White <| empty)<br>
<br>
<br>
borderOutput = "+" ++ (List.foldr1 (++) $ replicate 8 "----+")<br>
<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</blockquote>
<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/beginners" target="_blank">http://www.haskell.org/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br>