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 <[email protected] <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 [email protected] <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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to