Domemo(vb版) Lv1

##Domemo？
とあるボードゲーム。
社内勉強会で作成するプログラムの題材として選定。
[Domemoの詳細はこちらを参照](https://chimolog.co/domemo/)
![domemo2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/9b4ab5d6-045f-dcdd-cdf2-3d7ab490e878.png)

なぜDomemoを作る事にしたかといえば、
作って遊べるものを題材にした方がモチベーションが続きやすいから。

##準備
###まずはVisual Studio 2019をインストール！
https://docs.microsoft.com/ja-jp/visualstudio/releases/2019/release-notes

色んなバージョンがありますが「Community 2019　のダウンロード」でよいです。
![Community.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/95abcb91-63c1-6594-236c-1c65e2de326d.jpeg)

「.Netデスクトップ開発」を選んでインストールしてください。
![vb版.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/d91ed6af-78a1-6ef9-825b-e6ece1dcefd1.jpeg)
なお、必須ではないですが、F#を入れるのもおすすめです。
とても面白い言語です。

Visual Studioを起動したら、メニューの「ファイル」から新しいプロジェクトを作成。
![vb2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/c6b50945-ec5e-6115-b90a-4f265eac475f.jpeg)

Visual Basicを選びます。プロジェクト名はお好きなように。
![vb3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/da3d72b1-17bd-8dc4-28a5-bb8b38006aff.jpeg)

エディタにソースコードを書きます。
![vb4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270579/628e0ce6-4f0a-3c0f-9a97-a05cfbf8292d.jpeg)


###VB.Netについてはここから！
以下で紹介する記事は全部読んだり、1回で理解する必要はないです。
必要に応じて参照してください。

[VS2019を使ったチュートリアル](https://docs.microsoft.com/ja-jp/visualstudio/get-started/visual-basic/tutorial-console?view=vs-2019)
※VisualStudioの使い方わからない人は必読!!

[VBリファレンス](https://docs.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/index)

[VB.NET 文法メモ(文法かいつまみ)](https://qiita.com/k-moriscom/items/9f8393905d0a7c479e93)

[MS公式Doc-トップページ](https://docs.microsoft.com/ja-jp/dotnet/visual-basic/)

##考え方
まずはゲームのルールを理解しましょう。
実際に遊んでみるのが一番！
実物を持ってると、実際に並べながら考えられるのでお勧めです。

###どうやったらゲームができるのか、手順を考える
1: 1～7までのカードを用意する
2: カードをシャッフルする
3: 場にカードを4枚表にする
4: 4枚のカードを、内容を伏せたままゲームから除外する
5: カードを5枚ずつ4人のプレイヤーに配る
6: 各プレイヤーは自分には見えないようにカードを表にする
7: 各プレイヤーは(他のプレイヤーのカードを見ながら)自分が持っているカードを予想して、宣言する
8: 予想があっていたら、手札からカードを場に移動して表にする
9: 最初に手札がなくなったプレイヤーが勝ち

[Domemoの詳しいルールについてはこちらを参照](https://chimolog.co/domemo/)

###シンプルにするための前提
1: プレイヤー人数を4人とする
2: Player1(自分)の手札は見えないようにする
3: とにかく動けばOK

##今後のロードマップ
**Lv1:まずは組んでみよう(now!)**
Lv2:[プレイヤーの処理を関数にまとめてみよう](https://qiita.com/aoi_erimiya/items/0642177270222e5ebfeb)
Lv3:プレイヤー1を操作できるようにしよう
Lv4:CPUを強くしよう
Lv5:プレイヤーをクラス化してみよう

##Lv1:全自動でゲームが進むようにする
まずは動けばOK!!
難しく考えずに、全自動でゲームが進むように作ってみましょう。

```vb
Module Module1

    ' Player2～4の手札を表示する
    Sub show(cards As List(Of Integer))
        For Each card In cards
            Console.Write(card)
        Next
        Console.WriteLine("")
    End Sub

    ' Player1の手札を伏せて表示する
    Sub showMask(cards As List(Of Integer))
        For Each card In cards
            Console.Write("X")
        Next
        Console.WriteLine("")
    End Sub

    Sub Main()
        ' 1: 1～7までのカードを用意する
        Dim cards As List(Of Integer) = New List(Of Integer)

        For i As Integer = 1 To 7
            For j As Integer = 1 To i
                cards.Add(i)
            Next
        Next

        ' 2: カードをシャッフルする
        Dim shuffledCards As List(Of Integer) = cards.OrderBy(Function(x) Guid.NewGuid()).ToList

        show(shuffledCards)

        ' 3: 場にカードを4枚表にする
        Dim openCards As List(Of Integer) = shuffledCards.GetRange(0, 4)

        ' 4: 4枚のカードを、内容を伏せたままゲームから除外する
        Dim closeCards As List(Of Integer) = shuffledCards.GetRange(4, 4)

        ' 5: カードを5枚ずつ4人のプレイヤーに配る
        Dim player1 As List(Of Integer) = shuffledCards.GetRange(8, 5)
        Dim player2 As List(Of Integer) = shuffledCards.GetRange(13, 5)
        Dim player3 As List(Of Integer) = shuffledCards.GetRange(18, 5)
        Dim player4 As List(Of Integer) = shuffledCards.GetRange(23, 5)

        Dim random As New Random()

        ' 6: 各プレイヤーは自分には見えないようにカードを表にする
        For i As Integer = 1 To 30
            Console.WriteLine("---------------------------------")
            ' 場のカードとプレイヤーの手札を表示する
            Console.Write("open->")
            show(openCards)
            Console.Write("Player1->")
            showMask(player1)
            Console.Write("Player2->")
            show(player2)
            Console.Write("Player3->")
            show(player3)
            Console.Write("Player4->")
            show(player4)

            ' 7: 各プレイヤーは自分が持っているカードを予想して、宣言する
            ' Player1
            Dim declaration As Integer = random.Next(7) + 1
            Console.WriteLine("p1 -> " & declaration)

            ' 8: 予想があっていたら、手札からカードを場に移動して表にする
            If player1.Remove(declaration) Then
                Console.WriteLine("jackPot!")
                openCards.Add(declaration)

                ' 9: 最初に手札がなくなったプレイヤーが勝ち
                If player1.Count = 0 Then
                    Console.WriteLine("player1 win!")
                    Exit For
                End If
            End If

            ' Player2
            declaration = random.Next(7) + 1
            Console.WriteLine("p2 -> " & declaration)
            If player2.Remove(declaration) Then
                Console.WriteLine("jackPot!")
                openCards.Add(declaration)
                If player2.Count = 0 Then
                    Console.WriteLine("player2 win!")
                    Exit For
                End If
            End If

            ' Player3
            declaration = random.Next(7) + 1
            Console.WriteLine("p3 -> " & declaration)
            If player3.Remove(declaration) Then
                Console.WriteLine("jackPot!")
                openCards.Add(declaration)
                If player3.Count = 0 Then
                    Console.WriteLine("player3 win!")
                    Exit For
                End If
            End If

            ' Player4
            declaration = random.Next(7) + 1
            Console.WriteLine("p4 -> " & declaration)
            If player4.Remove(declaration) Then
                Console.WriteLine("jackPot!")
                openCards.Add(declaration)
                If player4.Count = 0 Then
                    Console.WriteLine("player4 win!")
                    Exit For
                End If
            End If

            ' 何か入力したら次のターンにいくようにする
            Console.ReadKey()
        Next

        Console.ReadKey()
    End Sub

End Module
```
改良できる部分はまだまだたくさん。
また、これと違うプログラムを書いても、ルール通りに動けばOKです。
楽しみながら作ってみましょう！