VBAでオセロをつくろう! その1
コードを書いていて思うことは。
目的の機能を書くことは難しくない。
抽象化して書くことは難しい。
ということ。
抽象化して書いているつもりでも
後で振り返ると無駄が多かったり。
重複した処理を書いていたり。
まだまだ修行中です。。
とりあえず。
オセロver01書きました。
- できること
手動で対戦ゲームができます。
たぶん一番シンプルな機能です。
- コード
メイン
Public rp As Range
Public field As Range
Public n As Integer
Public c As Range
Public stone As Variant
Public turn As Variant
Private Sub Worksheet_Activate()
'シートの状態を設定
Cells.ClearContents
Call 基礎値共有(rp, n, field, c, stone, turn)
Call フィールド形成(rp, field, stone, n)
c.Value = 0
c.Offset(1, 0) = turn(0)
End Sub
Private Sub Worksheet_SelectionChange(ByVal target As Range)
Call 基礎値共有(rp, n, field, c, stone, turn)
Dim flag As Boolean
Dim tmp As String
Dim d(1) As Integer
Dim q(1) As Integer
q(0) = c Mod 2
q(1) = (c + 1) Mod 2
'手番の表示
c.Offset(1, 0) = turn(q(0))
'場外判定
flag = field_alart(target, field, flag)
If flag = True Then
Exit Sub
End If
'targetの周囲の認識
For i = 0 To 8
d(0) = i Mod 3 - 1
d(1) = i \ 3 - 1
tmp = target.Offset(d(0), d(1)).Value
If tmp = stone(q(1)) Then
'石を置けるのかの判定とおけた場合の処理
Call 置けるかの判定(target, stone, d, q, n, flag)
End If
Next
'石が置けない場合の処理
If flag = False Then
Exit Sub
End If
'クリック数と手番の更新
Call クリック数のカウント(n, c)
c.Offset(1, 0) = turn(q(1))
'Call 手番の表示(c, turn, q)
End Sub
サブ
Sub 基礎値共有(rp, n, field, c, stone, turn)
Set rp = Cells(2, 2) 'フィールド形成の定点の定義
n = 8 '盤面の大きさの定義
Set field = Range(rp, rp.Offset(n - 1, n - 1)) 'フィールドの定義
Set c = rp.Offset(0, n + 2) 'カウントセルの指定
stone = Array("●", "○") '黒石と白石の定義
turn = Array("黒番", "白番") '手番プレートの定義
End Sub
Sub フィールド形成(rp, field, stone, n)
'フィールドのヴィジュアル定義
With field
.ClearContents
.Rows.RowHeight = 50
.Columns.ColumnWidth = 8
.Interior.Color = RGB(200, 200, 200)
.Borders().LineStyle = xlContinuous
End With
'初期配置
With rp
.Offset(n / 2 - 1, n / 2 - 1) = stone(0)
.Offset(n / 2, n / 2) = stone(0)
.Offset(n / 2 - 1, n / 2) = stone(1)
.Offset(n / 2, n / 2 - 1) = stone(1)
End With
End Sub
Function field_alart(target, field, flag) As Boolean
'targetがfield内の場合にtrueを返す
If Application.Intersect(target, field) Is Nothing Then
field_alart = True
Else
field_alart = False
End If
End Function
Sub 置けるかの判定(target, stone, d, q, n, flag)
Dim tmp As Range
Dim stock As Range
Set tmp = target
mystone = stone(q(0))
Set stock = tmp
For i = 1 To n - 1
Set tmp = tmp.Offset(d(0), d(1))
Select Case tmp.Value
Case Is = ""
Exit For
Case Is = mystone
stock = mystone
flag = True
Exit For
Case Else
Set stock = Union(stock, tmp)
End Select
Next
End Sub
Sub クリック数のカウント(n, c)
Dim tmp As Integer
c.Value = c.Value + 1
End Sub
- 思ったこと
オセロにおいては。
選んだ場所に石が置けるかどうか。
がミソです。
その場所がよい場所かどうか。
が次のポイントですね。
解析をするにしても仮想の敵を作るにしても。
- 次の予定
次は仮想の相手を用意したいのですが。
いきなりは難しいかなと思うので。
次に置けるポイントを☆で示す。
それぞれのポイントの良し悪しを評価する要素を設ける。
の2点を書こうかなと思います。
ではでは。