C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

三目並べ 完成?

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■92690 / inTopicNo.1)  三目並べ 完成?
  
□投稿者/ aiti (7回)-(2019/10/20(Sun) 10:00:23)

分類:[VB.NET/VB2005 以降] 

Option Explicit On '型宣言を強制する。
Option Strict On  '暗黙的な型変換を禁止する。

Module Module1
Sub Main()
Do
Dim table(2, 2) As String
table(0, 0) = " "
table(0, 1) = " "
table(0, 2) = " "
table(1, 0) = " "
table(1, 1) = " "
table(1, 2) = " "
table(2, 0) = " "
table(2, 1) = " "
table(2, 2) = " "

Dim P1name As String
Dim P2name As String
Dim WinPlayer As String = String.Empty
Dim LoopCount1 As Integer = 1
Dim Gameover As Integer = 0
Dim dNow As DateTime = System.DateTime.Now
Console.Clear()
'文字出力
Console.ForegroundColor = ConsoleColor.Green
Console.WriteLine(dNow.ToShortDateString())
Console.WriteLine(dNow.ToString("HH時mm分ss秒"))
Console.WriteLine()
Console.WriteLine("(--Tic_Tac_Toe--)")
Console.WriteLine()
Console.WriteLine("先攻は「O」です。")
Console.Write("あなたの名前を入力して下さい")
Console.WriteLine()
Console.WriteLine()
P1name = Console.ReadLine()
Console.WriteLine()
Console.WriteLine("後攻は「X」です。")
Console.Write("あなたの名前を入力して下さい")
Console.WriteLine()
Console.WriteLine()
P2name = Console.ReadLine()
Console.Clear()
Console.WriteLine()
Console.WriteLine("Rを押すとゲームを終了できます。")
Console.WriteLine("対応するキーを入力すると先攻は「O」,後攻は「X」が表示されます。")
Console.WriteLine()
Console.WriteLine(" #####")
Console.WriteLine("# 123 #")
Console.WriteLine("# 456 #")
Console.WriteLine("# 789 #")
Console.WriteLine(" #####")
Console.WriteLine()
Console.WriteLine("1から9の数字を入力して下さい。")

Do

Dim Mark As String = SenkouKOukouDisp(LoopCount1, P1name, P2name, WinPlayer)
If (LoopCount1 Mod 2) <> 0 Then
Mark = "O"
WinPlayer = P1name
Else
Mark = "X"
WinPlayer = P2name
End If

Dim Cursor As Integer = 0
Dim Key As ConsoleKeyInfo
Dim Truefalse1 As Boolean = False
Key = Console.ReadKey(True)
Truefalse1 = True
Select Case Key.Key
Case ConsoleKey.D1 To ConsoleKey.D9
Cursor = Convert.ToInt32(Key.Key) - 48
Case ConsoleKey.R
Gameover = 3
Case Else
Truefalse1 = False
Console.Write("入力されたキーは使えません")
End Select


'End Select

If Cursor >= 1 AndAlso Cursor <= 9 Then
Dim x As Integer = (Cursor - 1) Mod 3
Dim y As Integer = (Cursor - 1) \ 3

If table(y, x) = " " Then
table(y, x) = Mark
LoopCount1 += 1
End If
End If

Dim checkline(,) As Integer = {{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}}

For n = 0 To 7
Dim v() As Integer = {checkline(n, 0), checkline(n, 1), checkline(n, 2)}
Dim line = String.Join("", v.Select(Function(p) table(p Mod 3, p \ 3)))

