14 Mayıs 2010 Cuma

Geleceğe dair...



Uzun zamandır bloguma pek bir şey yazamadım .Biraz sancılı bir dönem geçiriyorum diyebilirim .Artık mezuniyet kapıya dayandı ve ileriye dönük bazı kararlar verme vakti geldi . Önümdeki seçenekler neler olabilir ,kpss ye girmek memur olmak ,yüksek lisans yapmak , şuanda proje yaptığım şirkette devam etmek , kariyer.net cv doldurup dua etmek .Memurluğun bana uygun olduğunu pek düşünmüyorum . Geçen sene elektronikten mezun olan arkadaşın denetmen yardımcısı olup çiftlikleri denetlediğini ve şeftali hakkında tez hazırladığını duyduktan sonra memurluktan daha da soğumuş bulunmaktayım . Yüksek lisans düşünüyor muyum diye kendime sorarsam ortalamam pek iyi değil oda mümkün gözükmüyor .Şuanda takıldığım bir şirket var ama sadece bir proje almış durumdayız ve ilerisi için tam olarak bir plan kurmuş değiliz . Bir de kariyer netimiz var tabii .Bunlar seçenekler birkaç tane daha eklenebilir(Kendi işini kurmak gibi .Biraz erken şimdilik) .Ama en büyük sorun benim tam olarak ne yapmak istediğim .Hedefim hiç bir zaman büyük bir şirkete kapağı atıp onlara bu şirkette çalışmak için doğdum havasında mülakatlardan geçip aktif oyuncu rolünde basamakları tırmanmak olmayacaktır .Bu düşünce bana aittir böyle düşünmeyenlere de saygım vardır lakin ben yaptığım işten haz almaya çalışan biriyim diyebilirim .

Neyse bu faslı geçelim . Blogumda şimdiye kadar bölümünde oyun programlama ile bir kaç yazı yayınlamıştım .Bundan sonrada genel olarak bilgisayar grafikleri üzerine yazılar yazmayı düşünüyorum . Bu aralar Render olayına kafayı takmış bulunmaktayım .

Render, (bilgisayarda) çizilmiş olan modeli veya modelleri bilgisayar tarafından işlemektir. Görüntünün ham halinin, bilgisayar tarafından işlenmesi de denebilir. Bu işlemi gerçekleştirmek için çeşitli bilgisayar yazılımlarına ihtiyaç duyulur.
Tanım ile resim vikipediden alınmıştır .Render modellenmiş cisimlere gerçekçilik katacak ışık ,yansıma ve gölgelendirmelerin hesaplanarak resim veya videoların son halinin oluşturulması diyebiliriz .Kullanım alanlarına oyunlar ,filmler ,3d animasyonları örnek verebiliriz.Render işlemi günümüz bilgisayarları için bile hayli zaman alabiliyor .Pixar'ın sitesinde yazılana göre yaptıkları bir 3d animasyon videosunda saniyede 24 kare oynuyor .Ve bu karelerin her biri için yaklaşık 4 saat render süresi gerekiyormuş.Hatta bazı motion blur efekti bulunan karelerde bu 70 saate kadar çıkabiliyormuş .İşin ilginci şirket bu renderi bizim evdeki masaüstü bilgisayarlarda yapmıyor tabii kendi süper bilgisayarlarını kullanıyor .

Benim ilgilendiğim asıl konu ise bilgisayarın bu işi nasıl yaptığı ve algoritmalarının nasıl çalıştığı bu hayli teorik olabilir .Pratik kısmı ise bir modelleme programı ile modelleme yapmak ve render etmek .Modelleme yapmak bir sanat işi diyebilirim ve bu konuda kendime pek güveniyorum diyemem .Bunun için ilk başta hazır modeller üzerinde uğraşabilirim .Hatta bu aralar takip ettim bir site www.3dimparatorlugu.com da düzenlenen yarışmalar var .Verilen modellere kendi renderini yapıp katılıyorsun . Tabii şimdilik işin başındayız .Son olarak bahsettiğim sitede bulunan bir yarışmada modeli ve render edilmiş halini paylaşıyorum.



19 Mart 2010 Cuma

