2日ほどこねくり回してようやくゲーム画面に相当するものができた。乱数の扱いが、最初いまひとつピンとこなかったのだけれど、ようやく把握…できたと思う。
以下、コード。
import Graphics.UI.GLUT import Control.Exception import System.Exit import System.Random import Data.IORef main = do board <- (makeBoard >>= newIORef) getArgsAndInitialize createWindow "Sample" initialDisplayMode $= [RGBAMode] displayCallback $= display board keyboardMouseCallback $= Just keyboardMouse clearColor $= Color4 0.0 0.0 0.2 0.2 mainLoop makeBoard = do g <- getStdGen let colors = map (\ n -> colorList !! n) $ randomRs (0, length colorList - 1) g return $ take 10 $ getTable 10 colors where getTable n colors = column : getTable n rest where (column, rest) = splitAt n colors blue = Color3 (0.0::Double) 0.0 1.0 green = Color3 (0.0::Double) 1.0 0.0 cyan = Color3 (0.0::Double) 1.0 1.0 red = Color3 (1.0::Double) 0.0 0.0 magenta = Color3 (1.0::Double) 0.0 1.0 yellow = Color3 (1.0::Double) 1.0 0.0 white = Color3 (1.0::Double) 1.0 1.0 colorList = [blue, green, cyan, red, magenta, yellow, white] keyboardMouse key keystate modifiers position = case key of Char 'q' -> throwIO $ ExitException ExitSuccess _ -> return () display points = do clear [ColorBuffer] ps <- readIORef points let posList = map (? n -> n / 10) [-9, -7..] mapM_ drawPoint $ concat $ zipWith (\ x column -> zipWith (\ y c -> (x, y, c)) posList column) posList ps flush drawPoint (x, y, c) = do color c renderPrimitive Polygon $ mapM_ vertex [ Vertex3 (-0.07 + x) (-0.07 + y) 0.0, Vertex3 ( 0.00 + x) (-0.10 + y) 0.0, Vertex3 ( 0.07 + x) (-0.07 + y) 0.0, Vertex3 ( 0.10 + x) ( 0.00 + y) 0.0, Vertex3 ( 0.07 + x) ( 0.07 + y) 0.0, Vertex3 ( 0.00 + x) ( 0.10 + y) 0.0, Vertex3 (-0.07 + x) ( 0.07 + y) 0.0, Vertex3 (-0.10 + x) ( 0.00 + y) (0.0 :: GLfloat) ]