滝の音

滝の音

名こそ流れてなお聞こえけれ

VBAでオセロをつくろう! その2 次における場所を表示できるようになった!

その2では以下の3つを行います。

 

根幹プログラムの更新

新機能の増築

 

  • 根幹プログラムの更新

メイン

Dim rp As Range         'フィールド形成の定点の定義
Dim n As Integer        '盤面の大きさの定義
Dim field As Range      'rpとnでフィールドの定義
Dim c As Range          'カウントセルの定義
Dim stone As Variant    '黒石と白石の定義
Dim turn As Variant     '手番プレートの定義

Private Sub Worksheet_Activate()
 'シートの状態を設定
 Cells.ClearContents
 Call 基礎値共有(rp, n, field, c, stone, turn)
 Call フィールド形成(rp, field, stone, turn, c, n)
 
End Sub

Private Sub Worksheet_SelectionChange(ByVal target As Range)
 
 Call 基礎値共有(rp, n, field, c, stone, turn)
 
 Dim flag As Boolean    'flagはプロシージャを抜ける判定に使う
 Dim tmp As Range       '周辺認識用
 Dim stock As Range     '周辺認識用
 Dim d(1) As Integer    '周辺認識用
 Dim q(1) As String     'q0が自分の石でq(1)が相手の石
 
 q(0) = stone(c Mod 2)
 q(1) = stone*1
    Set stock = tmp
    If stock <> q(1) Then GoTo L1
        '周辺マスが敵の石だった場合の処理
    Do
        Set tmp = tmp.Offset(d(0), d(1))
        Select Case tmp
            Case Is = q(0)
                stock = q(0)
                target = q(0)
                flag = True
            Case Is = q(1)
                Set stock = Union(stock, tmp)
            Case Else
                Exit Do
        End Select
    Loop
L1:
 Next
 
 '石が置けなかった場合はプロシージャから抜ける
 If flag = False Then
    Exit Sub
 End If
 
 'クリック数と手番の更新
 c.Value = c.Value + 1
 c.Offset(1, 0) = turn(c Mod 2)
 
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, turn, c, n)
'フィールドの見た目を定義
With field
    .ClearContents
    .Rows.RowHeight = 50
    .Columns.ColumnWidth = 8
    .Interior.Color = RGB(200, 200, 200)
    .Borders().LineStyle = xlContinuous
 End With

'最初の4石を置く
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
 'カウントセルと手番の表示
 c.Value = 0
 c.Offset(1, 0) = turn(0)
End Sub

 

その1のプログラムとの違いをつらつらと。

 

余計なcallを削った。

これが一番ですね。

なんでもcallするのが格好いい気がしていたのですが

逆に見にくいなと思って書き換えました。

フィットするレベルはまだ模索中。

 

コメントの書き方を変えた

dimの段階でこれは何をするものですよーと書いたほうがいいかなと思って書き換えました。

このあたりのデザインセンスは磨き続けるしかないですよね。。

あんまり他人の書いたコードを読んだことがないので

それをすれば適したところがわかるのかな。。

 

プログラミング1列ずつの細かい説明は面倒なので需要がない限りは省略します。。

 

  • 新機能の増築

新機能は2つ。

星をつける(次における場所に☆をつけ、その際にひっくり返せる相手の石の数を示す)

星をはずす(上の星と数字を消す)

 

Sub 星をつける()


 Dim target As Range
 Dim first As Range
 Dim found As Range
 Dim q(1) As String
 Dim d(1) As Integer
 Dim cnt As Integer
 
 Call 基礎値共有(rp, n, field, c, stone, turn)
 q(0) = stone(c Mod 2)
 q(1) = stone*2
        If tmp <> q(1) Then GoTo L1
       
        Do
            Set tmp = tmp.Offset(d(0), d(1))
            Select Case tmp
                Case Is = q(0)
                    cnt = cnt + 1
                    target = "☆" & cnt
                    Exit Do
                Case Is = q(1)
                    cnt = cnt + 1
                Case Else
                    Exit Do
            End Select
        Loop
L1:
    Next
   
    If target.Address = first.Address Then
        Exit Do
    End If

 Loop
 
End Sub

 

Sub 星を消す()
 Dim target As Range
 Dim first As Range
 Dim found As Range
 Dim q(1) As Integer
 
 Call 基礎値共有(rp, n, field, c, stone, turn)

 Set target = field.Find("☆", lookat:=xlPart)
 If target Is Nothing Then
    Exit Sub
 Else
    Set first = target
 End If
 
 target = ""
 Do
    Set target = field.FindNext(target)
    If target Is Nothing Then
        Exit Do
    Else
        target = ""
    End If
 Loop
 
End Sub

 

仮想の相手を作る際の両輪は。

おける場所を示すこと。

そこに置く価値を示すこと。

とりあえずボロボロながらも両方を設けました。

 