multiplayer oyun server client mimarisi

Birçok oyun artık internet üzerinden veya LAN ağı kullanılarak oynanabiliyor .Oyunların multiplayer olarak oynanabilmesi için bilgisayarlara yüklü olan programların birbiri ile haberleşebilmesi ve durumlarını birbirine iletmesi gerekiyor .Bilgisayarların birbiri arasında haberleşmesi için genel olarak iki tür sistemden bahsedebiliriz. Bunlar Peer to Peer ve server/client mimarisi .
Peer to Peer ağları her bilgisayarın birbiri ile direkt haberleşebildiği ve oyunun seyrinin her bilgisayar da hesaplanması gereken bir network yapısı .












Peer to peer networkte bilgisayarların birbiri ile haberleşmesi ve kontrolu server client mimarisine göre hızlı ve kolay olmasına karşın sistem güvenliğini sağlamak daha zor .Çünkü clientler arasındaki iletişim server üzerinden olmakta .


Asıl konumuz Server client ilişkisi .Oyunlarda sistemin bir bütün olarak bir elden çalışabilmesi için iyi bir yöntem diyebiliriz .Aslında bu mimaride coğu işi server yapar .Clientler yapılan girişleri servera iletmekle ve sonuçlarını erkanda göstermekle mesuldurlar .Yani kısacası oyunda kullandığımız klavye ve fare girişlerini servera iletir ve kendisine dönen cevapları işler .

Server ise oyunun seyrini belirler bütün hesaplamalar ,yapay zeka algoritmaları ,fiziksel hesaplamaları ve clientlerden gelen girişleri oyuna ilave eder ve durumu clientlerine bildirir .




Serverın görevlerinden kısaca bahsedersek .

-fiziksel hesaplamalar
-yapayzeka algoritmaları
-çarpışma testleri
-iletişimi sağlama
Tabi bu işleri gerçekleştirmek için ve sistem performansını artırmak için bir çok ileri seviye algoritmalardan faydalanmak gerekiyor .


Son olarak server ve client ilşkisini gösteren kaba kodu ekliyorum ..













11 Şubat 2010 Perşembe

Bir Garip Yapay Zeka..


Oyun projesi için çalışmalarımız çok düzenli olmasa da devam ediyor .Projeyi tamamlamak için bir çok değişik alanda araştırma ve denemelerin yapılması gerekiyor . Zamana yayıp aklımızdaki yeni fikirleri de ekleyip tamamlayabilmek ilk hedefimiz .Şu anda kullanıcımız kendi tankımı yönetip ateş edebiliyor ama bu yeterli değil tabiki bilgisayarın düşman tankları yönetebilmesi gerekiyor .

Yapay zeka dersinde gördüğümüz algoritmalar daha çok en kısa yolu bulma ile ilgili algoritmalar .Bu algoritmalar bu oyunda pekte işe yaramıyor aslında .Düşmanın En kısa yolu bulup direkt olarak hedefe yönelmesi onu fazlaca akıllı yapacaktır .Bu bizim pek işimize gelmeyecekti . Bizim işimize daha çok rasgele hareket eden ve engellere göre yönünü değiştiren bunlara ek olarak hedefe yönelik hareketler de gösterebilen davranışlar yarayacaktı .

public void otonom_tank()
{
hareket_sayisi = (hareket_sayisi + 1) % degisim;
if (hareket_sayisi%30 == 0)
{
tank_yon_degis();
}
if (hareket_sayisi != 0)
{
if (engel_var_mi(tank_yon))
{
tank_hareket_et(tank_yon);
}
else
{
tank_hareket_et(random.Next(0, 4));
}
}
else if(hareket_sayisi==0)
{
degisim = random.Next(30, 70);
yonelme(yonel);
}
}

