tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルVB .NET 2003でゲーム
記事No7008
投稿日: 2008/02/12(Tue) 22:58
投稿者さぁら
私は現在、VBで二角取り(四川省)のゲームを作っています。
そこで、二角取りの牌を取れる条件の定義がわからないので質問します。

参考になるソースのあるサイトや、二角で取れる条件のソースが分かれば教えてください。
自分で書いてて内容がおかしいのは分かってますが、分かる方お願いします。

[ツリー表示へ]
タイトルRe: VB .NET 2003でゲーム
記事No7009
投稿日: 2008/02/13(Wed) 09:31
投稿者よねKEN
> 私は現在、VBで二角取り(四川省)のゲームを作っています。
> そこで、二角取りの牌を取れる条件の定義がわからないので質問します。

「二角取り(四川省)」と言われてわからなかったのでGoogleで検索してみました。
以下のようなすごく参考になりそうなページが見つかりましたが、参考になりませんか?

Wikipedia - 四川省 (ゲーム)
http://ja.wikipedia.org/wiki/%E5%9B%9B%E5%B7%9D%E7%9C%81_(%E3%82%B2%E3%83%BC%E3%83%A0)

こちらの定義だけを見るとなかなかややこしそうに見えるルールですが、

3LINES - 「二角取り」「四川省」と呼ばれる牌パズルゲーム
http://www.gamedesign.jp/flash/lines/lines_jp.html

こちらと合わせてみるとルールは理解できると思います。

> 参考になるソースのあるサイトや、二角で取れる条件のソースが分かれば教えてください。

まず盤面をデータ上でどのように表現するかを考え、
合わせて取れる/取れないの条件判定を考える必要がありますね。
この部分が一番重要で、かつ、一番面白いところだと思うので頑張ってください。

このくらいの複雑さになるといきなりソースを見ても理解するのは難しいと思いますので、
解き方の考え方を解説しているサイトを探してみるとよいかもしれません。
「四川省 アルゴリズム」などで検索してみることをお勧めします。

また、もしこういうパズル系のプログラム作成が初挑戦なのであれば、
このルールはそこそこ難易度高めだと思いますので、
これを完成にこぎつけるために必要な知識を身につけるために、
もう少し難易度の低いリバーシ(オセロ)(ただし、駒をひっくり返すロジックだけ)を作ってみるのもよいかもしれません。

[ツリー表示へ]
タイトルRe^2: VB .NET 2003でゲーム
記事No7014
投稿日: 2008/02/13(Wed) 23:39
投稿者さぁら
> 解き方の考え方を解説しているサイトを探してみるとよいかもしれません。
> 「四川省 アルゴリズム」などで検索してみることをお勧めします。
>
> また、もしこういうパズル系のプログラム作成が初挑戦なのであれば、
> このルールはそこそこ難易度高めだと思いますので、
> これを完成にこぎつけるために必要な知識を身につけるために、
> もう少し難易度の低いリバーシ(オセロ)(ただし、駒をひっくり返すロジックだけ)を作ってみるのもよいかもしれません。

なるほど、わかりました。
いろいろ探してみます。
ありがとうございました。

[ツリー表示へ]
タイトルRe^3: VB .NET 2003でゲーム
記事No7071
投稿日: 2008/02/22(Fri) 16:27
投稿者さぁら
わからなくなったのでまた質問します。
現在、
        For y = 0 To 7
            For x = 0 To 16
                n = n + 1
                btn(n) = New Button
                btn(n).Parent = Me
                btn(n).Tag = n
                btn(n).Text = ""
                btn(n).TextAlign = ContentAlignment.MiddleCenter
                btn(n).SetBounds(23 * x + 23, 31 * y + 31, 23, 31)
                Controls.Add(btn(n))
                AddHandler btn(n).Click, AddressOf ButtonClick
            Next
        Next

            For y = 0 To 33
                fname = "hai" & (1 + y).ToString() & ".gif"
                haif(y) = Image.FromFile(fname)
                btn(y).Image = haif(y)
                pict1(y) = y
                pict1(34 + y) = y
                pict1(68 + y) = y
                pict1(102 + y) = y
            Next
