0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

白石さんと黒石さん

Last updated at Posted at 2019-10-17

:zero: 気晴らしに 緑の上で 戯れる

:one: 準備

'Sheet1.cls
Option Explicit
Const 位置 = "C3",  = 8,  = "●", サイズ = 36, 決定 = "{END}"
Dim 手番 As 配色
Private Enum 配色
    白石 = vbWhite
    黒石 = vbBlack
    盤面 = vbGreen
    盤外 = vbBlue
    思案 = vbCyan
    示唆 = vbYellow
End Enum
Private Function 裏(色 As 配色) As 配色
     = IIf( = 黒石, 白石, 黒石)
End Function
Private Property Get 今の色() As 配色
    今の色 = 手番
End Property
Private Property Get 次の色() As 配色
    次の色 = (手番)
End Property
Private Sub 攻守交替()
    手番 = 次の色
End Sub

:two: 舞台

Private Property Get () As Range
    Set  = Me.Range(位置).Resize(, )
End Property
Private Property Get 通知() As Range
    Set 通知 = Me.Range(位置).Offset(0,  + 1)
End Property
Private Property Get 状況() As Range
    Set 状況 = Me.Range(位置).Offset(2,  + 1).Resize(2)
End Property

Private Sub 盤面作成()
    ActiveWindow.DisplayGridlines = False
    With Me.Cells
        .Clear
        .Font.Size = サイズ
        .Font.Color = 盤外
        .HorizontalAlignment = xlHAlignCenter
        .VerticalAlignment = xlVAlignCenter
    End With
    With 
        .Interior.Color = 盤面
        .Font.Color = 盤面
        .Value = 
        .EntireColumn.AutoFit
        .EntireRow.AutoFit
        .Borders.LineStyle = xlContinuous
    End With
    With .Resize(2, 2).Offset( / 2 - 1,  / 2 - 1)
        Union(.Cells(1, 1), .Cells(2, 2)).Font.Color = 黒石
        Union(.Cells(1, 2), .Cells(2, 1)).Font.Color = 白石
    End With
    With 通知
        .HorizontalAlignment = xlHAlignLeft
    End With
    With 状況
        .Interior.Color = 盤面
        .Font.Bold = True
        .Value = "____"
        .EntireColumn.AutoFit
        .Borders.LineStyle = xlContinuous
        .Rows(1).Font.Color = 黒石
        .Rows(2).Font.Color = 白石
    End With
End Sub
Private Sub 手番通知()
    通知.Value = Join(Array(色名(今の色), "の番です"))
End Sub
Private Function 色名(色 As 配色) As String
    色名 = IIf( = 黒石, "黒", "白")
End Function

Private Sub 状況更新()
    Dim c As Range
    For Each c In 状況
        c.Borders(xlEdgeRight).Weight = IIf(c.Font.Color = 今の色, xlThick, xlThin)
        c.Value = (c.Font.Color)
    Next
End Sub
Private Property Get ( As 配色)
    Dim c As Range
    For Each c In 
        If c.Font.Color =  Then  =  + 1
    Next
End Property
Private Function 勝敗判定() As String
    Dim , , 結果 As String
     = (黒石)
     = (白石)
    Select Case True
        Case  > : 結果 = 色名(黒石)
        Case  < : 結果 = 色名(白石)
        Case Else: 結果 = "引き分け"
    End Select
    勝敗判定 = Join(Array(, "対", , "で", 結果))
End Function

:three: 開始

Sub 初期処理()
    盤面作成
    状況更新
    手番通知
    決定割当
End Sub

Private Sub 決定割当(Optional 設定 As Boolean = True)
    If 設定 Then
        Application.OnKey "+" & 決定, Me.CodeName & ".示唆表示"
        Application.OnKey 決定, Me.CodeName & ".置石実施"
    Else
        Application.OnKey "+" & 決定
        Application.OnKey 決定
    End If
End Sub
Private Sub Worksheet_Activate()
    決定割当 True
End Sub
Private Sub Worksheet_Deactivate()
    決定割当 False
End Sub

:four: 思案

Private Sub Worksheet_SelectionChange(ByVal target As Range)
    思案表示 target.Resize(1, 1)
End Sub
Private Sub 思案表示(置く場所 As Range)
    .Interior.Color = 盤面
    Dim col As Collection, c As Range
    Set col = 裏返る場所(置く場所, 今の色)
    If col.Count > 0 Then
        通知.Value = col.Count & "枚裏返ります。(Endで決定)"
        col.Add 置く場所
        For Each c In col
            c.Interior.Color = 思案
        Next
    Else
        通知.Value = "そこには置けません。(Shift+Endでヒント表示)"
    End If
End Sub
Private Function 裏返る場所(置く場所 As Range,  As 配色) As Collection
    Set 裏返る場所 = New Collection
    Dim x, y, c As Range, buf As Collection
    If Not 置く場所.Font.Color = 盤面 Then Exit Function
    For x = -1 To 1: For y = -1 To 1
        Set c = 置く場所(1)
        Set buf = New Collection
        Do: DoEvents
            Set c = c.Offset(x, y)
            Select Case c.Font.Color
                Case ()
                    buf.Add c
                Case 
                    For Each c In buf
                        裏返る場所.Add c
                    Next
                    Exit Do
                Case Else
                    Exit Do
            End Select
        Loop
    Next: Next
End Function

:five: 示唆

Sub 示唆表示()
    Dim col As Collection
    Set col = 置ける場所(今の色)
    Dim c As Range
    For Each c In col
        c.Interior.Color = 示唆
    Next
    通知.Value = "黄色の場所に置けます"
    伝言表示 "黄色の場所に置けます", 1
    .Interior.Color = 盤面
    Set c = col(1)
    c.Select
End Sub
Private Function 置ける場所(色 As 配色) As Collection
    Set 置ける場所 = New Collection
    Dim c As Range
    For Each c In 
        If 裏返る場所(c, ).Count > 0 Then 置ける場所.Add c
    Next
End Function
Private Sub 伝言表示(text As String, Optional sec As Integer = 1, Optional title = "伝言")
    CreateObject("WScript.Shell").Popup text, sec, title
End Sub

:six: 決断

Sub 置石実施()
    Dim c As Range, col As Collection
    Set col = 裏返る場所(置く場所:=ActiveCell, :=今の色)
    If col.Count = 0 Then Exit Sub
    col.Add ActiveCell
    For Each c In col
        c.Font.Color = 今の色
        c.Interior.Color = 盤面
    Next
    攻守交替
    終了判定
End Sub
Private Sub 終了判定()
    Dim パス As Boolean, 終了 As Boolean, 伝言 As String
    状況更新
    パス = (置ける場所(今の色).Count = 0)
    終了 = パス And (置ける場所(次の色).Count = 0)
    If 終了 Then
        伝言表示 勝敗判定, 5, "終了"
        初期処理
        Exit Sub
    End If
    If パス Then
        伝言 = Join(Array(色名(今の色), "の置ける場所がありません。一手パスします。"), "")
        伝言表示 伝言, 2, "パス"
        攻守交替
    End If
    手番通知
End Sub
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?