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%