Yukarıda bulunan kod bloğu düşman tanklarının hareketlerini sağlayan metodumuz . Bu metodumuz tankın her bir hareketini hareket_sayısı değişkeninde tutuyor . Bu değişkenin modunu belli bir sayıya göre aldığımızda ve sıfıra eşitlendiğinde raslantısal hareket eklenir .
Kırmızı renkteki blok tankların engelle karşılaştığı zaman yönünü değiştirmesini sağlıyor.
En son kısmında ise yonel değişkeninde tutulan kordinata doğru bir yönelme gerçekleştiriyor .
Bu yönelme bizim savunmasını yapacağımız yerin kordinatını tutacak . Rastgele hareketlerle tanklar bizim savunmasını yapacağımız yere ateş etmesi düşük bir olasılık olduğu için yönelme davranışını ekledim.
public void yonelme(Point koor)
{
int rand=random.Next(0,2);
if (rand == 0)
{
if (koor.Y > tank_koor.Y)
{
tank_hareket_et((int)yonler.asagi);
}
else
{
tank_hareket_et((int)yonler.yukari);
}
}
else
{
if (koor.X > tank_koor.X)
{
tank_hareket_et((int)yonler.sag);
}
else
{
tank_hareket_et((int)yonler.sol);
}
}
}


Yönelme fonksiyonun mantığı basit hedef kordinatın x veya y değerlerine bakarak yönünü belirliyor .Eğer x koordinatı tankın kordinatından büyükse tankın yönünü ona çeviriyoruz. Y değeri içinde aynısını yapıyoruz .
İşin kötü tarafı tankların rastgele hareketlerinde biraz sorun yaşıyorum .Resimde gördüğümüz tanklar ilk başta tamamen dolu bir alanda başlamışlardı ve ateş ederek resimdeki gibi duvarları yıktılar .Sağ taraftaki iki tankın aynı yerler gidip ateş ettiğini anlıyoruz . Her ne kadar global random değerler kullanmış olsam da şimdilik bu sorunu çözemedim.

Tankların bu hareketlerine ek olarak ateş etmesi de biraz akıllı hale getirebiliriz .Mesela önünde engel varsa ateş et ,düşman varsa ateş et gibi .


30 Ocak 2010 Cumartesi

Asenkron işler

Birden fazla sesin aynı anda çalınması için Hasanın bulduğu dll ler işimizi baya kolaylaştırıyor .Şimdi de kontrollerin asenkron olarak kontrol edilmesi gerekiyor .Ne demek şimdi bu asenkron control diye sorarsanız .C sharp ta bir tuşa basılıp basılmadığını kendi eventlarından kontrol edebilirsiniz ama aynı anda birden fazla tuşa bastığınızda sorun çıkacaktır .Buna ek olarak bazı tuşların uygulamanız için bir önceliği olabilir.

Bir oyunu düşünelim ,yukarı ok tuşuna bastığımızda grafiğimiz ileri doğru ilerlesin sağ oka basıldığında sağa doğru ilerlesin space tuşuda ateş etsin .

Eğer bu tuşların hepsine birden basarsak normalde sadece biri çalışacaktır .


[DllImport("User32.dll")]
public static extern int GetAsyncKeyState(long vKey);

Yukarıda bulunan bloğu clasımıza eklediğimizde bu fonksiyonu kullanabileceğiz .
Aşağıda bulunan kodlar 90 tank projesinin basit olarak yön tuşlarını nasıl kontrol edildiğini gösteriyor .Bu kodla birlikte sağ ve sol yönlerin ileri ve geri tuşlarına bir öncelik sağlanması gerçekleştirilmiştir. Aynı anda say ve ileri basıldığında tankımız sağa gidecektir.Space ise ateş etmesini sağlayan bir tuş ve diğer tuşlardan bağımsız olarak her basıldığında işlemini gerçekleştirir.


private void asenkron_key()
{
bool ileri = true;

if (Form1.GetAsyncKeyState((int)System.Windows.Forms.Keys.Left) != 0)
{
tankım.key_handle("37");
ileri = false;
}
if (Form1.GetAsyncKeyState((int)System.Windows.Forms.Keys.Right) != 0)
{
tankım.key_handle("39");
ileri = false;

}
else if (Form1.GetAsyncKeyState((int)System.Windows.Forms.Keys.Up) != 0 && ileri)
{
tankım.key_handle("38");

}
else if (Form1.GetAsyncKeyState((int)System.Windows.Forms.Keys.Down) != 0 && ileri)
{
tankım.key_handle("40");

}
if (Form1.GetAsyncKeyState((int)System.Windows.Forms.Keys.Space) != 0)
{
kursun.key_handle("32", tankım);

}
}
Bu kullanılan fonksiyonun ilginç tarafı başka bir uygulamada uğraştığınızda bile tuşları konrol edebilmesi .Yani bir keylogger programı yazmak isteyen biri bu fonksiyonu kullanarak uygulamalarda kullanılan tuşları kaydedebilir .


