Logika di balik game seperti berhiaskan berlian

12

Dalam prototipe yang saya lakukan, ada minigame yang mirip dengan bejeweled. Menggunakan kisi yang merupakan array 2d ( int[,]) bagaimana saya bisa mengetahui kapan pengguna membentuk kecocokan? Saya hanya peduli secara horizontal dan vertikal.

Dari atas kepala saya, saya berpikir saya hanya akan melihat setiap arah. Sesuatu seperti:

int item = grid[x,y];
if(grid[x-1,y]==item)
{
    int step=x;
    int matches =2;
    while(grid[step-1,y]==item)
    {
        step++;
        matches++
    }
    if(matches>2)
        //remove all matching items
}
else if(grid[x+1,y]==item
    //....
else if(grid[x,y-1==item)
    //...
else if(grid[x,y+1]==item)
    //...

Sepertinya harus ada cara yang lebih baik. Disana?


sumber
Saya ingat saya menulis loop yang membosankan untuk melakukan itu (untuk koneksi-n)
Ming-Tang

Jawaban:

6

Ulangi setiap item dalam sumbu yang sama (x atau y), jika item tersebut sama dengan item sebelumnya yang cocok. Ketika item berikutnya menjadi berbeda, periksa apakah kecocokan atau lebih dari 3, panggil fungsi yang menghapus item yang cocok, dan lanjutkan.

Kode AS3:

var grid:Array = [[2,3,2,2,2,4],
                  [ .. ]]; //multidimensional array
var matches:uint;
var gemType:uint;
for(col = 0; col < grid.length; col++){
    matches = 0;        
    gemType = 0; //Reserve 0 for the empty state. If we make it a normal gem type, then only 2 are needed to match for the start.
    for(i = 0; i < grid[0].length; i++){
        if(grid[col][i] == gemType){
            matches++;
        }
        if(grid[col][i] != gemType || i == grid[0].length - 1){ //subtract 1 because arrays start at 0
            if(matches >= 3){
                removeMatches(blah);
            }
            gemType = grid[col][i];
            matches = 1;
        }
    }
}

Ini hanya untuk sumbu x, untuk y, kisi [col] [i] akan menjadi kisi [i] [baris], dll. Saya yakin Anda dapat mengetahuinya :)

apscience
sumber
4

Hanya berpikir saya akan menimbang dengan pengalaman kami dalam membangun game seperti Match-3.

Kami telah membangun prototipe untuk permainan kata berbasis Match-3, sedikit seperti menumbuk scrabble dan Bejeweled. Kami menyadari sangat awal bahwa mesin yang memasok permata baru / ubin untuk mengisi ruang kosong harus sangat introspektif (kami menjalankan heuristik hybrid dan pengambilan sampel MonteCarlo) untuk menciptakan peluang nyata bagi pemain untuk merangkai huruf untuk membentuk kata-kata melalui Mekanik Match-3. Ini jauh lebih rumit daripada deskripsi tapi saya tetap singkat karena kita harus menulis makalah.

Untuk menjawab OP - kami sedang melakukan pemeriksaan pola untuk menilai berapa banyak kecocokan yang ada pada semua sandang yang diberikan, pada saat ini, melalui metode yang sangat mirip dengan cuplikan kode "gladoscc". Meskipun bekerja dengan baik, biaya komputasi untuk menjalankan yang secara rekursif selama play-out pencarian pohon menjadi beban yang substansial, jadi kami sedang dalam proses menulis ulang bagian logika ini dan representasi data dengan metodologi bit-board ( umumnya diimplementasikan dalam jaringan lain seperti permainan seperti catur, catur, Othello, dll. Dalam tes kami telah menunjukkan bahwa itu dapat berjalan lebih dari 20 kali lebih cepat dalam ActionScript, dan bagi kami kebutuhan untuk melakukannya adalah slam-dunk - dan membebaskan siklus penting untuk responsif, suara, animasi, dll.

Wissam
sumber
3
Jawaban Anda harus menjadi jawaban dan tidak menambahkan pertanyaan lain. Jika Anda memiliki pertanyaan, harap buat pertanyaan baru menggunakan tombol "TANYA PERTANYAAN". Ini bukan forum diskusi.
bummzack
1
bummzack .... terima kasih untuk itu. Alasan saya adalah bahwa kami memiliki wawasan untuk ditawarkan, terutama yang berkaitan dengan kinerja apa yang diusulkan sebelumnya ketika pencarian pohon / introspeksi ditambahkan ke dalam konteks. Dan itu terus relevan karena kita pada dasarnya masih berbicara tentang "Logika di balik permainan Bejeweled". Jika ini terus menjadi bentuk yang buruk, saya akan dengan senang hati mengedit / memposting ulang sesuai saran Anda.
Wissam
2
Tidak apa-apa. Tetapi Anda harus menghapus bagian "pertanyaan" dari jawaban Anda. Pertanyaan harus menjadi pertanyaan baru dan bukan bagian dari jawaban ...
bummzack
1
diedit dan diposting pertanyaan di tempat lain
Wissam
2

Rekursi, yo. Itu untuk ketika Anda tidak tahu batas Anda.

   public int getHMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 0, column, 1);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }


    public int getVMatchSize(int row, int column)
    {
        int returnMe = getMatchValue(row, 1, column, 0);

        if (returnMe < 3)
        {
            return 0;
        }
        else return returnMe;
    }

    /// <summary>
    /// I return the match size.
    /// </summary>
    /// <param name="row"></param>
    /// <param name="rowDelta">1 means look vertically.  Dont set both deltas to 1.</param>
    /// <param name="column"></param>
    /// <param name="columnDelta">1 means look horizontally.  Dont set both deltas to 1.</param>
    /// <returns>The number of contiguous matching things</returns>
    public int getMatchValue(int row, int rowDelta, int column, int columnDelta)
    {
        int[] start = getEndItem(row, -1 * rowDelta, column, -1 * columnDelta);
        int[] end = getEndItem(row, rowDelta, column, columnDelta);

        int returnMe = 0;
        returnMe += end[0] - start[0];
        returnMe += end[1] - start[1];
        return returnMe;
    }

    /// <summary>
    /// I will return the end of a sequence of matching items.
    /// </summary>
    /// <param name="row">start here</param>
    /// <param name="column">start here</param>
    private int[] getEndItem(int row, int rowDelta, int column, int columnDelta)
    {
        Gem matchGem = new Gem(-1);
        int[] returnMe = new int[2];

        if (boardSpace[row + rowDelta][column + columnDelta] == boardSpace[row][column])
        {
            return getEndItem(row + rowDelta, rowDelta, column + columnDelta, columnDelta);
        }
        else
        {
            returnMe[0] = row;
            returnMe[1] = column;
            return returnMe;
        }
    }
Arconom
sumber
0

Anda dapat menggunakan algoritma pengisian banjir . Ini benar-benar bisa digunakan untuk masalah jenis ini.

ktornai
sumber
1
Tidak, sebenarnya itu tidak ada hubungannya dengan Pertanyaan. OP bertanya bagaimana mendeteksi tiga item yang cocok secara berurutan.
Cyclops
2
Jika Anda mulai mengisi dengan elemen yang dibalik, algoritme akan melewati elemen yang cocok. Tetapi hanya untuk memeriksa 3 (dan tidak ada lagi) elemen yang cocok dalam satu baris (dan tidak ada kolom yang saling bersilangan), itu mungkin merupakan pembunuhan berlebihan. Kami menggunakan ini dalam permainan seperti Bubble Puzzle, dan melakukan apa yang kami butuhkan.
ktornai
2
Anda mungkin harus menjelaskan sedikit lebih dari sekedar "menggunakan isi banjir" karena saya bingung bagaimana hal itu relevan dengan masalah ini.
jhocking