Temel Veri Yapıları ve STL 1 - Vektörler (Genişleyebilen Dizi)
Oyun programları geliştirirken çoğu zaman çeşitli veri yapılarını kullanmaya
ihtiyaç duyarız. Örneğin dizi veri yapısı en çok kullanılan veri yapılarından
bir tanesidir. Bu veri yapısının bu kadar çok rağbet görmesi sonucu olarak ta tüm
programlama dilleri dizi veri yapısına destek verirler.
Dizi veri yapısı o kadar çok kullanılır ki, çoğu programcı her tür ihtiyacı
için ya direk olarak yada modifiye ederek bu veri yapısı üzerinden programlarındaki
ihtiyacı karşılama yoluna gider. Programlarımızda amaca uygun veri yapılarını
kullanmak bize hem hız, hemde esneklik ve programlama kolaylığı sağlar. Dizi veri yapısı
dışında amacımıza uygun başka bir veri yapısı varsa bunu kullanmak en uygun davranış
olacaktır.
Bu yazı dizimizde oyun yapımı sırasında hayatımızı kolaylaştıracak çeşitli
veri yapılarını inceleyecek, kullanımına örnekler vereceğiz. Programlama dili
olarak oyun programlamada en çok kullanılan C/C++ dili kullanılacak. Veri yapılarını
baştan inşaa etmek yerine Standart Template Library (STL) kütüphanesindeki veri
yapılarının kullanımlarını inceleyeceğiz. STL her platform ve derleyici tarafından
günümüzde standart olarak desteklenmekte. Siz sadece gerekle include ları yaptıktan
sonra bu kütüphaneyi ek bir çaba göstermeden kullanabileceksiniz. Şimdi ilk veri
yapımızı incelemeye başlayalım:
Vektör
Vektör veri yapısı dizi veri yapısına birebir uymakta fakat dizi veri yapısının
getirdiği bazı kısıtlamalara da çareler bulmaktadır. Şüphesiz dizi veri
yapısının en büyük eksisi eleman sayısının önceden belirlenme zorunluluğudur. Bu
eleman sayısı değişken değildir. Örneğin 10 elemanlık bir dizi yarattığınız
zaman daha sonra 11. elemanı bu diziye koyamassınız.
Vektör veri yazpısı bize dizi veri yapısının sağladığı: elemanlara indis ile
direk ve hızlı olarak erişme kolaylığını sağlar, bununla birlikte vektör veri
yapısında dizi veri yapısı gibi eleman üst sınırı kısıtı yoktur. Bir vektöre
belleğiniz yettiği sürece istediğiniz kadar eleman ekleyebilirsiniz.
Şimdi bazı örneklerle bu veri yapısının kullanımını inceleyelim. Vektörleri
kullanmadan önce ilgili include tanımını yapmamız gerekiyor:
#include <vector>
using namespace std;
İlk satırda vektör template kodunu içeren kütük derleyiciye tanıtılıyor,
ikinci satırda ise kodumuzun "std" isimli ad bölgesinde çalışacağı
bildiriliyor. Namespace kavramına yabancı iseniz bu satırı fazla kafanıza takmayın.
Bu şekilde daha az kod satırı yazma durumunda kalıyoruz. Diğer tüm veri
yapılarında olduğu gibi vektör yapısı da ancak bir tür eleman içerebilecek
şekilde kullanılır. Yani bir vektör içerisinde hem integer hemde float türünde
veriler bulunduramassınız. Ancak integer lar için ayrı bir vektör, float lar için
ayrı bir vektör oluşturabilirsiniz. Biz şimdi bir integer vektörü oluşturalım:
vector v;
İşte integer elemanlar içerebilecek bir vektör tanımladık. İsterseniz şimdi bu
vektöre birkaç eleman ekleyelim. Eleman eklemek için .push_back() yordamını kullanıyoruz:
v.push_back(100);
v.push_back(200);
v.push_back(300);
Yukarıda yazdığımız kod ile vektörümüze sırası ile 100, 200 ve 300
sayılarını ekledik. Bu eklenen verilere [] (indis) operatörü ile ulaşabiliriz. İlk
eklenen elemanın indisi aynen dizilerde olduğu gibi 0 dır.
int x = v[0];
int y = v[1];
int z = v[2];
Gördüğünüz gibi dizinin eleman sayısı değişkendir. Dizinin içinde bulunan
elemanlarının sayısını ise .size() yordamı ile öğrenebiliriz:
int elemanSayisi = v.size();
Diziye sıra ile eleman eklemeyi görmüştük, sıra ile eleman çıkarmak için ise
yine bir fonksiyonumuz var .pop_back(). Bu yordam tersten işlemekte. Yani ilk
çağırdığınız zaman en son eklenen elemanı diziden çıkarmakta.
int a = v.pop_back();
// a = 300
int b = v.pop_back();
// b = 200
Vektörlere istediğiniz kadar eleman ekleyebilirsiniz demiştik. Aslında burada
yapılan işlem şu: standart olarak bir vektör tanımladığınız zaman o vektör
sistemce belirlenen bir sayıda eleman eklenebilecek şekilde yaratılır. Bu eleman
sayısından fazla eleman eklenmeye çalışıldığı zaman ise vektörün boyutu büyültülür.
Siz isterseniz vektörü yaratırken başlangıç eleman sayı sınırını
belirleyebilirsiniz. Örneğin 100 double eleman içereceğini tasarladığınız bir
vektör şu şekilde oluşturulur:
vector vv(100);
Bu vektöre 101. elemanı eklemeye çalıştığınız zaman yine otomatik olarak boyut
büyütme işlemi uygulanacaktır. Boyut büyütme zaman alan bir işlem olduğu için
hız gerektiren kritik noktalarda kullandığımız vektörlerimizde üst sınır
belirtmek faydalı olacaktır. Üst sınır belirttiğiniz vektörlerde [] (indis)
operatörü ile eleman ekleme işlemini de gerçekleştirebilirsiniz. vv vektörünün 5
indisli bölgesine 600 sayısını eklemek istersek:
vv[5] = 3.1415;
Bir vektörün eleman içerip içermediğini öğrenmek için .empty() yordamı
kullanılır. Vektör eleman içeriyorsa bu yordam false, içermiyorsa true değerini
döndürür:
bool bos = vv.emtpy();
Bir vektörü boşaltmak için .clear() yordamını kullanabilirsiniz. Bu işlemden
sonra vektörün eleman sayısı 0 olacaktır.
vv.clear();
Şimdiye kadar verdiğimiz örneklerde vektörler içerisine hep temel veri tiplerini
(int, float , double vb..) ekledik. Struct olrak tanımlanmış verileri içeren
vektörleri de kullanabiliriz. Örneğin x,y ve z değerlerini tutan Point isimli bir
yapı oluşturalım.
struct Point {
float x,y,z;
};
Point tipinde elemanlar içerecek olan bir vektör şu şekilde oluştutulabilir:
vector pVec;
Şimdi bir Point elemanı yaratıp vektörümüze ekleyelim:
Point p = {0,12,100};
pVec.push_back(p);
Gördüğünüz gibi vektörler bize dizilerin sağladığı tüm imkanları sunmakla
beraber aynı zamanda eleman kısıtları olmaması nedeniyle oldukça esnek bir yapı sağlıyor.
Bir grup veriniz var ve bu veriye rastgele indisler ile erişiyor iseniz, vektör veri
tipini rahatlıkla kullanabilirsiniz. İleriki derslerimizde liste, yığıt, kuyruk, küme
gibi birçok yaralı veri yapısını incelemeye devam edeceğiz. Gelecek derslerde
görüşmek üzere, kendinize iyi bakın.
M.Deniz Aydınoğlu :: 2002 :: www.oyunyapimi.org