Satranç programını geliştirirken aşağıdaki yön dizilerini verilen değerlerle başlatmanın önemi nedir?


106

Rekabetçi programlamada yeniyim ve sık sık fark ettim ki, büyük kodlayıcıların çoğunun kodlarında bu dört satır var (özellikle dizileri içerenlerde):

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int diK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int djK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };

Bu gerçekten ne anlama geliyor ve teknik ne için kullanılıyor?


5
Sıklıkla bunun için kullanırım d={0,1,0,-1,0}: öğe çiftleri d[i], d[i+1]bana dört ana yön vermek için .
dasblinkenlight

14
Bu şaşırtıcı derecede iyi bir soru. ... Başlıkla ilgili bir şey yapılabilir mi?
luser droog

7
Yani bu kodun bir satranç motorundan geldiğini söylemeyi düşünmediniz mi? Ayrıca bu değerlerin nasıl kullanıldığına bakmayı düşünmediniz mi?
trojanfoe

15
"büyük kodlayıcıların birçoğunun bu dört satırı var [...]" - Burada özledim, ancak harika kodlayıcılar olsalardı, kodları "wtf bu yapı mı ?!"
utnapistim

6
@utnapistim Kodun büyük çoğunluğunu yazarken haklısınız ama burada bir noktayı kaçırıyorsunuz. Bu dava, bu kuralın meşru bir istisnasıdır. Bir yarışma için kod yazıyorsanız ve bir zaman kısıtlaması altında, hızlı ve kirli olmak neredeyse her zaman temiz ve bakımı yapılabilir olmaktan daha iyidir. Bu durumda size okunabilir, şimdi gerçekten önemli olan tek şeydir. Büyük bir kodlayıcı , bu bağlamda , normal kodlarının çoğu yüksek oranda okunabilir ve bakımı yapılabilir olsa bile , bu bağlamda , okunması imkansız bir karışıklığı çok iyi yazar .
Ben Lee

Yanıtlar:


84

Bu, tüm yönleri diziler olarak kodlamak için bir tekniktir - her çift di[i],dj[i]farklı bir yöndür.

X, y konumunda bir parçamız olduğunu hayal edersek ve onu yakın bir konuma taşımak için x ve y değerini eklemek istersek, 1,0 doğu, -1,0 batı, 0,1 güney, 0, -1 kuzey vb.

(Burada sol üst 0,0 ve sağ alt 4,4 demiştim ve dizilerin her bir indeksinin merkezi nokta olan X'den 2,2'de hangi hareketi yapacağını gösterdim.)

.....
.536.
.1X0.
.724.
.....

Kurulum şekli , indekste yaparsanız ^1( ^bitsel XOR olarak) zıt yönü elde edersiniz - 0 ve 1 zıttır, 2 ve 3 zıttır vb. (Kurmanın başka bir yolu da kuzeyden başlayarak saat yönünde ilerlemektir - sonra ^4size ters yön verir.)

Artık üzerinde döngü verilen bir noktadan tüm yönlere test edebilirsiniz dive djbunun yerine kendi satırında her yönünü yazmak için ihtiyaç duyma, diziler (toplam sekiz!) (Sadece :) sınırları denetleme yapmak unutmayın)

diKve tüm bitişik yönler yerine djKtüm şövalyelerin yönlerini oluşturun . Burada, ^1bir eksen boyunca ^4dönecek, zıt ata sıçrayacak.

.7.6.
0...5
..K..
1...4
.2.3.

3
'şövalye tarifleri' nedir?
David

4
Oh, bu tür bir şövalye.
David

1
Cevabınız için çok teşekkür ederim .. Lütfen beni bağlar mısınız ya da daha iyi açıklamak için bana bir kod gösterir misiniz .. (Biraz acemiyim ..
eğer

1
Pataşu'nun bir cevap girişimini alkışlıyorum. Açıklamasını birçok kişi anlamış gibi görünse de, ben onu tam olarak anlayamadım. Daha önce söylenenlere ekleyebilecek biri varsa, çok minnettar olurum.
deepak

1
@deepak Bir konumun x,y2B alanda bir demet ile temsil edildiğini hayal edin . Her bir çift di[i], dj[i]için onu ekleyin x,yve x,yher yöne birer birer aktarılırsınız. bu mantıklı mı?
Patashu

64

Patashu'nun açıklamasını takip etmekte zorlananlar için, açıklığa kavuşturmaya çalışacağım.

Bir satranç tahtasında belirli bir noktadan olası her hareketi değerlendirmeye çalıştığınızı hayal edin.

Di değerlerini x ofseti ve dj değerlerini y ofseti olarak yorumlayarak di ve dj dizileri üzerinde döngü yaparsanız, olası 8 yönün her birini kaparsınız.

Pozitif x'in doğu ve pozitif y'nin güney olduğunu varsayarsak (Patashu'nun cevabında olduğu gibi), şunu elde edersiniz;

  | di / x | dj / y | Yön
- + ------ + ------ + -----------
0 | 1 | 0 | Doğu
1 | -1 | 0 | batı
2 | 0 | 1 | güney
3 | 0 | -1 | kuzeyinde
4 | 1 | 1 | güneydoğu
5 | -1 | -1 | Kuzey Batı
6 | 1 | -1 | kuzey-doğu
7 | -1 | 1 | güneybatı

DiK ve djK dizileri, Şövalye parçası için olası hareketleri oluşturmak için aynı şekilde yorumlanabilir. Satranca aşina değilseniz, Şövalye bir L şeklinde hareket eder - bir yönde iki kare ve buna dik açıda bir kare (veya tam tersi).

  | diK / x | djK / y | Yön
- + ------- + ------- + ----------------
0 | -2 | -1 | 2 batı, 1 kuzey
1 | -2 | 1 | 2 batı, 1 güney
2 | -1 | 2 | 1 batı, 2 güney
3 | 1 | 2 | 1 doğu, 2 güney
4 | 2 | 1 | 2 doğu, 1 güney
5 | 2 | -1 | 2 doğu, 1 kuzey
6 | 1 | -2 | 1 doğu, 2 kuzey
7 | -1 | -2 | 1 batı, 2 kuzey

1

Tüm yönlerde mümkün olan hareket miktarını kontrol etmek için küçük bir kod parçası, tanımlı dizileri kullanır.

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int movesPossible[8];
int move = 0;
int posx, posy; // position of the figure we are checking

for (int d=0; d<8; d++) {
  for (move = 1; board.getElt(posx+di[d]*move, posy+dj[d]*move)==EMPTY; move++) ;
  movesPossible[d] = move-1;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.