2018年6月27日水曜日

EXCEL VBAで簡単倉庫番 その2

前回は荷物が押せるところまでを作りました。
今回はすべての荷物が正しい場所に置かれていることを判定できるようにします。
荷物を置く場所は※で表すことにします。
正しい場所にある荷物は●と表示しましょう。
プレイヤーがいる場所が荷物置き場かどうかも判断できないといけません。
荷物置き場にいる場合は▲と表示するようにしましょう。
●は正しい場所にある荷物、○は正しい場所にない荷物です。
○がなくなったらクリアです。
1回移動する度に○の数をチェックします。
毎回全部のセルをチェックするのは無駄な気もしますので、
最初に全部のセルをチェックし、その後は移動した荷物についてだけ増減させればいいでしょう。

前回と同様に次のコードをVBAのワークシートに貼りつければ出来上がりです。



☆☆☆↓ここから
Const YY = 2, XX = 12
Private Sub Worksheet_Activate()
Dim DATA(10) As String
KOSU = 0
CHARA = UCase(Cells(YY, XX))
If CHARA <> "E" Then
DATA(0) = "□□□□□□□□□□"
DATA(1) = "□/////□//□"
DATA(2) = "□//////□/□"
DATA(3) = "□/□□●□///□"
DATA(4) = "□//●▲●//□□"
DATA(5) = "□//□●□//□□"
DATA(6) = "□///○////□"
DATA(7) = "□///□/□//□"
DATA(8) = "□////////□"
DATA(9) = "□□□□□□□□□□"
Cells.ClearContents
CX = 0
For WY = 1 To 10
For WX = 1 To 10
CHARA = Mid(DATA(WY - 1), WX, 1)
CX = InStr("△▲○●□※", CHARA)
Select Case CX
Case 0
CHARA = " "
Case Is <= 2
   Cells(YY + 2, XX) = WY: Cells(YY + 2, XX + 1) = WX
  Case 3
    KOSU = KOSU + 1
  End Select
  Cells(WY, WX) = CHARA
Next WX
Next WY
Cells(YY - 1, XX) = "↑"
Cells(YY, XX - 1) = "←"
Cells(YY + 1, XX) = "↓"
Cells(YY, XX + 1) = "→"
Cells(YY + 3, XX) = KOSU
Columns("A:M").EntireColumn.AutoFit
Cells(YY, XX).Select
End If
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim OKIBA(3) As Integer
CHARA = UCase(Cells(YY, XX))
If CHARA <> "E" Then
dy = Target.row - YY: dx = Target.Column - XX
If Abs(dy) + Abs(dx) = 1 Then
CY = Cells(YY + 2, XX): CX = Cells(YY + 2, XX + 1)
NY = CY + dy: NX = CX + dx
NY2 = NY + dy: NX2 = NX + dx
CELL1 = Cells(NY, NX)
If Cells(CY, CX) = "▲" Then OKIBA(0) = 1
If CELL1 = "●" Or CELL1 = "※" Then OKIBA(1) = 1
If InStr("□○●", CELL1) = 0 Then
Cells(NY, NX) = Mid("△▲", OKIBA(1) + 1, 1)
Cells(CY, CX) = Mid(" ※", OKIBA(0) + 1, 1)
Cells(YY + 2, XX) = NY: Cells(YY + 2, XX + 1) = NX
End If
If CELL1 = "○" Or CELL1 = "●" Then
CELL2 = Cells(NY2, NX2)
If CELL2 = "※" Then OKIBA(2) = 1
If InStr("□○●", CELL2) = 0 Then
Cells(NY2, NX2) = Mid("○●", OKIBA(2) + 1, 1)
Cells(NY, NX) = Mid("△▲", OKIBA(1) + 1, 1)
Cells(CY, CX) = Mid(" ※", OKIBA(0) + 1, 1)
Cells(YY + 2, XX) = NY: Cells(YY + 2, XX + 1) = NX
Cells(YY + 3, XX) = Cells(YY + 3, XX) + OKIBA(1) - OKIBA(2)
If Cells(YY + 3, XX) = 0 Then Cells(YY, XX) = "E"
End If
End If
End If
Cells(YY, XX).Select
End If
End Sub
☆☆☆↑ここまで


今回面データは配列DATAに入れておいて展開しています。
この部分を書きかえれば好きな配置で遊ぶことができます。
空白セルは「/」にしておきましたが、△▲○●□以外は空白と判断します。
壁で囲まれているという前提でプログラムは作られています。
データがおかしいと変な動きをしたりエラーになったりします。
クリアしてもマクロが動かなくなるだけで特に演出はありません。
L2のセルの「E」をクリアしてシートを切り替えれば再び動くようになります。
プレイヤーのY座標の下に残りの荷物(○)の数の表示を追加しました。
やっていることはコードを読めば大体理解できると思います。
配列OKIBAについてだけ説明しておきます。
これはある場所が荷物置き場かどうかを判定するための配列です。
荷物置き場の場合には値が1となり、そうでない場合は0です。
OKIBA(0)は移動前のプレイヤーの位置の情報、
OKIBA(1)は進行方向に1マスの位置、プレイヤーの移動予定先の情報、
OKIBA(2)は進行方向に2マスの位置の情報です。
荷物を押すときには、進行方向に1マスの位置から2マスの位置に荷物が移動しますので、
○の個数の増減はOKIBA(1)-OKIBA(2)で計算できます。


これで一応倉庫番が遊べるようにはなりましたが、やはり見た目がさびしいですね。
セルに色をつけるとかオートシェイプを使うとかでもう少しそれっぽくならないかなと思います。
それから、こういうパズルでは一手戻す機能は是非ほしいところです。
さらに欲を言えばエディット機能が欲しいですね。
そのうち取り組みたいと思います。

0 件のコメント:

コメントを投稿