Melihat apakah konfigurasi kisi tertentu cocok dengan resep tertentu mudah jika Anda menyandikan kisi 3x3 sebagai string dan menggunakan kecocokan ekspresi reguler . Mempercepat tampilan adalah masalah yang berbeda, yang pada akhirnya akan saya bicarakan. Baca terus untuk informasi lebih lanjut.
Langkah 1) Encode kisi sebagai String
Cukup berikan id karakter untuk setiap jenis sel dan gabungkan semuanya berdampingan dalam urutan ini:
123
456 => 123456789
789
Dan sebagai contoh yang lebih konkret, pertimbangkan resep tongkat, di mana W berarti kayu dan E adalah sel kosong (Anda bisa menggunakan arang kosong ''):
EEE
WEE => EEEWEEWEE
WEE
Langkah 2) Cocokkan Resep menggunakan Ekspresi Reguler (atau String. Berisi dengan sedikit pemrosesan pada data)
Melanjutkan dari contoh di atas, bahkan jika kita memindahkan formasi, masih ada pola dalam string (WEEW padded oleh E di kedua sisi):
EEW
EEW => EEWEEWEEE
EEE
Jadi, di mana pun Anda memindahkan tongkat, tetap akan cocok dengan ekspresi reguler berikut: /^E*WEEWE*$/
Ekspresi reguler juga memungkinkan Anda melakukan perilaku kondisional yang Anda sebutkan. Misalnya (resep dibuat-buat), jika Anda ingin beliung yang terbuat dari besi atau batu memberikan hasil yang sama, yaitu:
III SSS
EWE or EWE
EWE EWE
Anda dapat menggabungkan keduanya ke dalam ekspresi reguler: /^(III)|(SSS)EWEEWE$/
Membalik horisontal juga dapat ditambahkan dengan mudah (menggunakan operator | juga).
Sunting: Bagaimanapun, bagian regex tidak sepenuhnya diperlukan. Ini hanya salah satu cara untuk merangkum masalah dalam satu ekspresi Tapi untuk masalah lokasi variabel Anda bisa memangkas string grid dari setiap ruang padding (atau E dalam contoh ini) dan melakukan String.Contains (). Dan untuk masalah bahan berganda atau resep cermin, Anda bisa menangani semuanya sebagai resep ganda (yaitu terpisah) dengan hasil yang sama.
Langkah 3) Mempercepat Pencarian
Sedangkan untuk mengurangi pencarian, Anda perlu membuat beberapa struktur data untuk mengelompokkan resep bersama dan membantu pencarian. Memperlakukan kisi sebagai string juga memiliki beberapa keuntungan di sini :
Anda bisa mendefinisikan "panjang" resep sebagai jarak antara karakter non-kosong pertama dan karakter non-kosong terakhir. Sederhana Trim().Length()
akan memberi Anda informasi ini. Resep bisa dikelompokkan berdasarkan panjang dan disimpan dalam kamus.
atau
Definisi alternatif "panjang" dapat berupa jumlah karakter yang tidak kosong. Tidak ada yang berubah. Anda dapat mengelompokkan resep berdasarkan kriteria ini juga.
Jika poin nomor 1 tidak cukup, resep juga dapat dikelompokkan berdasarkan jenis bahan pertama yang muncul dalam resep. Ini akan sesederhana melakukan Trim().CharAt(0)
(dan menjaga Trim menghasilkan string kosong).
Jadi misalnya Anda akan menyimpan resep di:
Dictionary<int, Dictionary<char, List<string>>> _recipes;
Dan lakukan pencarian seperti:
// A string encode of your current grid configuration
string grid;
// Get length and first char in our grid
string trim = grid.Trim();
int length = trim.Length();
char firstChar = length==0 ? ' ' : trim[0];
foreach(string recipe in _recipes[length][firstChar])
{
// Check for a match with the recipe
if(Regex.Match(grid, recipe))
{
// We found a matching recipe, do something with it
}
}