27 Ocak 2010 Çarşamba

İlk denemler



Oyun programlamaya başlamaya karar verdikten sonra ilk proje için eski atari oyunlarında 90 tank oyununu belirlemiştik .İlk denemelerin görünümü yandaki resimde göründüğü gibi oldu .
Tank , mermi resimlerini gerçek oyunun ekran görüntüsünü paintte keserek ekledim ,umarım bir sorun çıkarmazlar :)) .Kaç zamandan beri oyun oynamayan ben ,oyunun kurallarını ve algoritmalarını iyi gözlemleyebilmek için akşamları düzenli olarak aynı oyunu oynamaya başladım . Oyun oynamak için ilk defa bir nedenim oldu :) .
Şimdi oyunun teknik kısımlarından bahsedelim .
Oyunu c sharp kullanarak kodlamaya karar vermiştik .Şimdilik basit olarak 3 classım
var harita classı ,mermi ve tank classı .Classlar şu anda çok yetersiz özellikler bulundurmasına rağmen işlerin nasıl bölünebileceğine bir temel teşkil ediyor .

Sırasıyla classların ne işe yaradığından görelim .
Haritamız grid tabanlı idi yani haritamızı belli büyüklükteki karelere bölüyoruz .
Classımız bu karelerin tutulduğu matrisi tutuyor .Mesela örnek olarak 50x50 matrisimiz olsun
bu matris te -1 degerleri boşlukları 1 degerler i duvarları göstersin .Üsteki resim de görüldüğü gibi belli bir alan duvar bloku döşenmiş .Bu bloku oluşturmak için belli bir indisten başlayarak çift for döngüsüyle matrisimize 1 degerlerini yerleştirmemiz yeterli.
harita classı işimizi kolaylaştıracak bir çok özelliği eklememiz gerekiyor .Harita grafiklerinin sağlanması gibi .

İkinci classımız tank classı genel olarak engellerin tespit edilmesi , hareketleri sağlayacak tuşların handle edilmesi ve grafiklerin sağlanmasını kolaylaştırıyor.
Klavye den yukarı oka bastığımızda tankın ilerlemesi gerekiyor her bir ilerleme hareketi için öncelikle tankın önünde bir engel olup olmadığı önceden test edilmesi gerekiyor .Bu işlemi harita classımızdaki matrisimizden bakıyoruz .Tankımızın yönü clasımızda tutuluyor ve tankın görüntüsünü döndüren metodumuz tankın yönüne göre resim döndürüyor .

Son classımız mermi classı tank clasımıza benziyor aslında . Atıldığı tanktan yön ve başlangıç koordinatlarını alan bu class bağımsız olarak engellere çarpıp çarpmadığını kontrollerini gerçekleştiriyor.

Oyunun projesini grubunuza yükledim .İsteyen indirip deneyebilir.
VS 2008 kullanarak denemenizi tavsiye ediyorum .

21 Ocak 2010 Perşembe

Oyun Programlamaya Dönüş

İkinci sınıfın başında nasıl oluyor da bu oyunlar yapılıyor diye bir merakla başladığım araştırmalarda bu işin aslında ne kadar zor ve eğlenceli olduğunu görmüştüm .Tabi o aralar oyun yapabilmem için elimde bulunan tek yardımcım c programlama bilgim olmuştu ama buda başlangıç seviyesinde idi . Bende doğal olarak bütün işi bu bilgimle götürmeye başlamıştım .Bu dil ile window uygulaması yazmak bir ölümdü .Hazır hiç bir tool da kullanmıyordum .Dolayısıyla işler çok yavaş işler olmuştu .Sonradan derslerin kötü gitmesiyle beraber bu işten soğumaya başladım ama iyi tarafı birçok konuda bir fikir sahibi olmuştum .

Şimdi bu işe C# kullanarak yeniden başlamaya karar verdim .Bu işe yeniden başlamaya karar verme nedeni söylesem baya gülmenize neden olurdu . Yapmak istediğim oyunlar daha çok nostaljik atari oyunları (zamanında az oynamamıştım) .Hatta ilk oyun projem olarak oynayanlar bilir 90 tank oyunu olacak .Oyunda amaç düşman tanklarına karşı kartalı korumak .Ataride 1 veya 2 kişilik oynanabiliyordu .Bir haritatada tankların hepsini vurduktan sonra bir sonraki haritaya geçiliyordu .Oynu network programlamayla multiplayer programlanabilirse baya eğlenceli olabilir.


Bu fikrimi Uğurla paylaştığımda hemen kendisini de bu işe dahil etmemi istedi . Tabiki böyle bir şeyle uğraşmak bir grup olarak daha da eğlenceli olucaktı .Yeni fikirler bulmak sorunları tartışarak bir çözüme kavuşturmak belkide zevkli yanıydı .Hatta Uğur bir basamak daha ileri giderek bir oyun yarışması bulmuş hemen .Benim ilk hedefim eğlenerek bir şeyler öğrenmek olduğu için hemde biraz tecrübe edinmemiz gerektiğini düşündüğüm için bunu şimdilik erteledim . İlerde olur da güzel bir fikir gelirse neden olmasın .

Sonradan Hasanın da katılmasıyla birlikte bana göre ideal sayıya ulaşmış olduk .Şimdi işin zor tarafı kaldı .Hangi konuların araştırılacağı bu konuların nasıl dağıtılacağı .Şimdilik benim aklıma gelen genel konular .
  • basit olarak yapay zeka algoritmaları
  • seslerin yönetimi
  • grafikler
  • network progralama işlemleri
  • haritalama seçenekleri
  • genel olarak kullanılabilecek veri yapıları .
Aklıma gelen başka bir oyun fikri yine atari oynu olan load runner . Bu oyunda baya eğlenceli bir oyundu .Özellikle bazı haritaları çok iyi tasarlanmış ve çözümü oldukça zordu .Bu oynu yapmak biraz kastırabilir .Bu oynada bir editör programı tasarlayarak oyuncunun kendi oluşturduğu haritalarda oynayabilmesi oynun eglencesini arttırabilir .

Çalışmaların gidişatını blogumda örneklerle paylaşmayı düşünüyorum .Böylelikle meraklıları için bir fikir vermiş olabiliriz .


15 Ocak 2010 Cuma

Web Crawler

Robot,spider(örümcek),worm,walker,wanderer olarakta bilinir .Hemen hemen Web tarihi kadar eski bir yazılım türüdür .Web crawlerlar webi tarayarak sitelerin içeriğini indirip depolamakla görevlidirler . Web artık ele avuca sığmayan milyarlarca siteden oluşmakta .Bu büyüklükteki veriyi indirip işlemek çok zahmetli bir iş .Bunun için ileri teknikler kullanılan bu yazılımlara ihtiyaç vardır . Agent tabanlı olan bu yazılımlar web içeriğini belirlenen sitelerden besleme yapılarak indirmeye başlar ve indirilen html içeriği içinde bulunan yeni url leri depolar .
Bulunan yeni url ler bir kuyruk yapısına konur ve aynı işlemler devam eder .Tabi bu indirilen html içerikleri de ayrı depolanır .Bu html içerikleri arama motorları için kendi algoritmaları için kullanılabilir .

Web crawları beş ana fonksiyon altında inceleyebiliriz .

  • URLl frontier(indirilecek URLlerin listesi)
  • Domainlerin ip çözümlemesi
  • HTTP protokolü kullanılarak içeriğin indirilmesi
  • HTML içeriğinden yeni linklerin bulunması
  • Yeni URLlerden önceden indirilenlerin belirlenmesi












URL Frontier