と名前で判定をやっていますが、いくら頭を使っても消える判定ができません。
やはり配列に入れないとダメでしょうか?
といっても配列に入れる方法もわからないのでお手上げ状態です。
とりあえず、隣接したボタンを押せば消えるという処理をしたいのですが、教えていただければと思い、投稿しました。

[ツリー表示へ]
タイトルRe^4: VB .NET 2003でゲーム
記事No7080
投稿日: 2008/02/23(Sat) 03:34
投稿者よねKEN
> と名前で判定をやっていますが、いくら頭を使っても消える判定ができません。

と書かれていますが、「名前で判定」というのはどこでやっているのでしょうか?
提示のコードで書かれているのは
・ゲーム盤面上8 * 17の牌をボタンを使って表現
・34種類の牌のイメージの読み込み
の2点だけのようですが(一部不明なコードも)、肝心のその牌をどうこうする処理がないようです。

> やはり配列に入れないとダメでしょうか?
> といっても配列に入れる方法もわからないのでお手上げ状態です。

いきなり大きな盤面でやろうと考えず、小さな盤面で考えてみてください。
・3 * 4 の盤面
・牌の代わりに1,2,3という数字で牌を表すものとします。
・牌の置かれていない場所は0で表します。
・四川省のルールを考慮して、データ構造上は5 * 6の配列で表します。(X=0〜4、Y=0〜5)

例えば、以下は初期状態の盤面のイメージです。
  01234 X
  -----
0|00000
1|03230
2|01310
3|03120
4|02110
5|00000

Y

これをVBで表すなら、例えば、以下のような2次元配列の表現で表せます。
(ロジックを考える上では見た目は重要ではありませんので、コンソールプログラムで書いてます。)

Module Program
    Private board As Byte(,)

    Sub InitBoard()
        board = New Byte(,){ _
             {0,0,0,0,0}, _
             {0,3,2,3,0}, _
             {0,1,3,1,0}, _
             {0,3,1,2,0}, _
             {0,2,1,1,0}, _
             {0,0,0,0,0}  _
        }
    End Sub

    Sub DisplayBoard()
        ' 現在の盤面の状態を表示
        For y As Integer = 0 To 5
            For x As Integer = 0 To 4
                Console.Write("{0} ", board(y,x))
            Next
            Console.WriteLine()
        Next
    End Sub

    Sub Main()
        InitBoard()
        DisplayBoard()

        ' コンソールプログラムのため、実行したらすぐにDOSプロンプトが閉じてしまうため
        ' エンターキー押下まで待つ
        Console.Write("Press Enter key to finish ...")
        Console.ReadLine()
    End Sub

End Module

で、この配列を使ってごにょごにょすれば、四川省で必要な内部情報は扱えるようになりますが、
長くなるので、とりあえずここまでのヒントで頑張ってみてください。

> とりあえず、隣接したボタンを押せば消えるという処理をしたいのですが、教えていただければと思い、投稿しました。

「隣接したボタンを押せば消える」というのは隣り合った同じ牌があったら消せるようにするということだと思いますが、その前に、二つのボタンを選択できるように作りこむのが先になりますね。

考え方としては、

(1) 1つ目のボタンが押された → 1つ目に押されたボタン(牌の種類と座標)を覚えておく
(2) 2つ目のボタンが押された → 2つ目に押されたボタン(牌の種類と座標)を覚えておく
(3) 覚えておいた1つ目、2つ目のボタンの座標と牌の種類から消せるかどうかを判定する
    →隣接した牌のみ消せるというルールの場合、
      (3)-a  2つの牌が同じか? → 同じでなければ消せない、同じなら(3)-bの判定へ
      (3)-b  1つ目と2つ目の座標のX軸、Y軸のどちらかの方向だけが前後1異なる → その通りなら牌は消せる

という判定になりますね。

[ツリー表示へ]