랜덤(Random)


코드를 클론하거나 온라인 에디터에서 함께 따라해주세요.


이번엔 1에서 6까지 중 숫자 하나를 반환하는 "주사위 굴리기" 앱을 만들거에요.

제가 효과가 있는 코드를 작성할 땐, 보통 두 단계로 나누어서 작업해요. 처음엔 화면이 되는 최소한의 코드를, 그 다음엔 세부 사항들을 채워나가는 거죠. 예제를 이런 과정을 통해 작성해 볼게요.

첫번째 단계 - 최소한의 코드

항상 시작할때는 Model 을 고려하세요.

type alias Model =
  { dieFace : Int
  }

지금은 일단 dieFace(주사위의 면)을 1부터 6까지의 정수라고 생각할거에요. 그리고 나서 빠르게 view 함수의 뼈대를 잡고 맘 편하게 다음단계로 넘어갈게요.

view : Model -> Html Msg
view model =
  div []
    [ h1 [] [ text (toString model.dieFace) ]
    , button [ onClick Roll ] [ text "Roll" ]
    ]

Elm 아키텍처의 사용자 입력 단원 예제에서 본 전형적인 형태에요. <button> 클릭하면 Roll 메시지를 전달하고, update 함수에 전달되겠죠.

type Msg = Roll

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Roll ->
      (model, Cmd.none)

update 함수는 이전과 같은 형태로 보이지만, 반환 타입이 살짝 달라요. 이전엔 모델만 반환했어요. 하지만 지금은 모델명령, 둘 다를 반환하죠. "모델을 반환할 건데, 거기에 '무엇'을 더 하고 싶어"라고 생각하시면 되요. 이 예제의 경우엔, '무엇'이 Elm에게 랜덤값을 요청하는 거죠. 일단 Cmd.none 으로 채웠는데요. 이 의미는 "우리는 명령할 게 없어, 아무것도 하지마"를 뜻해요. 두번째 단계에서 '무엇'을 채울거에요.

마지막으로 아래와 같이 init 값을 만들거에요.

init : (Model, Cmd Msg)
init =
  (Model 1, Cmd.none)

앱이 시작될 때 즉시 실행될 때, 초기화 되어야 할 모델과 명령을 명시했어요. 이건 현재 update가 하고 있는 일과 거의 비슷해요.

지금까지 모든것을 연결될 수 있도록 하였어요. 동작이 않돼지만 <button>을 클릭할 수도 있죠. 자 그럼 동작하도록 바꿔 볼게요!

두번째 단계 - 동작 추가하기

랜덤에 관한 걸 놓치고 있었네요! 유저가 버튼을 클릭 했을 때, Elm에게 명령을 내려 1부터 6사이의 난수를 생성해야 해요. 그러기 위해 새로운 종류의 메시지를 추가할 거에요.

type Msg
  = Roll
  | NewFace Int

Roll은 그대로 두고, 난수를 받을 때 사용할 NewFace를 추가했어요. 이것만으로 update를 채우기 위한 준비는 끝났어요.

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Roll ->
      (model, Random.generate NewFace (Random.int 1 6))

    NewFace newFace ->
      (Model newFace, Cmd.none)

두 가지 새로운 게 보이는데요. 첫번째는 NewFace 메시지 부분, 두번째는 이제 진짜 Roll 명령어를 추가했다는 거죠. Random 라이브러리에서 두가지 함수를 사용했는데, 가장 중요한 것은 Random.generate 이에요.

Random.generate : (a -> msg) -> Random.Generator a -> Cmd msg

이 함수는 두개의 인자를 받아요. 첫번째 인자는 랜덤 값의 태그를 지정하는 것인데요. 위 경우에선 NewFace : Int -> Msg 를 사용하여, 난수를 update 함수에 전달했어요. 두번째 인자는 특정 유형의 임의 값을 지정하는 "생성자" 인데요. Int, Float, Bool 과 같은 간단한 타입을 사용할 수도 있지만, 필드가 많은 레코드에서도 사용할 수 있어요. 이 예제에서는 간단한 생성자를 사용하였어요.

Random.int : Int -> Int -> Random.Generator Int

정수에 상한과 하한을 정한 뒤, 자 이제 지정된 범위의 생성자를 갖게 되었습니다.

이제 모두 끝났어요. 버튼을 클릭해보시고 새로운 값이 나오는 지 확인해 보세요!

이 단원에서 중요한 교훈이 있어요.

  • 프로그램을 조금씩 조금씩 작성하세요. 일단 간단한 골격을 잡고, 점진적으로 발전시키세요.
  • update 함수에서 새로운 모델과 명령을 만들수 있어요.
  • 그냥 랜덤 값을 얻을 순 없어요. 명령을 만들면, Elm은 안보이는 곳에서 그것을 처리하여 제공해요. 사실, 프로그램에서 신뢰할 수 없는 값(랜덤 값, HTTP, file I/O, 데이터베이스 읽기 등)은 Elm을 통해서 처리하게 돼요.

이 시점에서, 명령에 대한 이해를 향상시키는 가장 좋은 방법은 예제들을 더 많이 보는거에요! HTTP 와 웹소켓 라이브러리에서 많이 사용되어지는 데요. 만약 어렵게 느껴지신다면, 랜덤과 같이 명령에 관한 더 많은 예제를 통해 연습해보시는 게 좋아요!

연습문제: 이미 소개 된 것들을 바탕으로 다음을 진행해보세요.

  • 숫자를 보여주는 대신 이미지를 이용해 주사위의 면을 표시해 보세요.
  • 주사위를 하나 더 추가해서, 두 주사위를 동시에 굴릴 수 있도록 해보세요

다음은 새로운 기술이 필요해요.

  • 이미지로 표현하는 대신 elm-lang/svg 라이브러리를 통해 직접 그려보세요.
  • 작업과 애니메이션을 배운 뒤에, 최종 값을 보여주기 전에 아무렇게나 빙글 돌도록 해보세요.

results matching ""

    No results matching ""