' 3 つ揃ったラインがあればループ終了 
If line = "OOO" Then
Gameover = 1
WinPlayer = P1name
Exit For
ElseIf line = "XXX" Then
Gameover = 2
WinPlayer = P2name
Exit For
Gameover = 0
WinPlayer = Nothing
End If
Next
'------------------------------------------------------------------------------------
Console.Clear()
Dim Row0 As String = (table(0, 0) & table(0, 1) & table(0, 2))
Dim Row1 As String = (table(1, 0) & table(1, 1) & table(1, 2))
Dim Row2 As String = (table(2, 0) & table(2, 1) & table(2, 2))
Console.WriteLine("ゲーム中Rキー入力でゲームを終了できます。")
Console.WriteLine("PressedKey:{0}", Key.Key) '入力したキーの表示
Console.WriteLine()
Console.WriteLine(" {0}’s BattleTurn", WinPlayer) '順番プレイヤーの名前の表示
Console.WriteLine()
Console.WriteLine("「見本」")
Console.WriteLine(" #####")
Console.WriteLine("# 123 #")
Console.WriteLine("# 456 #")
Console.WriteLine("# 789 #")
Console.WriteLine(" #####")
Console.WriteLine()
Console.WriteLine()
Console.WriteLine(" #####")
Console.WriteLine("# {0} ", Row0 & " # ")
Console.WriteLine("# {0} ", Row1 & " # ")
Console.WriteLine("# {0} ", Row2 & " # ")
Console.WriteLine(" #####")

Loop Until Gameover = 1 Or Gameover = 2 Or Gameover = 3

