Ana Başlık 2. Dizi Temelleri: Tanım, Erişim ve push/pop

Amaç: Dizi kavramını, indeksle erişimi ve push/pop/length işlemlerini oyun verisi bağlamında öğretmek.

Öğrenme Çıktıları:

Anahtar Sözcükler: dizi, indeks, length, push, pop, paralel dizi

Giriş

Şimdiye kadar çoğu örnekte tekil değişkenler yeterliydi: bir x, bir skor, bir hedef. Oyunlar büyüdükçe aynı türden birçok değer birlikte yönetilir — birden fazla balon konumu, birden fazla engel, tahmin geçmişi. Bunları x1, x2, x3 diye çoğaltmak bakımı bozar; dizi (array) aynı türdeki değerleri tek isim altında, sırayla tutar.

JavaScript’te dizi köşeli parantezle yazılır; elemanlar 0’dan başlayan indekslerle okunur. length uzunluğu verir; push sona ekler, pop sondan çıkarır. Dolaşma çoğu zaman for ile yapılır. Bu ana başlık dizinin sözdizimini ve temel mutasyonlarını kurar; sabit kapasiteli yığın benzeri kullanım ve paralel dizilerle mini sahne bir sonraki ana başlıkta gelir. Bundan sonra gelen alt başlıklarda önce veri modeli, sonra hamle kuralı, en sonda çizim ve etkileşim kurulur. Her yeni fonksiyon mümkün olduğunca küçük bir örnekte çalıştırılır; böylece hatanın kaynağı daha kolay bulunur. Anlatımda önce ilgili yapının ne işe yaradığı açıklanır, ardından kod satır satır okunur. Terimler ilk geçtikleri yerde kısa bir tanımla verilir; gerekirse tablo veya görsel ile desteklenir. Örnek sketch’ler tek bir mekaniğe odaklanır; böylece yan konular okumayı dağıtmaz.

2.1. Dizi Kavramı ve Tanımlama

Tanım: Dizi (array) — Köşeli parantez [] ile tanımlanan, indeksle erişilen sıralı veri koleksiyonudur.

Kod 1.

javascript
let skorlar = [10, 25, 40];           // Sayı dizisilet renkler = [255, 120, 80];         // RGB bileşenlerilet mesajlar = ["dogru", "yuksek", "dusuk"]; // Metin dizisilet bosDizi = [];                     // Boş dizi

Tablo 1.

İfade Anlam
[] Boş dizi oluşturur
[a, b, c] Başlangıç elemanlarıyla dizi
dizi[0] İlk eleman (indeks 0)
dizi.length Eleman sayısı

Dikkat: İndeksler 1'den değil 0'dan başlar. skorlar[1] ikinci elemanı verir; skorlar[3] üç elemanlı dizide tanımsızdır (undefined).

Dikkat — boş slot (hole): Olmayan bir indekse yazmak diziyi “delikli” uzatabilir:

Kod 2.

javascript
let a = [1];a[3] = 44;// a.length → 4; a[1] ve a[2] boş (empty); okununca undefined

Konsolda çoğu zaman Array(4) [ 1, <2 empty slots>, 44 ] benzeri görünür. Bu, bilerek yazılan BOS / -1 işaretinden farklıdır: empty slot’ta hücre hiç doldurulmamıştır. push veya 0, 1, 2… sırasıyla atama boşluk bırakmaz; oyun listelerinde bu delikleri oluşturmayın.

Görsel 1. Dizi indeksleri — skorlar = 10, 25, 40
Görsel 1. Dizi indeksleri — skorlar = 10, 25, 40

Görsel 1 her elemanın indeks numarasını (0, 1, 2) ve skorlar[i] erişimini kutularla gösterir. Dördüncü kutu yoktur — skorlar[3] tanımsızdır.

Bilgi: JavaScript dizileri başlangıç düzeyinde farklı türleri aynı listede tutabilir ([1, "iki", true]). Oyun kodunda genellikle tek tür tutulması okunabilirliği artırır.

Dizi okuma izlemesi: let renkler = [255, 120, 80]; tanımı için indeks ve değer eşleşmesi şöyledir:

Tablo 2.

İndeks renkler[indeks] Anlam
0 255 Kırmızı bileşen
1 120 Yeşil bileşen
2 80 Mavi bileşen
3 undefined Dizide karşılığı yoktur

fill(renkler[0], renkler[1], renkler[2]) ifadesi bu üç bileşeni sırayla okuyarak fill(255, 120, 80) ile aynı sonucu verir; dizi, ilgili renk bileşenlerini tek isim altında taşımayı sağlar.

Sıra Sizde: let skorlar = [10, 25, 40]; için kâğıda yazın:

  1. skorlar[0] ve skorlar[2] nedir? skorlar[3] neden sorunlu?
  2. skorlar.length kaçtır? Son geçerli indeks hangisidir?
  3. for ile üç skoru alt alta yazdıracak döngünün koşulunu bir satırda yazın (i < …).

2.2. Dizi Elemanlarına Erişim, Dolaşma ve Paralel Diziler

Eleman okuma ve yazma:

Kod 3.

javascript
let tahminler = [7, 12, 5];tahminler[0] = 8;        // İlk elemanı 8 yaplet ortanca = tahminler[1]; // 12

Kod bloğu: for döngüsüyle dizi elemanlarını ekrana yazma.

Kod 4.

javascript
let tahminler = [7, 12, 5, 9]; function setup() {  createCanvas(400, 300);} function draw() {  background(240);  fill(30);  textSize(18);  textAlign(LEFT, TOP);   for (let i = 0; i < tahminler.length; i = i + 1) {    let metin = (i + 1) + ". tahmin: " + tahminler[i];    text(metin, 20, 20 + i * 28);  }}

i < tahminler.length koşulu, indeksin dizi sınırları içinde kalmasını sağlar. length eleman sayısını verdiği için son geçerli indeks length - 1'dir.

Tablo 3.

i tahminler[i] Ekrandaki satır
0 7 1. tahmin: 7
1 12 2. tahmin: 12
2 5 3. tahmin: 5
3 9 4. tahmin: 9

Dizideki tek bir eleman güncellenebilir: tahminler[2] = 99; yalnızca üçüncü elemanı değiştirir. Son geçerli indeks dizi.length - 1'dir; bu sınırın dışına yazmak beklenmedik sonuçlara yol açabilir.

Paralel diziler — aynı indeks, bir nesne

Tek bir daire için x ve y iki değişken yeter. Ekranda birden fazla hedef varsa her biri için X ve Y gerekir. Bunları iki dizide, aynı indekste tutmak pratik bir çözümdür: hedefXListesi[i] ile hedefYListesi[i] aynı hedefin koordinatlarıdır. Bu modele paralel dizi denir. (İleride nesne veya 2B dizi alternatifleri gelecek; şimdilik paralel dizi yeterlidir.)

Hatırlatma — ellipse: ellipse(x, y, genislik, yukseklik) merkez (x, y) olan bir elips çizer. Genişlik ve yükseklik çaptır (yarıçapın iki katı). Daire için genişlik = yükseklik; oval için ikisi farklıdır. circle(x, y, cap) ise yalnızca daire içindir.

Kod bloğu: Konum listesinden birden fazla hedef çizimi.

Kod 5.

javascript
let hedefXListesi = [80, 200, 320];let hedefYListesi = [100, 150, 200];const YARICAP = 25; function setup() {  createCanvas(400, 300);  noStroke();} function draw() {  background(25, 30, 45);  fill(255, 200, 50);   for (let i = 0; i < hedefXListesi.length; i = i + 1) {    ellipse(hedefXListesi[i], hedefYListesi[i], YARICAP * 2, YARICAP * 2);  }}

Aynı i hem X hem Y’yi okur; döngü bir turda bir hedef çizer.

Görsel 2. Paralel diziler — aynı indekste X ve Y eşleşmesi
Görsel 2. Paralel diziler — aynı indekste X ve Y eşleşmesi

Görsel 2 hedefXListesi[i] ve hedefYListesi[i] çiftinin tuvalde aynı hedef dairesine karşılık geldiğini gösterir.