そこに置く価値はもう少し書かないとなぁ。

ただ自分がオセロ詳しくないので

強い敵を作るにはすこしオセロを勉強せねばなりませんが。。

 

そこまでのやる気はなさそうだな笑

 

  • 今後の予定

とりあえず仮想の敵を実装するのが次の課題ですね。

まぁもうほとんど部品はできているので

あとはそれを組むだけなのですが。

 

って。

そういうことはつくってから言いますね笑

 

ではでは。

 

 

 

 

*1:c + 1) Mod 2)
 
 
 'targetがフィールド外であればプロシージャから抜ける
 If Application.Intersect(target, field) Is Nothing Then
    Exit Sub
 End If
 
 'iでターゲットの周辺を認識
 
 For i = 0 To 8
    d(0) = i Mod 3 - 1
    d(1) = i \ 3 - 1
    Set tmp = target.Offset(d(0), d(1

*2:c + 1) Mod 2)

 Set target = field.Find("")
 If target Is Nothing Then
    Exit Sub
 Else
    Set first = target
 End If
 
 Do
    cnt = 0
    Set target = field.FindNext(target)
   
    For i = 0 To 8
        d(0) = i Mod 3 - 1
        d(1) = i \ 3 - 1
        Set tmp = target.Offset(d(0), d(1

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点を書こうかなと思います。

ではでは。

 

久しぶりの更新。次の矛先?

おはようございます。

めちゃ久しぶりの更新です。。。

 

最後に更新してからずっとジムに行っていないですねー。

やる気が消えてしまったのでまたやりたくなるまで休憩中です。

 

思い返すと昨年の9月くらいから筋トレばっかり記事を書いていましたねー。

筋トレブログなのかってくらい

筋トレの記録ばっかり書いていました笑

 

筋トレ欲はまだそこまで戻ってきていないのですが

ブログ書きたい欲は戻ってきたので

また何かについて書こうかなーと思って今書いています。

 

最近一番時間を使っているのはプログラミングですねー。

ほんのちょっぴりjavaもやってみたのですが

結局VBAを扱っています。

 

最近は特にシミュレーションを書くことに興味を持っています。

 

ということで。

 

しばらくは「プログラミング日記」を始めます。

 

自分はひとつのことを深く掘り下げるのがあまり得意ではないので

おそらくいくつかのジャンル(種類?)のものを並べて進めていくと思います。

今考えている候補は

  • オセロ
  • 将棋
  • 囲碁
  • マージャン
  • 街づくり
  • 戦略ゲーム(ちょっと名前がわからないので仮に)

 

 

あたりです。

実はこのうちの3つはすでに多少触れています。

 

それぞれの候補によって内容はもちろん違うと思いますが

  • CP(仮想の相手)を再現する
  • 解析に扱う
  • クオリティを高める

あたりが行き着く先なのかなと思っています。

進めてみないとわからないですね。。

 

とりあえず今回はこんな感じで。

次の記事ではオセロについて書こうかなと思っています。

ではでは。

 

実験 5*5高頻度ルーティーンって効果あるの? その11(take1)

先に話しておくと
今回のワークアウトは5セット目が5rep上がりませんでした。。
という事でタイトルに(take1)をつけました。

  • 5*5高頻度ルーティーンって?

  • 体重

67.5kg

前回と同じ体重だが
かすかに腹筋が見える感じ。
ウェストもだいぶ細くなった気がします。
そのせいか分かりませんが
いつもはいているジャージの長ズボンがパツンパツンでスクワットしにくかったです。。
次回はとりあえず半ズボンでやります。
 

  • ワークアウト

スクワット
75.0kg 5
80.0kg 5
85.0kg 5
90.0kg 5
95.0kg 2
90.0kg 2


セット間の休憩時間 2.0min
5,6セット間は休憩時間なし。

  • 感想

正直90.0kgの時点でちょっとふらついていたので
95.0kgは無理かなーと思いながら取り組んでしまいました。。
そのせいもあってか達成できず。。

言い訳をしてみると。
ジムについてパワーラックが空いていなかったので先に胸と三頭のワークアウトを行ってしまったことくらい。。

でもそんなの関係ないレベルで達成できませんでした。
90kgあたりの重量に少しなれる必要がありそう。

でもその方法はこのワークアウトを行うことなんだろうなー。

ま。
次回とりあえずtake2やってみます。
体重を500g増すのを休養中のノルマにします!
 

実験 5*5高頻度ルーティーンって効果あるの? その10

このワークアウトは5/3の夜に行いました。

最近はジムから家に帰るとご飯食べてすぐ寝てしまう。。。

 

この企画もようやく第10回。

そろそろハイレップでみっちりスクワットしたい欲にあふれています笑

そのためにもさっさと16回までクリアしてしまいたい。。。

 

- 5*5高頻度ルーティーンって?


- 体重
67.5kg

腹筋が隠れてしまった。

さすがに一気に体重を増やしすぎたか?

パワーベルトもちょっと苦しかった。。。

 

- ワークアウト
スクワット
70.0kg 5
75.0kg 5
80.0kg 5
85.0kg 5

90.0kg 5

セット間の休憩時間 1.5min

 

- 感想

前回に85kg10rep行ったこともあって

85kg自体にはそこまで感情がわかなくなりました。

まぁ軽いなぁと思えるほどではないけど。

 

90kgはまだ重いなぁと思ってしまいます。

1set目に持ってくれば10repできる気はするがどうだろう。。

 

この高頻度ルーティーンの実験とは別に

100kg10repが今見据えている目標です。

今のところ85kgまではクリアしています。

できれば90kgまではこの実験の片手間でクリアしてしまいたい。。

欲張りかな笑

 

なんやかんやでだんだんスクワットが好きになってきていて

それが今得ている一番の成果なのかな~

好きなことなら遅かれ早かれ伸びるだろうし笑

 

 

実験 5*5高頻度ルーティーンって効果あるの? その9 (+おまけ スクワット85kg10repクリアー!)

4/29にジムに行ってきました。

前回の脚トレ日から3日空いてしまいましたが

シンプルに筋肉痛が抜けるのを待っていただけでした。

 

90kg5repはまだだいぶダメージが残るのかな。

久しぶりにレッグエクステンションやったからかな。

 

- 5*5高頻度ルーティーンって?


- 体重
66.0kg
ちょっと回復。

3月後半は70kgあったのにな~。。

 

- ワークアウト
スクワット

65.0kg 5
70.0kg 5
75.0kg 5
80.0kg 5
85.0kg 10

セット間の休憩時間 1.5min

 

- 感想

なんかめちゃパワーアップしてました。。

65kgの時点で、あれ、重量間違えたかなってくらい軽く感じました。

 

いつもどおり5*5で終わらせようと思って4セット目までやっていたのですが

なんかできそうな気がする。。

試さずにはいられない!!

 

ということで85.0kg10repチャレンジしてしまいました笑

 

結構ぎりぎりでしたがなんとかクリア!

 

RM換算では110.5kgですね。

確か今までのRM換算上のマックスは105kgあたりだったので

5kgアップ!!

やったね!!

 

んーなんか本当に急に強くなった気がします。

前回の90kg5repがすごいいい具合に筋肉を刺激したのか。。

単にスクワットに慣れてきたのか。。

5*5高頻度ルーティーンの効果なのか。。

 

ちょっとよくわからないです笑

体重は一時期よりはかなり少ないのですが。

 

理由はわからないけれどいい風が吹いている!

この流れをきらないためにも補助種目は行わず

できるだけ早く次の脚トレ日を迎えられるようにします!

 

次回は5セット目に90kgを扱います。

正直10repチャレンジしたくてしょうがないけどまだ危ない気がするのでやめておきます。。

テンションがあがってもやらない笑

 

やるとしたらday12ですかね。

というか。

day10で我慢する代わりにday12では絶対にやる!!

 

あ。

話は変わりますが。

パワーラック待ちの間に久しぶりにダンベルプレスやりました。

前回はポジショニングに苦しみましたが今回は特に不満なく行えました。

ただめっちゃフラフラしちゃいます。

20kg 10

22kg 10 10

で行ったのですが。。

とにかくフラフラ笑

 

正直もうちょっと重量上げても余裕そうなのですが

こんなにフラフラしていいのだろうかと思って抑えています。

しばらく22kgでフォームを安定させるのが課題です。。

 

スクワットの次はダンベルプレス30kg10rep挙げるまで~のチャレンジ企画をやろうかなと考えています。

まあそんな先のことを話していたら鬼に笑われちゃいますね。

 

きょうはここまで。

 

実験 5*5高頻度ルーティーンって効果あるの? その8

かなり日にちが空いてしまいました。
ちょっと落ち込むことがあって
ジムに行けていませんでした。

今日は気持ちを切り替えるために無理矢理ジムへ行きました笑
運動ってこういう側面もあるんですね笑

  • 5*5高頻度ルーティーンって?

  • 体重

65.2kg
気分の落ち込みと体重の減少がリンクしているタイプの人間です。
ちょっとげっそりしてしまった。。

  • ワークアウト

スクワット
70.0kg 5
75.0kg 5
80.0kg 5
85.0kg 5
90.0kg 5

レッグエクステンション
30.0kg 15
35.0kg 15
30.0kg 15

  • 感想

90.0kg 5レップ初クリアです!
90.0kgにちょっとびびってしまいましたが
ギリギリクリア笑

もしかしたらしゃがみこむ深さがハーフまでいっていなかったかもしれませんが。。

まぁ次々回のワークアウトでまた90.0kgに触れることになるので
その時には文句無しの深さで行います!

あと体重戻さないと。。