Search code examples
haskelllist-comprehension

Index of list of list and return the position of a element in list of list


I'm currently trying to create a simple connect 4 game where the board is defined as follow

> testboard :: [[Char]]
> testboard = [['B','B','B','B','B','B','B'],
>         ['B','B','B','B','B','B','B'],
>         ['B','B','B','B','B','B','B'],
>         ['B','B','B','X','X','B','B'],
>         ['B','B','O','O','X','B','B'],
>         ['B','O','O','X','X','X','B']]

I want to create a function that returns the highest row the column has not yet been filled By X or O eg if I put column 4 it should return the highest row that its not filled in column 4 is 3 (from top down)

here is my attempt

 getlist :: [[Char]] -> Char -> Int -> [[Char]]
 getlist list char col =  [[x | x <- z , x == char] | z <- list]

but this would only return the rows that have that specific value disregarding the column positions so I tried this

getlist list char col =  [[x | (i,x) <- zip [0..] list , i == col] | z <- list]

and I cant seem to get it to work please help


Solution

  • As chi notes in comments, you can extract the column you want with !!.

    Prelude> map (!! 3) testboard
    "BBBXOX"
    

    Now, if we use takeWhile (== 'B') we can get the leading blanks.

    Prelude> takeWhile (== 'B') $ map (!! 3) testboard
    "BBB"
    

    Using this, writing a blankDepth function is trivial, and that will doubtless help you on your way to your solution.

    blankDepth :: Int -> [[Char]] -> Int
    blankDepth col = length . takeWhile (== 'B') . map (!! col)
    
    Prelude> blankDepth 3 testboard
    3
    Prelude> blankDepth 5 testboard
    5
    Prelude> blankDepth 1 testboard
    5
    Prelude> blankDepth 6 testboard
    6