Sıra Sizde: Aşağıdaki sahnede biz (oyuncu) ve düşmanlar var. Bizim konumumuz tek bir noktadır — bizX, bizY iki değer yeter, dizi gerekmez. Ama düşmanlar çok olduğu için konumları paralel dizilerde tutulur: dusmanX[] ve dusmanY[]. Aynı indeks bir düşmanı verir: (dusmanX[i], dusmanY[i]). Boş / ölü slotta hem X hem Y -1’dir; döngüde atlanır (sahnede çizilmez).

Kod 6.

javascript
let bizX = 200, bizY = 150;let dusmanX = [60, 340, -1, 260, 150];let dusmanY = [60,  80, -1, 240, 200]; // [2] ikisi de -1 → yok

Görsel 3. Düşman konumları — paralel diziler ve 2B sahne
Görsel 3. Düşman konumları — paralel diziler ve 2B sahne

Kağıda yazın:

  1. dusmanX.length kaçtır? Sahnede gerçekten kaç düşman var (-1 slotunu saymayın)?
  2. (dusmanX[0], dusmanY[0]) neresi? İndeks [2] neden sahnede yok?
  3. Bize en yakın düşman hangi indeks? for ile -1 olanları atlayıp dist(bizX, bizY, dusmanX[i], dusmanY[i]) (veya uzaklık karesi) ile en küçüğü bulun.

2.3. push(), pop() ve length

Tanım: push() — Dizinin sonuna eleman ekler; length bir artar.

Tanım: pop() — Dizinin son elemanını çıkarır ve o değeri döndürür; length bir azalır.

Tablo 4.

Metot / özellik Etki Örnek Sonuç
push(değer) Sona ekler liste.push(42) liste [10, 20] iken → [10, 20, 42]
pop() Sondan çıkarır liste.pop() liste [10, 20, 42] iken → 42 döner; liste [10, 20]
length Eleman sayısı liste.length [10, 20] iken → 2

Görsel 4. push() ile sona eleman ekleme ve for ile dolaşma
Görsel 4. push() ile sona eleman ekleme ve for ile dolaşma

Görsel 4 push(9) öncesi ve sonrası diziyi yan yana gösterir; altta for döngüsünün her indekste hangi değeri okuduğu özetlenir.

Kod bloğu: Tahmin geçmişine ekleme.

Kod 7.

