Visual Basic(VB)で簡単なマインスイーパを作ってみる
1 :
以下、名無しにかわりましてVIPがお送りします :
2008/08/26(火) 23:06:38.82 ID:dO4d+VlW0 プログラミングの練習に作ろうと思ってるんだ。 俺のプログラミングレベルは初心者。 VBは授業で少し習った程度。 プログラミングできる人がいればアドバイスください。
∧_∧ ピュー (´・ω・`) <これからも山崎誠を応援して下さいね。 =〔~∪ ̄ ̄〕 = ◎――◎
3 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:07:56.06 ID:dO4d+VlW0
とりあえずボタンを押したらボムを生成するプログラムを書いたんだけど、 この時点でなんか駄目っぽい感じがしますorz
4 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:08:19.66 ID:8BdFOIS2O
これがあの有名なインターネッツ
5 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:09:15.49 ID:iv+DehxI0
ついでに自動的にクリアする機能をつけて 延々と自動でマインスイーパをプレイし続けるソフトとかどうよ
6 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:10:18.22 ID:dO4d+VlW0
>>5 そこまでのレベルは今の俺には無理です。。
とりあえず今回は保留ということで
7 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:11:45.19 ID:dO4d+VlW0
ボム生成のアルゴリズムはどうしたらいいでしょうか? 俺には Do n = Int((Rnd() * 479) + 0) If mine(n Mod 16, n / 16) = False Then mine(n Mod 16, n / 16) = True i += 1 If i >= 99 Then Exit Do End If End If Loop こんなのしか思いつかなかったです。 しかしボタンを何度も押すとフリーズします。 どうしましょう。
>>5 のスクリーンセーバーがあったら欲しいな・・・
9 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:13:31.10 ID:dO4d+VlW0
10 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:13:37.34 ID:Ose8MH2m0
Do n = Int((Rnd() * 479) + 0) If mine(n Mod 16, n / 16) = False Then mine(n Mod 16, n / 16) = True i += 1 フリーズ = しないで If i >= 99 Then Exit Do End If End If Loop これでいいよ
11 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:15:44.73 ID:0xFpnW8r0
>>7 に関して説明不足でした。
99個のボムを生成します。
bool型の変数mineがtrueだとボムがそこに存在します。
13 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:19:37.79 ID:b9UFIhQk0
Basicはうろ覚えだけど n / 16じゃなくてn \ 16にすればいいんじゃね?
14 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:21:37.99 ID:itUhPjUJO
16 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:24:20.97 ID:vccygejD0
昔作ったけど、基本的に配列と再帰さえ分かってれば簡単にいけるな。
>>15 \は割り算の結果を整数で返す(小数点は切捨て)
/は実数で返すからな
あとDoの前にi = 0を追加しとけ
18 :
5 :2008/08/26(火) 23:25:19.46 ID:peXaWiRl0
>>17 ありがとう!
i =0は変数宣言の部分でしてました。
/ → \ にしましたがButtonを連続で何回もクリックするとフリーズするのは止まらず・・・
>>16 配列は理解してます。
再帰はなんとなく分かります。
再帰は何処で使いますでしょうか?
>>19 多分mineが全部Trueで埋まっちゃうから、iが99以上にならなくてフリーズするんじゃないの?
Doの前にmineを全部Falseにする処理を入れるべき
22 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:34:49.38 ID:dO4d+VlW0
>>21 ありがとう!
mineを全てfalseにする処理を入れたらフリーズしなくなりました!
23 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:36:53.59 ID:vccygejD0
>>19 マスをオープンしたときに、周りのマスに全く地雷がなかった場合、
その周りのマスもオープンしないといけない。そこで再帰を使う。
24 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:38:14.30 ID:dO4d+VlW0
25 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:40:12.03 ID:dO4d+VlW0
サテ次は何をしよう
26 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:41:46.45 ID:vccygejD0
選んだマスをオープンして周りのボム数を表示するようにしようぜ
27 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:42:16.65 ID:dO4d+VlW0
28 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:44:42.05 ID:itUhPjUJO
右クリックでチェックできるようにもしようぜ
For i = 0 To 30 For j = 0 To 16 senjo(i, j) = New PictureBox senjo(i, j).Width = 20 senjo(i, j).Height = 20 senjo(i, j).Left = i * 20 senjo(i, j).Top = j * 20 senjo(i, j).Enabled = True senjo(i, j).Visible = True If mine(i, j) = True Then senjo(i, j).BackColor = Color.Black Else senjo(i, j).BackColor = Color.White End If Next Next とりあえずボタンを押したらボムを黒、何も無いところを白く描くソースを書いてみた。 が、これもまた駄目みたい。 何も表示されません。 何故?
30 :
以下、名無しにかわりましてVIPがお送りします :2008/08/26(火) 23:56:29.07 ID:vccygejD0
いや、俺C言語しか分からんし・・・ senjo(i, j)はデフォルトではBackColorは何色なん? 指定しなくてもVisibleをTrueにしたら表示されるものなの?
デフォルトの設定が分からなかったのでとりあえず senjo(i, j) = Color.Whiteをコードに追加してみました。 結果:それでも表示されませんでした。 俺もVBが良く分からないです。 まだCのほうが簡単な気がする・・
C#とJavaScriptとPHPしかやったことないけど VBの構文がどうしても好きになれない。 文末に;無いし・・・forとかifとかまったく違うし・・・
33 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:03:58.06 ID:Spja4ebR0
PictureBoxを表示させた事はあるの?
>>32 俺もパッと見、意味は分かるけど、気持ち悪いと思うこれ
34 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:05:15.20 ID:Megce38d0
とりあえずForとかmineとか無視して 1つPictureBoxを表示させてみろ、話はそれからだ。
VBの構文って、名前の通り昔のBASICから来てるので、 見慣れない人は辛い。 つうか、今では俺も辛い
>>32 凄くよく分かります。
Cのほうがシンプルで素敵・・・
>>33 普通にツールボックスから引っ張ってきてました。
ソースコードから生成するのは初めてです。
>>34 了解です。
今覚えばソースコードでPictureBox作成するの初めてでした。
37 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:09:13.48 ID:YTBXXIlEO
今ならVB.netやる意味はないわな
38 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:12:01.66 ID:wJhOFow70
駄目だ。普通にピクチャーボックスを表示することすらできないorz senjo(0, 0) = New PictureBox senjo(0, 0).Width = 20 senjo(0, 0).Height = 20 senjo(0, 0).Left = i * 20 senjo(0, 0).Top = j * 20 senjo(0, 0).Enabled = True senjo(0, 0).Visible = True senjo(0, 0).BackColor = Color.White senjoの宣言はグローバルな場所で Dim senjo(30, 16) As PictureBoxって書いてます。
39 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:13:19.55 ID:wJhOFow70
間違えた。 i * 20とj * 20はそれぞれ10に脳内変換してください。
40 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:14:00.56 ID:Spja4ebR0
知らんがな 絶対にソースコードで生成しないといけないの?ポリシー? ツールボックスからの方が早くね? もしくはツールボックスから生成した時に出来たコードを参考にしてみるとか。 てかググったらすぐ出てきそうだけどな
>>40 マスの数は選べるようにしたいので、
ツールボックスからだと、個定数しか作成できないことない?
初めてやるなら、とりあえずマス目の個数変更は考えず固定で作って 出来たら変更できるように弄るってやったほうが良いと思うんだ。
配列で線引けばいいじゃん
44 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:23:40.01 ID:YTBXXIlEO
>>38 まさかとは思うがそれは作っただけじゃないか?
>>42 そうなんですが、ピクチャーボックスが配列になっていないと
単純なプログラムでも大変なことにならない?
46 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:24:33.10 ID:wJhOFow70
PictureBox を配列にしてるの? PictureBoxを1枚用意して、そこに描画するんじゃないのか?
48 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:26:58.43 ID:YTBXXIlEO
>>46 その前にVBなのかVB.netなのか教えてくれてもいんじゃないか?
>>47 !?
駄目だ。。俺の頭の弱さでは理解できない・・
>>48 VB2005です
┌┐┌┐┌┐┌┐┌┐ └┘└┘└┘└┘└┘ ┌┐┌┐┌┐┌┐┌┐ ※四角一つがPictureBox └┘└┘└┘└┘└┘ ┌┐┌┐┌┐┌┐┌┐ └┘└┘└┘└┘└┘ ┌┐┌┐┌┐┌┐┌┐ ・・・ こんなイメージで作ろうとしてる? └┘└┘└┘└┘└┘ ┌┐┌┐┌┐┌┐┌┐ └┘└┘└┘└┘└┘ ┌────────┐ │ .│ │ .│ │ ここに、 .│ じゃないのか? │ 升目分描画 .│ │ .│ │ .│ │ .│ └────────┘
51 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:29:49.47 ID:Spja4ebR0
Dim senjo(30, 16) As PictureBox の宣言方法じゃマスの数を可変に出来ないんじゃないかな・・・? と、C言語の脳みそで考えてみた。
52 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:31:04.39 ID:Spja4ebR0
>>50 俺は上を想像していたが、そもそもPictureBoxって何だw
その上にPictureを乗せるものなら、
>>1 のソースじゃ表示されないのは当たり前な気がするwww
53 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:31:19.55 ID:Megce38d0
ソース内で生成したPictureBoxって、
それをFormに結びつけるなにかをしなくていいんだっけ?
今のままじゃ、どこに表示したらいいのかVB君がわかんないんじゃね?
>>42 それはやりようによってはあとでの変更が大変なことにならないか?
>>50 画像の合成がめんどいと思う。
>>50 正にそんな感じで作ろうとしてました!
下のような方法もありましたね
>>51 とりあえずマインスイーパ上級が30*16なのでそれだけ用意しとけばいいかなぁと・・・。
>>52 よくわかんないです。
>>53 なるほど。結びつけかー。
ググってきます。
55 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:36:44.80 ID:Megce38d0
VB6の感覚で行くと、 PictureBoxは画像を表示するためのものだが、 とりあえず画像なしで表示しても枠だけ見えるはず。 枠を消す設定もできるが、デフォはONだった。VB6では、な。
56 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:36:57.67 ID:YTBXXIlEO
57 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:37:37.69 ID:Spja4ebR0
あれだな、アルゴリズムとかじゃなくて描画系で詰まるんだったら 俺とか何にも役に立たないな。。。
>>53 逆に上の方が面倒じゃないのか?
合成も何も、下は単に DrawImage なり DrawCircle すればって・・・ VBにそれがあるかどうか見ないと忘れたが
59 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:39:23.54 ID:Spja4ebR0
>>55 そーなんだ。地味に勉強になる・・・のか・・・このスレは。
どうせVB使うことはないだろうけど・・・。
>>53 確かにな。Win32で親ウィンドウを指定しないといけないのと同じ感覚だな。
60 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:40:19.72 ID:Spja4ebR0
>>58 なんとなくだけど、上の方が簡単な気がする・・・
61 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:41:49.69 ID:wJhOFow70
>>56 親切にありがとう!
Me.Controls.Add(senjo(i, j))を追加しただけで、上手くいくようになったよ!
これで描画系に詰まることはなくなったかな。
62 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:41:47.09 ID:Megce38d0
>>58 上なら、一つ一つのPictureBoxに、値が設定されたら画像を差し替えるって処理を入れれば
もうそれで済むはず。
絵の更新も必要なとこだけでいいしな。
合成しちゃうとやっぱりいろいろめんどうだと思うんだ。
CでWinAPIでやってんならもちろん下だけどな。
そもそも概念が違うから当たり前だが。
63 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:44:07.01 ID:Megce38d0
マインスイーパに必要な絵をリストアップするぞ ・蓋がしてある ・蓋がしてあってチェック済み ・オープン:空 ・オープン:爆弾 ・オープン:1〜8 欲を言えば ・オープン:爆弾、真っ赤 ・蓋がしてある:カーソル選択中 こんなもんだ。
64 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:46:10.81 ID:wJhOFow70
最初の描画に時間がかかるのはVBの仕様か・・・
よし、今度こそ
>>26 やってみます
65 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:48:31.50 ID:Megce38d0
正直、絵を用意するのがめんどいだろうから
最初はTextBoxかLabelにすりゃいいのにって思うんだけどね。
>>64 まずは単純に選択したマスだけ開けろよ。
いきなり再帰とか手つけんなよー
>>60 >>62 それ、描画だけじゃなくて、クリックとかのイベント考えて言ってるのか
一つ一つのPictureBoxに全部イベントのリスナくっつけて行き先一つにするのはいいとして、
クリックされたのがどれなのか、の判定してから配列上のデータとか識別して・・・ってやる事考えたらしんどくないか?って話なんだが
描画は楽かもしれないけどさ。 いま楽なだけじゃないのかと。
67 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:55:46.39 ID:Megce38d0
>>66 クリックイベントだって、クリックされたやつのインデックスって引数でとれるよね?
それを縦横で割るなりmodなりでxy求めるだけだべ?
下方式の場合、クリックされた座標をひとつひとつのサイズで割ってxyがどこだか求めて
…後の処理はどっちの方式でも同じじゃないか、と思うのだが。
PictureBox1 ・・・ 幅=横升目*1画像のwidth、高さ=縦升目*1画像のheight で、単に For y = 0 to 縦升目 For x = 0 to 横升目 e.Graphics.DrawImage(画像, x,y) ' 画像は升目の状態が詰まった二次元配列を元に切り替え Next x Next y ってやっとけば、イベント時にマウス位置から px = x/(升目一つの)width py = y/(升目一つの)height で求まるから、描画だけじゃなくてハンドリングも簡単じゃん、て話なんだが。 ・・・ただ結局本人がやりやすい方でやればいいと思うけど
69 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:55:58.20 ID:Spja4ebR0
>>66 分からん。なんとなくVBはオブジェクトごとにコード書いてくイメージ持ってるから、
PictureBoxがWin32でいうところのボタンコントロールみたいなイメージを持ってるんだ。
だから上の方が簡単なのかなとか思ったけど、それ自体が間違った想像なのかもしれないwww
>>67 >クリックイベントだって、クリックされたやつのインデックスって引数でとれるよね?
PictureBox の配列のインデックスの話だったら、自分で小細工しないと簡単には取れないと思うが、
VBだと他になんかあるのか?
71 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 00:59:35.45 ID:wJhOFow70
皆難しい話してやがるぜ・・・
誰かやっつけで20*20の
>>63 の画像を作ってくれると嬉しいです。
もちろん都合のいいお願いだと思うので無視してくださってOKです。
Draw_Line使うんじゃないのか
74 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:07:55.44 ID:Megce38d0
>>71 とりあえず、上のやり方は今楽なだけで、多分詰まるぞ。
>>67 が言う、「クリックしたPictureBoxが何番目のモノなのかが簡単にわかる方法」 ってのが無い限り。
・・・・もちろんやりようはあるけど、遠回りにはなると思う。
上の方法で配列の何番目なのかを特定する方法
方法1.Hashtable 的な物に名前と位置の値を記録して、クリック時に特定する
方法2.Nameプロパティに数字を仕込んどいて、それをParseInt する
こんな小細工しないとうまくいかなくなる、多分。で、普通はやらない
76 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:15:21.23 ID:Spja4ebR0
>>75 VBって各PictureBoxにメニューハンドルみたいなのはつけれないの?
>>74 いやそれ普通だと思うけど。合成って言い方があれだけど、単に FromImageで コンテキスト作って DrawImage 重ねてSaveしてるだけでは。
一つのPictureBox に1回しか DrawImage 出来ないだったら問題だけど、それは無い。
78 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:19:17.59 ID:wJhOFow70
選んだマスをオープンさせるので詰まる俺ガイル
>>76 >VBって各PictureBoxにメニューハンドルみたいなのはつけれないの?
俺もVBはもうExcelでマクロ書くぐらいしか使ってないけど、メニューハンドルって言うか hwnd みたいな識別子持たせて
そこから対象を特定しようとすると、
>>75 の方法1みたいな事しないと、「それがどこの升目のモノなのか」 が特定できないよね
って、遠回りでもいいなら別にそれでもいいかもだけど
80 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:20:30.26 ID:Spja4ebR0
とりあえず
>>1 は先にCUIで作って、後でGUIを付けたらどう?w
81 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:22:23.29 ID:Megce38d0
とりあえず
>>1 合成がとくに問題ないということなので
PictureBoxは一つにする方式に変更した方がいい。
いまやってる選んだマスを開ける処理すら変わる事態だ。
まさか、クリックしたindexがとれないなんて思ってもなかったよ…
82 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:23:43.01 ID:wJhOFow70
>>80 実はVBでやってるのは理由があるんだ。
Cだったら確かに出来そうだ。
クリックをどうやって判別するんだ・・・?
>>81 取れるわけ無いだろwww 元々配列とインスタンスになんの関係も無いんだから
>>80 俺もそれがいいと思う。とりあえず完成させたいなら
84 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:24:29.72 ID:wJhOFow70
85 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:26:03.68 ID:wJhOFow70
一つのピクチャーボックスを分割していくつも画像を表示させたりできるの?
86 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:26:35.67 ID:Spja4ebR0
hwndみたいな識別子からPictureBoxを特定するのは 2重forループ回してhwndが一致するPictureBoxを探せばすぐ出来そうだけど、 プログラム的にカッコ悪いね。。。 それなら方法2のNameプロパティパースIntでsenjo(iName/10, iName%10)の方がまだマシだけど それもカッコ悪いってか。
87 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:27:09.50 ID:ERHSz7BF0
閏年考慮した時計を作ろうとしたが俺には無理だった
88 :
以下、名無しにかわりましてVIPがお送りします :2008/08/27(水) 01:28:58.16 ID:Megce38d0
>>83 取れるわけ無いだろ、って言われても。VB6では取れたんだからさ。
俺の脳内では、Formにaddしたときに、同じ名前のモノが複数きたら
それのindexを覚えてくれる的なことをしてくれるはずだった。
VB6と2005の壁はかなり厚いようだな…。
>>88 あぁ、同名が自動で配列にって奴か。Add順=indexみたいな。
それあるかも・・・ だけど Form1 に問い合わせて IndexOf とか、PictureBoxのインスタンスがメンバ持ってればいけるって事か
90 :
1 :2008/08/27(水) 01:37:59.32 ID:wJhOFow70
過疎ってきましたので、俺はそろそろ風呂に行こうと思います。 また明日の夜9時ぐらいに同じスレを建てます。
91 :
1 :2008/08/27(水) 01:39:47.39 ID:wJhOFow70
そのときはまたスレを覗いてくれると嬉しいです。 それでは! 皆ありがとう!
92 :
以下、名無しにかわりましてVIPがお送りします :
2008/08/27(水) 01:42:33.30 ID:Megce38d0 >>89 そういうのを自動でやってくれるのを自分で作ればいいのかね。
まあ俺はこれからもVBは6を使うさ。
>>1 まずはCUIで、もしくは
どこをクリックしたかはとりあえずTextBoxで入力して
表示も画像じゃなくてデバッグプリントでとかなんとかってのは
俺も賛成
てなわけで乙。がんばれ。