'結果出力 
If Gameover = 1 Then
Console.WriteLine()
Console.WriteLine(" 試合終了 {0}の勝利!!!!!", WinPlayer)
Console.WriteLine(" Rキー入力で名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
ElseIf Gameover = 2 Then
Console.WriteLine()
Console.WriteLine("引き分け")
Console.WriteLine("Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
ElseIf Gameover = 3 Then
Console.WriteLine()
Console.WriteLine(" ゲームを終了します。")
Console.WriteLine(" Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
End If

Loop While Console.ReadKey.Key = ConsoleKey.R 'Rキーを押すと名前入力画面(最初に)に戻る
End Sub

Private Function SenkouKOukouDisp(LoopCount1 As Integer, P1name As String, P2name As String, WinPlayer As String) As String

End Function
End Module

ゲームをコンソールで動かせるところまでは完成しました。コードをまとめたり、短縮できる部分がありそうなのです。アドバイスをお願いします。
引用返信 編集キー/
■92701 / inTopicNo.2)  Re[1]: 三目並べ 完成?
□投稿者/ furu (11回)-(2019/10/21(Mon) 11:34:55)
No92690 (aiti さん) に返信
完成していない?
ちゃんとテストした方がいいです。
 ・先攻が勝つ場合
 ・後攻が勝つ場合
 ・引き分けの場合
 ・止めたい場合
引用返信 編集キー/
■92703 / inTopicNo.3)  Re[2]: 三目並べ 完成?
□投稿者/ aiti (8回)-(2019/10/21(Mon) 14:58:32)
No92701 (furu さん) に返信

Option Explicit On '型宣言を強制する。
Option Strict On  '暗黙的な型変換を禁止する。
Module Module1

    ''' <summary>
    ''' プレイヤーの氏名入力
    ''' </summary>
    ''' <param name="turn">手番</param>
    ''' <param name="symbol">記号</param>
    ''' <returns>プレイヤーの氏名</returns>
    ''' <remarks></remarks>
    Private Function InputPlayerName(turn As String, symbol As String) As String
        Console.WriteLine("{0}は「{1}」です。", turn, symbol)
        Console.Write("あなたの名前を入力して下さい")
        Console.WriteLine()
        Console.WriteLine()
        Dim name = Console.ReadLine() '1行分の文字を読み取る
        Return name
    End Function

    Sub Main()
        Do
            Dim table(2, 2) As String
            table(0, 0) = " "
            table(0, 1) = " "
            table(0, 2) = " "
            table(1, 0) = " "
            table(1, 1) = " "
            table(1, 2) = " "
            table(2, 0) = " "
            table(2, 1) = " "
            table(2, 2) = " "

            Dim P1name As String '先攻 プレイヤー1の名前 
            Dim P2name As String '後攻 プレイヤー2の名前
            Dim WinPlayer As String = String.Empty
            Dim LoopCount1 As Integer = 1
            Dim Gameover As Integer = 0
            Dim dNow As DateTime = System.DateTime.Now
            Console.Clear()
            'タイトル表示
            Console.ForegroundColor = ConsoleColor.Green
            Console.WriteLine(dNow.ToShortDateString())
            Console.WriteLine(dNow.ToString("HH時mm分ss秒"))
            Console.WriteLine()
            Console.WriteLine("(--Tic_Tac_Toe--)")
            Console.WriteLine()
            P1name = InputPlayerName("先行", "O")
            P2name = InputPlayerName("後攻", "X")

            Console.Clear() '↑のコンソールウィンドウをクリアして↓を出力
            Console.WriteLine()
            Console.WriteLine("Rを押すとゲームを終了できます。")
            Console.WriteLine("対応するキーを入力すると先攻は「O」,後攻は「X」が表示されます。")
            Console.WriteLine()
            Console.WriteLine(" #####")
            Console.WriteLine("# 123 #")
            Console.WriteLine("# 456 #")
            Console.WriteLine("# 789 #")
            Console.WriteLine(" #####")
            Console.WriteLine()
            Console.WriteLine("1から9の数字を入力して下さい。")

            Do 'Do Loop 繰り返す条件の指定  先攻がO 後攻がX

                '現在のプレイヤーの記号を取得する。
                Dim Mark As String = SenkouKOukouDisp(LoopCount1, P1name, P2name, WinPlayer)
                If (LoopCount1 Mod 2) <> 0 Then
                    Mark = "O"
                    WinPlayer = P1name
                Else
                    Mark = "X"
                    WinPlayer = P2name
                End If

                '入力されたキーの出力
                Dim Cursor As Integer = 0
                Dim Key As ConsoleKeyInfo
                Dim Truefalse1 As Boolean = False
                Key = Console.ReadKey(True)
                Truefalse1 = True
                Select Case Key.Key
                    Case ConsoleKey.D1 To ConsoleKey.D9
                        Cursor = Convert.ToInt32(Key.Key) - 48
                    Case ConsoleKey.R
                        Gameover = 3
                    Case Else
                        Truefalse1 = False
                        Console.Write("入力されたキーは使えません")
                End Select

                If Cursor >= 1 AndAlso Cursor <= 9 Then
                    Dim x As Integer = (Cursor - 1) Mod 3
                    Dim y As Integer = (Cursor - 1) \ 3

                    If table(y, x) = " " Then
                        table(y, x) = Mark
                        LoopCount1 += 1
                    End If
                End If

                '勝敗判定
                ' 縦・横・斜めの探索ライン(全8通り)
                Dim checkline(,) As Integer = {{0, 3, 6}, {1, 4, 7}, {2, 5, 8}, {0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 4, 8}, {2, 4, 6}}
                '全パターン 8 回探索する
                For n = 0 To 7
                    Dim v() As Integer = {checkline(n, 0), checkline(n, 1), checkline(n, 2)}
                    Dim line = String.Join("", v.Select(Function(p) table(p Mod 3, p \ 3)))

                    ' 3 つ揃ったラインがあればループ終了
                    If line = "OOO" Then
                        Gameover = 1
                        WinPlayer = P1name
                        Exit For
                    ElseIf line = "XXX" Then
                        Gameover = 2
                        WinPlayer = P2name
                        Exit For
                        ' 最後まで決着がつかなかった場合
                    ElseIf LoopCount1 > 9 Then
                        Gameover = 4
                        WinPlayer = Nothing
                    End If
                Next

                Console.Clear()
                Dim Row0 As String = (table(0, 0) & table(0, 1) & table(0, 2))
                Dim Row1 As String = (table(1, 0) & table(1, 1) & table(1, 2))
                Dim Row2 As String = (table(2, 0) & table(2, 1) & table(2, 2))
                Console.WriteLine("ゲーム中Rキー入力でゲームを終了できます。")
                Console.WriteLine("PressedKey:{0}", Key.Key) '入力したキーの表示
                Console.WriteLine()
                Console.WriteLine(" {0}’s BattleTurn", WinPlayer) '順番プレイヤーの名前の表示
                Console.WriteLine()
                Console.WriteLine("「見本」")
                Console.WriteLine(" #####")
                Console.WriteLine("# 123 #")
                Console.WriteLine("# 456 #")
                Console.WriteLine("# 789 #")
                Console.WriteLine(" #####")
                Console.WriteLine()
                Console.WriteLine()
                Console.WriteLine(" #####")
                Console.WriteLine("# {0}  ", Row0 & " # ")
                Console.WriteLine("# {0}  ", Row1 & " # ")
                Console.WriteLine("# {0}  ", Row2 & " # ")
                Console.WriteLine(" #####")
                'ループを抜け出した先の分岐
            Loop Until Gameover = 1 Or Gameover = 2 Or Gameover = 3 Or Gameover = 4

            '結果出力 
            If Gameover = 1 Then
                Console.WriteLine()
                Console.WriteLine(" 試合終了 Player1 「{0}」の勝利!!!!!", WinPlayer)
                Console.WriteLine(" Rキー入力で名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
            ElseIf Gameover = 2 Then
                Console.WriteLine()
                Console.WriteLine("試合終了 Player2 「{0}」の勝利!!!!!", WinPlayer)
                Console.WriteLine("Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
            ElseIf Gameover = 3 Then
                Console.WriteLine()
                Console.WriteLine("  ゲームを終了します。")
                Console.WriteLine("   Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
            ElseIf Gameover = 4 Then
                Console.WriteLine()
                Console.WriteLine(" 引き分け ")
                Console.WriteLine("Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
            End If
        Loop While Console.ReadKey.Key = ConsoleKey.R 'Rキーを押すと名前入力画面(最初に)に戻る
    End Sub

    Private Function SenkouKOukouDisp(LoopCount1 As Integer, P1name As String, P2name As String, WinPlayer As String) As String

    End Function
End Module

勝敗判定を訂正しました。アドバイスをお願いします。

引用返信 編集キー/
■92708 / inTopicNo.4)  Re[3]: 三目並べ 完成?
□投稿者/ みい (102回)-(2019/10/21(Mon) 18:42:55)
No92655 YuOさんの「手順を踏むとよいでしょう。」以下のアドバイスが
活かされていないように見受けられます。

例えば...
> table(0, 0) = " "
> table(0, 1) = " "
> table(0, 2) = " "
> table(1, 0) = " "
> table(1, 1) = " "
> table(1, 2) = " "
> table(2, 0) = " "
> table(2, 1) = " "
> table(2, 2) = " "
スペースを入れる処理を繰り返しているだけなので、
単純に考えてもFor文で配列のインデックスを回すだけでも
まとまりますよね。

> '結果出力 
> If Gameover = 1 Then
> Console.WriteLine()
> Console.WriteLine(" 試合終了 Player1 「{0}」の勝利!!!!!", WinPlayer)
> Console.WriteLine(" Rキー入力で名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
> ElseIf Gameover = 2 Then
> Console.WriteLine()
> Console.WriteLine("試合終了 Player2 「{0}」の勝利!!!!!", WinPlayer)
> Console.WriteLine("Rを押すと名前入力画面に戻ります。R以外のキー入力をするとゲームを終了します。")
ここも違いは「Player『1』」「Player『2』」
『1』と『2』が入っている変数は...と考えるとまとめる事ができますよ

引用返信 編集キー/
■92777 / inTopicNo.5)  Re[4]: 三目並べ 完成?
□投稿者/ aiti (10回)-(2019/10/29(Tue) 17:10:05)
No92708 (みい さん) に返信

Dim table(2, 2) As String
For i = 0 To 2
For j = 0 To 2
table(i, j) = " "
Next
Next
こんな感じにしたらできました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