URL Frontier indirilecek olan URLleri tutan bir veri yapısı .Bir çok crawler Breath first algoritmasını kullanarak webi dolaşmaya çalışır .Bu dolaşım biçimi FIFO kuyruk yapısında kolayca tanımlanabilir .Gerçekte kullanılan bir crawler milyonlarca URL yi tutacağı için büyük bir bölümü hard diskte tutulması gerekir .Kuyruk yapısınıda bu şekilde dizayn etmemiz gerekecektir .

Crawler URL frontierından aldığı urlyi HTTP protokolünü kullanarak siteyi indirecektir ancak ilk önce bu url nin ip çözümlemesi yapılması gerekir .Bunun için DNS ye bağlanarak domaine karşılık gelen IP adresini alır .Bu IP ile Web servera bağlanarak gerekli HTML içeriğini indirir .
Crawlerlar için her defasında DNSe bağlanıp domainin IP sini öğrenmesi uzun zaman alabilir .Bunu önlemek için ziyaret edilen sitelerin IP adresleri kaydedilebilir .


İÇERİK TESTİ

Bir çok döküman internette farklı URLler altında yayılanabilir veya miror edilmiş olabilir .İki faktörde Crawlerın bu aynı dökümaları birden fazla indirmesine sebep olabilir .Bunu engellemek için içerik testi uygulanması gerekir.Bu testi uygulamak hem yer hemde zaman açısından çok probleme yol açabilir . Testi bütün dokümanların belli bir bölümüne uygulayarak yer ve zamandan tasarruf sağlayabiliriz. Testi gerçekleştirebilmek için checksum algoritmaları olan MD5 ve SHA algoritmaları kullanılabilir.

URL TESTİ

İndirdiğimiz sitelerin içinde bulduğumuz URLler bizim için yeni indirilecek olan sitelerin adresini bulmamıza yarıyordu fakat bir URL bir sitede birden fazla veya başka sitelerde de bulunabilir .Bulunan her URLnin önceden bulunup bulunmadığını yine kontrol etmemiz gerekecektir .Elimizde milyonlarca URL olduğunu düşünürsek bu işlem de zaman alan bir işlem olarak görülebilir .

HTTP protokolü


Siteleri indirirken HTTP protokolü kullanılıyor demiştik. HTTP protokolü TCP/IP üzerinde çalışan bir protokol .Kullandığımız web tarayıcıları bu protokolü kullanarak web serverlara bağlanır ve girilen URL ye karşılık gelen dökümanı tarayıcıya gönderir .Bu işlem klasik istemci sunucu paradigması kullanılarak gerçekleşir .


İstemci(client) web tarayıcımız ve sunucumuz URLde bulunan domaine karşılık gelen IP adresindeki web serverimizdir .İstemci yazılım request paketini hazırlar ve gönderir sonrasında sunucu bu paketin çözümlemesini yapar ve response mesajını ve bir sorun yoksa HTML içeriğini göndermeye başlar.

request paket örneği

GET http://en.kioskea.net/ HTTP/1.0
Accept: text/html
If-Modified-Since: Saturday, 15-January-2000 14:37:11 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)

response paket örneği

HTTP/1.0 200 OK
Date: Sat, 15 Jan 2000 14:37:12 GMT
Server: Microsoft-IIS/2.0
Content-Type: text/HTML
Content-Length: 1245
Last-Modified: Fri, 14 Jan 2000 08:25:13 GMT

Socket programı yazarak request paketini 80. porttan gönderdiğiniz de kullandığınız dile göre
değişebilen (c dilinde receive())fonksiyonla sunucudan gelecek response paketini alabilirsiniz .

Son olarak bir web crawlerin yaptığı işlemlerin sonuçlarını paylaşmak istiyorum.

200 OK 65,790,953 87.03%
404 Not Found 5,617,491 7.43%
302 Moved Temporarily 2,517,705 3.33%
301 Moved Permanently 842,875 1.12%
403 Forbidden 322,042 0.43%
401 Unauthorized 223,843 0.30%
500 Internal Server Error 83,744 0.11%
406 Not Acceptable 81,091 0.11%
400 Bad Request 65,159 0.09%
Other 48,628 0.06%
Total 75,593,531 100.0%