2016-10-12 4 views
0

私は、ユーザーに5個の四角形のグリッドが表示され、9個がハイライト表示されているメモリゲームに取り組んでいます。ユーザはこれらの9つの四角形を覚えて選択しなければならない。エルムのメモリゲーム、ランダム化またはシャッフルグリッド

予想される/獲得したボード構成を生成するにはどうすればよいですか?

現在、私は命令型言語ではList (List Bool)

としてBoardを持っている必要があり、JSのように、私はランダムに突然変異する列と行のインデックスを選択グリッド上で9回を繰り返すでしょう。それはエルムでは不可能なので、私はちょっと立ち往生しています。

カップルの戦略が心に来た:

戦略1

が使用Array

戦略2

無作為化グリッドを生成し、すべての座標をシャッフル、最初に選びます9.

注意タイルを選択する方法も必要ですのでBoardList (List Tile)になります。Tile{ x: Int, y: Int, selected: Bool}です。

私はすでにvanilla JSでゲームを書いています。あなたはここでそれを試してみることができます。

module Main exposing (..) 

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


-- model 


type alias Board = 
    Array (Array Bool) 


type alias Tile = 
    { x : Int 
    , y : Int 
    , selected : Bool 
    } 


type alias Model = 
    { board : Board 
    , expectedBoard : Board 
    , gameOver : Bool 
    , playerWon : Bool 
    , turnCount : Int 
    } 


initModel : (Model, Cmd Msg) 
initModel = 
    ({ board = generateSquareMatrix 5 False 
     , expectedBoard = Array.fromList [] 
     , gameOver = False 
     , playerWon = False 
     , turnCount = 0 
     } 
    , Cmd.none 
    ) 


generateSquareMatrix : Int -> Bool -> Array (Array Bool) 
generateSquareMatrix num value = 
    Array.repeat num (Array.repeat num value) 



-- update 


type Msg 
    = SelectTile Bool 
    | RestartGame 
    | SuffleBoard 
    | NewBoard (Array (Array Bool)) 


update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case (Debug.log "msg" msg) of 
     SelectTile tile -> 
      ({ model 
       | turnCount = model.turnCount + 1 
       } 
      , Cmd.none 
      ) 

     RestartGame -> 
      ({ model 
       | turnCount = 0 
       } 
      , Cmd.none 
      ) 

     SuffleBoard -> 
      (model, Random.generate NewBoard (Random.Array.shuffle model.board)) 

     NewBoard newBoard -> 
      ({ model | board = newBoard } 
      , Cmd.none 
      ) 



-- view 


view : Model -> Html Msg 
view model = 
    div [ class "scoreboard" ] 
     [ h1 [] [ text "Recall" ] 
     , grid model 
     , button [ onClick SuffleBoard ] [ text "New Board" ] 
     , p [] [ text (toString model) ] 
     ] 


grid : Model -> Html Msg 
grid model = 
    div [ class "recall-grid" ] 
     (List.map 
      (\row -> 
       div 
        [ class "recall-grid-row" ] 
        (List.map 
         (\tile -> 
          div [ class "recall-grid-tile", onClick (SelectTile tile) ] [] 
         ) 
         (Array.toList row) 
        ) 
      ) 
      (Array.toList model.board) 
     ) 



-- SUBSCRIPTIONS 


subscriptions : Model -> Sub Msg 
subscriptions model = 
    Sub.none 


main : Program Never 
main = 
    App.program 
     { init = initModel 
     , view = view 
     , update = update 
     , subscriptions = subscriptions 
     } 

答えて

1

戦略、それはランダムな要素の一意性を保証しますので、2つの作品だけで罰金:ここ

http://mruzekw.github.io/recall/は、私がこれまでに多少の戦略を実装書いたコードです。

ランダム性を扱う場合、ジェネレータマッピング関数を使用して、単純なジェネレータから複雑なジェネレータを構築することをお勧めします。これにより、実際のジェネレータコード内のランダムなシードを追跡する必要がなくなります。

私たちが必要とする最初のジェネレータは、配列インデックスのリストを構築するものです。この配列のタプルは(Int, Int)です。

indexGenerator : Int -> Int -> Random.Generator (Array (Int, Int)) 
indexGenerator edgeSize sampleSize = 
    List.map (\i -> List.map2 (,) (List.repeat edgeSize i) [0..(edgeSize-1)]) [0..(edgeSize-1)] 
     |> List.concat 
     |> Array.fromList 
     |> Random.Array.shuffle 
     |> Random.map (Array.slice 0 sampleSize) 

今、私たちはsquareMatrixGeneratorを構築するためにFalsesのあなたの最初の行列と一緒に、Random.mapを使用することができます。

squareMatrixGenerator : Int -> Int -> Bool -> Random.Generator (Array (Array Bool)) 
squareMatrixGenerator edgeSize sampleSize value = 
    let 
     initialMatrix = 
      Array.repeat edgeSize (Array.repeat edgeSize value) 
     invertPoint (x, y) = 
      Array.Extra.update x (Array.Extra.update y not) 
     indexes = 
      indexGenerator edgeSize sampleSize 
    in 
     Random.map (Array.foldl invertPoint initialMatrix) indexes 

上記のコードは、アレイの更新をelm-community/array-extraパッケージに依存しています。

initの間にシードをRandom.stepに渡し、ShuffleBoardメッセージをRandom.generateに渡すことで使用できます。例:

ShuffleBoard -> 
    (model, Random.generate NewBoard (squareMatrixGenerator 9 5 False)) 
+0

ありがとう、チャド!ここで解析する方法はたくさんあります。私はそれがどのように行くかを見て実行してみましょう。フォローアップの質問があればコメントします。 –