javascript
let tahminGecmisi = []; function mousePressed() {  let yeniTahmin = floor(random(1, 11)); // 1–10 arası tam sayı  tahminGecmisi.push(yeniTahmin);}

floor() p5.js'te ondalıklı sayıyı aşağı yuvarlayarak tam sayı üretir; random(1, 11) 1 ile 11 arasında (11 hariç) değer verir.

Tanım: floor() — Verilen sayıyı aşağı yuvarlayan p5.js fonksiyonu; tam sayı elde etmek için random() ile birlikte kullanılır.

Dikkat: pop() boş dizide undefined döndürür. Oyun mantığında dizinin boş olup olmadığı length === 0 ile kontrol edilebilir.

pop() iz örneği: let liste = [10, 20, 42];

Tablo 5.

Adım İşlem liste içeriği Dönüş
Başlangıç — [10, 20, 42] —
1 liste.pop() [10, 20] 42
2 liste.pop() [10] 20
3 liste.pop() [] 10
4 liste.pop() [] undefined

Son satırda dizi boşken pop() güvenli çalışır ancak anlamlı değer vermez; oyun mantığında «son tahmini geri al» gibi özellikler eklenecekse önce length > 0 kontrolü yapılır.

Bilgi — yığın (stack): push ve pop yalnızca «diziyi büyüt / küçült» değil; birlikte kullanıldığında dizi yığın (stack) gibi davranır. Kural LIFO’dur (last in, first out — son giren ilk çıkar): en son eklenen eleman ilk çıkarılır. JavaScript’te ayrı bir Stack sınıfı şart değildir; sıradan bir dizi + push/pop çoğu zaman yeter.

Yığın, programlamada temel bir yapıdır: fonksiyon çağrıları makinede bir çağrı yığını üzerinde tutulur; derleyiciler ve yorumlayıcılar bu modeli kullanır. Oyun geliştirmede de sık görülür — birkaç tanıdık örnek:

Tablo 6.

Bağlam Yığın ne tutar? push / pop hissi
Geri al (Undo) Son hamleler / fırça darbeleri Ctrl+Z ≈ pop; çizim editörleri, Super Mario Maker seviye düzenleyicisi, birçok bulmaca oyunu
Ekran / menü yığını Açık menü katmanları Duraklat → Ayarlar → Kontroller; kapatınca bir üst menüye dönüş (pop) — konsol RPG ve aksiyon oyunlarında klasik
Kart / deste Destenin üstü Solitaire ve benzeri kart oyunlarında desteden çekmek ≈ üstten pop; yeni kart koymak ≈ push
Envanter «son alınan» Son eklenen eşyalar Bazı envanter / crafting akışlarında «son ekleneni geri ver» veya kısa geçmiş

Aşağıdaki mini kule örneğinde GERİ AL ile son kuleyi kaldırmak da aynı fikirdir: geçmiş bir yığındır.

Bilgi: push() çağrısının kendisi de bir değer üretir: eklemeden sonraki yeni eleman sayısını döndürür. let yeniUzunluk = tahminGecmisi.push(7); satırında yeniUzunluk, güncellenmiş tahminGecmisi.length ile aynı değeri taşır. Örneklerde dönüş değeri kullanılmaz, push yalnızca ekleme etkisi için çağrılır; ancak dönüş değerinin var olduğunu bilmek, ileride benzer metotlarla karşılaşıldığında şaşırtıcı olmayacaktır.

Kod bloğu: Dizide en büyük değeri bulma (skor listesi, can değerleri…).

Kod 8.

javascript
function enBuyuk(degerler) {  if (degerler.length === 0) {    return 0;  }  let maks = degerler[0];  for (let i = 1; i < degerler.length; i = i + 1) {    if (degerler[i] > maks) {      maks = degerler[i];    }  }  return maks;}

enBuyuk(skorlar) çağrısı listedeki en yüksek skoru verir; for + karşılaştırma örüntüsü birçok özet istatistikte tekrarlanır.

Kod bloğu: Mini kule savunma — haritaya tıkla, kule kur (push); geri al henüz yok (Sıra Sizde’de pop).

Kod 9.

javascript
let kuleX = [];let kuleY = []; function setup() {  createCanvas(400, 300);} function draw() {  background(210, 230, 205); // yesil harita   // Once buton — metinler ustune binmesin diye saginda / altinda  fill(150, 60, 60);  rect(0, 0, 72, 36);  fill(255);  textAlign(CENTER, CENTER);  textSize(12);  text("GERİ AL", 36, 18);   fill(40);  textSize(13);  textAlign(LEFT, TOP);  text("Haritaya tıkla: kule kur", 80, 6);  text("GERİ AL: son kuleyi kaldır", 80, 22);  text("Kule sayısı: " + kuleX.length, 12, 44);   for (let i = 0; i < kuleX.length; i = i + 1) {    fill(70, 110, 200);    circle(kuleX[i], kuleY[i], 26); // kule govdesi    fill(255);    circle(kuleX[i], kuleY[i], 10); // namlu  }} function mousePressed() {  if (mouseX < 72 && mouseY < 36) {    // GERİ AL — Sıra Sizde'de pop eklenecek  }  kuleX.push(mouseX);  kuleY.push(mouseY);}

Her tıklama harita konumunu her iki diziye push eder; kuleler ekranda birikir. Sol üst GERİ AL kutusuna tıklamak şu hâliyle kaldırma yapmaz; dahası tıklama alttaki push satırına da ulaştığı için o noktaya yeni bir kule eklenir. Kaldırma mantığı ve bu istenmeyen ekleme Sıra Sizde’de birlikte düzeltilir.

Sıra Sizde: Yukarıdaki mini kule savunma kodunu temel alın. GERİ AL’a tıklanınca son kurulan kuleyi kaldırın (kule savunmada yanlış yere konan kuleyi geri almak gibi).

İstenenler:

  1. Kâğıtta: kuleX = [10, 20], kuleY = [30, 40] iken bir kule kurun → push (50, 60), sonra bir geri al — diziler nasıl kalır?
  2. mousePressed içinde GERİ AL dalına: length > 0 ise her iki dizide pop (yalnızca birinde değil — paralel dizi!).
  3. Çalıştırıp birkaç kule kurup geri alın; ekrandaki kule sayısı kuleX.length ile uyumlu olsun.

İpucu: Yalnızca if bloğunun içine pop yazmak yetmez — mousePressed içinde en az bir değişiklik daha gerekir; yoksa GERİ AL’a basınca istenmeyen bir push de tetiklenebilir.

Yapay Zekâ Etkileşimi: Dizi Dolaşma Bug’ı Tahmini süre: 15–20 dakika.

Amaç: Off-by-one hatalarını tanımak.

Adım 1: i <= dizi.length yazan hatalı bir döngü düşünün; ne olur yazın. Adım 2: Yapay zekâya bu bug’ı ve düzeltmesini sorun; kendi gerekçenizle karşılaştırın. Adım 3: Kısa bir diziyle editörde hem hatalı hem doğru sınırı deneyin.

Özet

Dizi, köşeli parantezle tanımlanan ve indeksle erişilen sıralı bir veri koleksiyonudur; let sayilar = [10, 20, 30] üç elemanlı bir listedir. İndeksler sıfırdan başladığı için sayilar[0] ilk elemanı verir ve son geçerli indeks length - 1 olur; bu sınırın dışına çıkan bir okuma undefined üretir. Dolaşma döngüsünün koşulu bu yüzden çoğu zaman i < dizi.length biçiminde yazılır. Var olmayan bir indekse yazmak diziyi boş hücrelerle uzatabilir; bu boşluklar, oyun listelerinde bilinçli olarak konan işaret değerlerinden farklıdır.

Aynı türden birden çok nesnenin özellikleri paralel dizilerde tutulabilir: iki ayrı listede aynı indeks aynı düşmanın x ve y koordinatını gösterir, kullanılmayan hücre ise bir işaret değeriyle atlanır. Tek bir for döngüsü her turda ilgili indeksin iki değerini birden okuyarak sahnedeki nesneleri çizer. Bu model, ileride gelecek nesne ve iki boyutlu dizi alternatiflerinin ön adımıdır.

push diziyi sonundan büyütür, pop son elemanı çıkarıp değerini döndürür ve length her iki işlemde de güncellenir; boş dizide pop çağrısı undefined verdiği için önce uzunluk denetlenir. İkisi birlikte kullanıldığında dizi, son giren ilk çıkar kuralıyla çalışan bir yığın gibi davranır; geri alma, menü katmanları ve kart destesi bu davranışın tanıdık örnekleridir. Sabit kapasiteli kullanım ve mini sahne örneği bir sonraki ana başlıkta bu temele dayanır.

Neler Öğrendik?

Soru 1 JavaScript dizilerinde ilk elemanın indeksi nedir?

A) 1

B) 0

C) -1

D) length

E) undefined

Soru 2 dizi.push(5) ne yapar?

A) İlk elemanı siler

B) 5’i dizinin sonuna ekler

C) Tuvali temizler

D) FPS’i 5 yapar

E) setup’ı yeniden çalıştırır

Soru 3 for (let i = 0; i < dizi.length; i++) neden yaygındır?

A) Çünkü length dışı indekslere güvenli sınır çizer

B) Çünkü rengi değiştirir

C) Çünkü HTML siler

D) Çünkü ses açar

E) Çünkü DNS ister

Soru 4 Paralel diziler ne anlama gelir?

A) İki dizinin aynı indekste ilişkili özellik tutması

B) İki tarayıcının zorunlu açılması

C) Yalnızca string birleştirme

D) CSS grid

E) Git branch

Neler Öğrendik Yanıt Anahtarı

Soru 1: Doğru Cevap: B

Soru 2: Doğru Cevap: B

Soru 3: Doğru Cevap: A

Soru 4: Doğru Cevap: A

Yararlanılan Kaynaklar

Bu içerik aşağıdaki kaynaklardan derlenerek hazırlanmıştır: