Created
January 14, 2013 15:29
-
-
Save tamurashingo/4530793 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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