Thanks Peter for your help! I could go further but now, there's another 
issue. I would like to display the current player's shape when he clicks on 
a cell. The thing is I don't know how to interact with the DOM in this 
case. I know how to define an onClick event on each cell (displayed as a 
div), but I don't know how to interact with a cell to display a shape in 
its div).

Here's my code. Hope you can help me!

import Html.App as App
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)

main =
    App.program { init = init, update = update, view = view, subscriptions 
= \_ -> Sub.none}

type alias Player =
  {
    id: Int
   ,name: String
   ,shape: String
   ,score: Int
  }

type alias Model = 
    {
        player1: Player
       ,player2: Player
       ,current: Player
       ,boxClicked: Maybe Int
    }

 
type alias Box = 
  {
    id: Int
   ,player: Maybe Player
  }

player1: Player
player1 =
  {id = 1, name = "Player 1", shape = "X", score = 0 }
  
player2: Player
player2 =
  {id = 2, name = "Player 2", shape = "O", score = 0}

area: List (List Box)
area = 
  [
    [Box 1 Nothing, Box 2 Nothing, Box 3 Nothing]
   ,[Box 4 Nothing, Box 5 Nothing, Box 6 Nothing]
   ,[Box 7 Nothing, Box 8 Nothing, Box 9 Nothing]
  ]

init: (Model, Cmd Msg)
init =
    (Model player1 player2 player1 Nothing, Cmd.none)

type Msg = None | ClickBox Int

changePlayer: Player -> Player
changePlayer player =
  case player.id of
    1 ->
      player2
    _ ->
      player1


filterRow: Int -> List Box -> Maybe Box
filterRow boxId row =
  row
  |> List.filter (\box -> box.id == boxId)
  |> List.head

renderClickedBox: Maybe Int -> String
renderClickedBox boxId =
  case boxId of
    Nothing -> "No box clicked yet"
    Just b -> "Box " ++ (toString b) ++ " clicked"

update: Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of
        None ->
            (model, Cmd.none)
        
        ClickBox boxId ->
            let
              currentBox = area
                         |> List.map (filterRow boxId)
                         
              currentPlayer = changePlayer model.current
            in
            (Model model.player1 model.player2 currentPlayer (Just boxId), 
Cmd.none)

view: Model -> Html Msg
view model =
    div []
    [
      span[style [("font-weight", "bold")]][text model.player1.name]
     ,span[style [("text-decoration", "underline")]] [text 
(toString(model.player1.score))]
     ,span[style [("margin-right", "15px")]][]
     ,span[style [("text-decoration", "underline")]] [text 
(toString(model.player2.score))]
     ,span[style [("font-weight", "bold")]][text model.player2.name]
     ,div[]
     [
       area
       |> List.map (viewRow model)
       |> div[]
     ]
    ,div[][text (renderClickedBox model.boxClicked)]
    ,div[][text model.current.name]
    ]
    
viewRow: Model -> List Box -> Html Msg
viewRow model row =
  row
  |> List.map (\box -> div [id (toString box.id), style (boxStyle 
box.player), onClick (ClickBox box.id)][])
  |> div[]
  
boxStyle shape =
  [
    ("border", "1px solid black")
   ,("width", "64px")
   ,("height", "64px")
   ,("display", "inline-block")
  ]

Le lundi 24 octobre 2016 14:36:48 UTC+2, Peter Damoc a écrit :
>
> You almost got it right. Here is your program with the view altered a 
> little bit (I've extracted the row display and the style of the cell)
>
> import Html.App as App
> import Html exposing (..)
> import Html.Attributes exposing(..)
>
> main =
>     App.program { init = init, update = update, view = view, subscriptions 
> = \_ -> Sub.none}
>
> type alias Player =
>   {
>     name: String
>    ,shape: String
>    ,score: Int
>   }
>
> type alias Model = 
>     {
>         player1: Player
>        ,player2: Player
>     }
>
>  
> type alias Box = 
>   {
>     id: Int
>    ,shape: Maybe Player
>   }
>
> area: List (List Box)
> area = 
>   [
>     [Box 1 Nothing, Box 2 Nothing, Box 3 Nothing]
>    ,[Box 4 Nothing, Box 5 Nothing, Box 6 Nothing]
>    ,[Box 7 Nothing, Box 8 Nothing, Box 9 Nothing]
>   ]
>
> init: (Model, Cmd Msg)
> init =
>     (Model {name = "Player 1", shape = "X", score = 0 } {name = "Player 
> 2", shape = "O", score = 0}, Cmd.none)
>
> type Msg = None
>
> update: Msg -> Model -> (Model, Cmd Msg)
> update msg model =
>     case msg of
>         None ->
>             (model, Cmd.none)
>
> view: Model -> Html Msg
> view model =
>     div []
>     [
>       span[style [("font-weight", "bold")]][text model.player1.name]
>      ,span[style [("text-decoration", "underline")]] [text 
> (toString(model.player1.score))]
>      ,span[style [("margin-right", "15px")]][]
>      ,span[style [("text-decoration", "underline")]] [text 
> (toString(model.player2.score))]
>      ,span[style [("font-weight", "bold")]][text model.player2.name]
>      ,div[]
>      [
>        area
>        |> List.map viewRow 
>        |> div[style [("border", "1px solid black")]]
>      ]
>     ]
>     
>     
>     
> viewRow : List Box -> Html Msg
> viewRow row = 
>   div [] 
>   (List.map (\box -> div [id (toString box.id), style (boxStyle 
> box.shape)][]) row)
>   
>   
> boxStyle shape = 
>   [ ("border", "1px solid black")
>   , ("width", "64px")
>   , ("height", "64px")
>   , ("display", "inline-block")
>   ]
>
> On Mon, Oct 24, 2016 at 3:01 PM, Did <didier...@gmail.com <javascript:>> 
> wrote:
>
>> Hello there!
>>
>> As a newbie, and in order to learn elm, I started to write a tic tac toe 
>> game. I wanted to start by drawing the game area but I'm stuck with one 
>> thing. I decided that my area was a list of list of Box : List (List Box). 
>> A box is defined by an id and maybe a player (so that I can track if a box 
>> was filled by a player or not). With procedural languages, I can do 
>> something like this:
>>
>> for(var i = 0; i < 3; i++ {
>>     for (var j = 0; j < 3,; j++) {
>>         drawBox(area[i][j]);
>>     }
>> }
>>
>> But I can't figure out how to do this in elm... It does not even compile, 
>> but that's because I don't fully understand List.map... 
>>
>> Here is the code I started writing. If someone can help me, I would 
>> really appreciate!
>>
>> import Html.App as App
>> import Html exposing (..)
>> import Html.Attributes exposing(..)
>>
>> main =
>>     App.program { init = init, update = update, view = view, 
>> subscriptions = \_ -> Sub.none}
>>
>> type alias Player =
>>   {
>>     name: String
>>    ,shape: String
>>    ,score: Int
>>   }
>>
>> type alias Model = 
>>     {
>>         player1: Player
>>        ,player2: Player
>>     }
>>
>>  
>> type alias Box = 
>>   {
>>     id: Int
>>    ,shape: Maybe Player
>>   }
>>
>> area: List (List Box)
>> area = 
>>   [
>>     [Box 1 Nothing, Box 2 Nothing, Box 3 Nothing]
>>    ,[Box 4 Nothing, Box 5 Nothing, Box 6 Nothing]
>>    ,[Box 7 Nothing, Box 8 Nothing, Box 9 Nothing]
>>   ]
>>
>> init: (Model, Cmd Msg)
>> init =
>>     (Model {name = "Player 1", shape = "X", score = 0 } {name = "Player 
>> 2", shape = "O", score = 0}, Cmd.none)
>>
>> type Msg = None
>>
>> update: Msg -> Model -> (Model, Cmd Msg)
>> update msg model =
>>     case msg of
>>         None ->
>>             (model, Cmd.none)
>>
>> view: Model -> Html Msg
>> view model =
>>     div []
>>     [
>>       span[style [("font-weight", "bold")]][text model.player1.name]
>>      ,span[style [("text-decoration", "underline")]] [text 
>> (toString(model.player1.score))]
>>      ,span[style [("margin-right", "15px")]][]
>>      ,span[style [("text-decoration", "underline")]] [text 
>> (toString(model.player2.score))]
>>      ,span[style [("font-weight", "bold")]][text model.player2.name]
>>      ,div[]
>>      [
>>        area
>>        |> List.map
>>        |> List.map (\box -> span[id box.id, style [("border", "1px solid 
>> black")]][])
>>        |> div[style [("border", "1px solid black")]]
>>      ]
>>     ]
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elm-discuss...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to