1

I would like to be able to draw something like a chess board using haskell and gloss.

In any other language I could do something like

for( i=0; i < 10; i++){
   for( j=0; j < 10; j++){
      drawSquare(radius, i, j)
    }
}

and that would be it, but I am new to haskell and I have no idea how this can be done. I am using Gloss and I am able to draw things manually, but I want to be able to create them procedurally not 1 by 1 until I draw 100 squares.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
lesolorzanov
  • 3,536
  • 8
  • 35
  • 53

2 Answers2

3

If you work inside the IO monad, you can use the same style. For instance

printSquares :: IO ()
printSquares =
   forM_ [0..9] $ \x ->
      forM_ [0..9] $ \y -> do
         putStrLn "Here's a square!"
         putStrLn ("Square(" ++ show x ++ ", " ++ show y ++ ")")
         -- add here the actual drawing Gloss commands

I'm not familiar with Gloss to suggest the actual drawing commands.


Update: it seems Gloss has a different interface than using IO as above. You probably need something like

squares :: Picture
squares = Pictures [ square x y | x<-[0..9], y<-[0..9] ]

square :: Float -> Float -> Picture
square x y = Polygon [(x,y), (x+1,y), (x+1,y+1), (x,y+1) ]
   -- even better: use rectangleWire and then translate
   -- rectangleUpperWire also seems useful
chi
  • 111,837
  • 3
  • 133
  • 218
  • Oh, I didnt know you could use the same style, I shall try. – lesolorzanov Feb 18 '17 at 13:30
  • 1
    @ZloySmiertniy Actually, I'm unsure about the Gloss interface. Maybe this answer is completely off the track. Maybe in Gloss you have to represent your image as a list/tree of shapes. – chi Feb 18 '17 at 13:32
  • yes it seems that I have to create a Picture, like in this post http://andrew.gibiansky.com/blog/haskell/haskell-gloss/ what I couldnt figure out was how to do a board of varaible length sizes and colors. the style "[ square x y | x<-[0..9], y<-[0..9] ]" is perfect. I am trying it right now – lesolorzanov Feb 18 '17 at 13:45
  • 1
    Got it! I did a Picture like this squares :: Picture squares = Pictures [ (translate x y $ rectangleSolid 1 1) | x<-[0,2..9], y<-[0,2..9] ] – lesolorzanov Feb 18 '17 at 13:57
3

While I am not familiar with the gloss library, you are probably looking for something like a list comprehension:

drawBoard :: Int -> Int -> IO ()
drawBoard w h = sequence_ [drawSquare radius i j | i <- [0 .. w], j <- [0 .. h]]
SDR
  • 69
  • 1
  • 8
  • I like this style for defining the range and asigning it to the variable. In gloss it seens that you have to draw a "Picture" to send to the render so it looks like this in the end: squares :: Picture squares = Pictures [ (translate x y $ rectangleSolid 1 1) | x<-[0,2..9], y<-[0,2..9] ] Thank you very much. – lesolorzanov Feb 18 '17 at 13:58
  • 1
    Nitpick: this needs a `sequence_` to be applied to the list of `IO` actions. – duplode Feb 18 '17 at 15:25