Skip to content

Instantly share code, notes, and snippets.

@tamurashingo
Created January 14, 2013 15:29
Show Gist options
  • Save tamurashingo/4530793 to your computer and use it in GitHub Desktop.
Save tamurashingo/4530793 to your computer and use it in GitHub Desktop.
-- Haskell練習
-- 五目並べ
-- 石の定義。
data Ishi = Blank
| Black
| White
deriving (Eq)
instance Show Ishi where
show Blank = "_"
show Black = "O"
show White = "X"
-- ゲーム盤の定義。
data Board a = Board [[a]] deriving (Show)
getWidth :: Board Ishi -> Int
getWidth (Board a) = length (head a)
getHeight :: Board Ishi -> Int
getHeight (Board a) = length a
-- 初期のゲーム盤を作成する。
makeEmptyBoard :: Int -> Int -> Board Ishi
makeEmptyBoard width height = Board (replicate height (replicate width Blank))
-- 指定した場所の石を取得する。
getIshi :: Board Ishi -> Int -> Int -> Ishi
getIshi (Board a) x y = a !! y !! x
-- 置けるかチェック。
isBlank :: Board Ishi -> Int -> Int -> Bool
isBlank board x y = getIshi board x y == Blank
-- 石を置く。
putIshi :: Board Ishi -> Int -> Int -> Ishi -> Board Ishi
putIshi (Board a) x y ishi =
let
row = take x (a !! y) ++ [ishi] ++ drop (x+1) (a !! y)
in
Board (take y a ++ [row] ++ drop (y+1) a)
-- 置いた場所を通る行、列、左上から右下、右上から左下の石のリストを生成する。
getList :: Board Ishi -> Int -> Int -> [[Ishi]]
getList (Board a) x y =
let
-- 行
getRow = a !! y
-- 列
getCol = map (!! x) a
-- ゲーム盤のサイズを取得しておく。
width = getWidth (Board a)
height = getHeight (Board a)
-- 左上、右上の座標を取得
startUL | x < y = (0, y-x)
| otherwise = (x-y, 0)
startUR | width-1-x < y = (width-1, y-(width-1-x))
| otherwise = (x+y, 0)
-- 左上(UpLeft)から右下(DownRight)の石をリスト化
getULtoDR x y lst | x < width && y < height = getULtoDR (x+1) (y+1) (lst ++ [(getIshi (Board a) x y)])
| otherwise = lst
-- 右上(UpRight)から左下(DownLeft)の石をリスト化
getURtoDL x y lst | 0 <= x && y < height = getURtoDL (x-1) (y+1) (lst ++ [(getIshi (Board a) x y)])
| otherwise = lst
in
-- リストのリスト
[getRow,
getCol,
getULtoDR (fst startUL) (snd startUL) [],
getURtoDL (fst startUR) (snd startUR) []]
-- 上で生成したリストの中に、指定した石が5個並んでいたらTrueが返る。
checkFive :: [[Ishi]] -> Ishi -> Bool
checkFive a ishi | a == [] = False
| otherwise =
let
checkLoop lst cnt | cnt == 5 = True
| lst == [] = checkFive (tail a) ishi
| head lst == ishi = checkLoop (tail lst) (cnt+1)
| otherwise = checkLoop (tail lst) 0
in
checkLoop (head a) 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment