Game of Life! (msw logo üzerinde ^^)

Okulumuzun ilk döneminde bize öğretilen program idi msw logo. Yeni öğrenciler programlamaya giriş yapsın diye bu tip eğitim programları gösteriliyor.

Msw logo bir çizim programı denebilir, fakat kullanıcılar komut girerek çizim yapıyorlar.

logo2

Yukarıdaki üçgen (ismi turtle, eskiden hakikaten kaplumbağa şeklindeymiş ondan adı böyle =)) bizim kalemiz. Biz verdiğimiz komutlarla turtle ı hareket ettiriyor, döndürüyor ve çizim yapıyoruz. Yukarıdaki örnekte turtle karenin sol alt köşesinden başladı ve yukarı bakıyordu. fd 100 (forward 100) ile 100 pixel ileri gitti ve karenin sol kenarını çizdi. rt 90 üçgeni 90 derece saat yönünde döndürdü. Sonra gene fd 100 ile karenin üst kenarını çizdik. Yukarıdaki komutları takip ederek resimdeki şekli oluşturduk.

Kulağa komik bir program gibi gelebilir =), ama gayet geniş bir şey aslında. 3d çizim yapmaya izin veriyor mesela. İnternette araştırılırsa çok güzel çizimler sunan basit kodlar bulunabilir. Mesela bir örnek şu (tıklayarak büyük halini açın):

desen

Bu deseni ortaya çıkartan kod da şurada. Denemek için Edall a tıklayın, kodu yapıştırın, “save and exit” ile çıkın ve komut verilen yere “db 2 6” yazıp çalıştırın. Yapan arkadaş recursive in dibine vurmuş hakikaten.

Benimde yıllar sonra aklıma esti ve game of life ı msw logo üzerinde çalıştırayım dedim =D. Sonucu da burada

gameoflifemswlogo

Kaynak kodumuzda buradan alabilirsiniz.

http://www.shultays.com/gameoflifelogo.txt

Kullanmak için Edall butonuna tıklayın, açılan pencereye bu kodu yapıştırın ve “save and quit” ile pencereyi kapatın. Daha sonra komut yerine “gameoflife 16 16 100” yazarak game of life ı başlatabilirsiniz (ilk 16 değeri satır sayısı, ikinci 16 sütun ve 100 de toplam kaç generation yapılacak onun sayısı, isteğinize göre arttırıp azaltabilirsiniz)

Mswlogo yu indirebilmek için.

http://www.softronix.com/logo.html

Game of Life hakkında bilgi

http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

Eski Odtü algoritma yarışması sorusu

Geçen yıl finalde sorulan sourlardan birisi o zamandan beri aklıma bir parça takılmıştır. Bir türlü nasip olmadı oturup uğraşmak.

Odtü lü arkadaşların soru için güzel bir hikayesi vardı, şimdi aklımda değil malesef.

Soruda bir input dosyasından dikdörtgen koordinatları okuyoruz (her dikdörtgen için sol-üst ve sağ alt köşenin koordinatları veriliyor). İstenen ise bu dikdörtgenleri tek renk bir kalem ile bir kağıda çizer ve boyar isek oluşan şeklin alanı.

Dikdörtgenlerin boyutlarunda ve koordinatlarında sınır olmadığı için (integer sınırlarında farzedin) “İki boyutlu bir array açayım, dikdörtgen olan yerleri 1 yapayım” gibi bir mantık işe yaramıyor.

Aklıma gelen bir çözüm yolu (ki obvious çözüm gibi bir şey) her yeni eklenen dikdörtgeni öncekiler ile karşılaştırmak ve eğer kesişiyorsa önceki dikdörtgeni kesişmeyen iki dikdörtgene bölmek. Örnek resim:

res11

Mesela soldaki örnekte b dikdörtgeni önceden gelmiş bir dökdörtgen. a ise yeni gelen dikdörtgen. Biz bu b yi şu şekilde ikiye bölüyoruz (Yazının bu kısmında l4d oynamak için ufak bir ara verdim, herkese tavsiye ederim bu oyunu =p)

res2b dikdörtgenini c ve d olarak ikiye ayırdık. Artık kesişme sorunu yok ve alan olarakta aynı alan. Elbette farklı şekilde de bölünebilirdi.

Bu bölme işleminden sonra a yı kalan dikdörtgenlerle (eğer kaldıysa) kontrol edeceğiz. Gerekirse yine aynı şekilde onları da böleceğiz. Her çakışma sonucu ikiye bölünecek diye bir şart yok. Eğer şanslı isek eski dikdörtgen yenisini kapsar ve daha fazla kontrole gerek kalmaz. Veya mesela şu örnek için:

res3Eğer yeni gelen dikdörtgen kırmızı olan ise sadece mavi dikdörtgenin kırmızı içinde kalan kısımlarını çıkartarak (mavi dökdörtgeni bir parça sol tarafından kırparak) çakışmadan kurtulabilirdik. Eğer yeni gelen mavi olan ise ve kırmızıyı bölmeye kalkarsa üçe bölmek zorunda kalacaktık. Bunun yerine algoritmayı biraz değiştirerek yine aynı şekilde maviyi (yeni gelen dikdörgeni) kırparak dikdörtgen sayısını azaltabiliriz. Yine aynı şekilde yeni gelen dikdörtgen eskini kapsıyor ise eskisini listeden çıkartabiliriz, bu durumda hala yeni dikdörtgeni kontrol etmek zorundayız ama en azından toplam dikdörtgen sayımız azaldı.

Yani en kötü ihtimalle her karşılaştırma için bir yeni dikdörtgen oluşturuyoruz. Aklıma gelen şu anlık tek çözüm bu, ama performansı konusunda şüphelerim var. Yani mesela n dikdörgen var ise, n+1 inciyi eklerken her karşılaştırma için 1 artar ise toplamda 2n+1 dikdörtgen olacak. Tabi bu çok uç bir input ve muhtemelen tek bir input dosyası içinde sayısının fazla olması imkansız. Alan hesaplamak içinde en sonunda tek tek bütün dikdörtgenlerin alanlarını toplayacağız.

Son zamanlarda da asıl aklıma takılan böyle bir algoritmanın complexity si ne olur. Yani bir kere O(n^2) den düşük olamayacak (sonuçta her yeni geleni bir öncekilerle kontrol ediyoruz). Ama devamlı dikdörtgenler bölüneceği için n^2 den yüksek bir complexity alması lazım gibi duruyor.

Yapılabilecek başka bir iyileştirme ise dikdörtgenleri sort sağ noktasının x koordinatlarına göre sort edilmiş şekilde tutmak. Eğer yeni dikdörtgenin sol noktasının x koordinatı, eskilerin sağ x ini geçer ise artık kalan dikdörtgenleri kontrol etmeye gerek kalmayacak. Eğer sorted bir şekilde tutar isek dikdörtgenleri linked list yapısında saklamak daha mantıklı çünkü bölünen yeni dikdörtgenler (ve yeni gelen dikdörtgenler) devamlı araya girmeye kalktığında array i shift etme zorluğu yaşamayalım. Bu ayrıntıyıda algoritmaya eklersek bariz bir şekilde iyileştirme sağlayacaktır (eğer bölünme olmasaydı O(nlogn) olacaktı, ama tabi gerçek complexity yi hesaplamak çok daha fazla karıştı =D).

Bu sorunun ikinci kısmı ise çevre hesaplamak idi (sadece şeklin etrafını çevreleyen değil, içerde boşluk varsa o boşluğunda çevresi de hesaba katılacak). Çevrenin tek farkı ise şu. Önce yine aynı şekilde dikdörtgenler kesişmeyecek şekilde oluşturacağız. Sonra her dikdörtgenin çevresini bir toplam çevre değerine ekleyeceğz. Daha sonra, dikdörtgeni bir önceki dikdörtgenler ile karşılaştıracağız, eğer iki dikdörtgen teğet ise ne kadar uzunlukta teğet olduğunu bulacağız ve o değerinin iki katını toplamdan çıkaracağız.

res4 Mesela a ve b nin çevreleri A, B ise ve sarı çizginin (teğet olan kısım) uzunluğu L ise toplam çevre.

Çevre = A + B – 2*L

olacak.

Henüz daha iyi bir çözüm aklıma gelmedi, olabilir diye umuyorum. Algoritmayı koda dökmeye hep üşeniyorum. Çok fazla ağır gibi durmasada iki dikdörtgenin karşılaştırılması ve bölünmesi baya zor olacak gibi duruyor, bir çok ihtimal var sonuçta. Belki daha iyi bir tane bulunabilir bilmiyorum. Odtü finalinde çok kötü bir algoritma yazmıştım, kesişen her iki dikdörtgen için kesişen alanı çıkarıyordu. Ama mesela 3 dikdörtgen aynı noktada kesişirse o durumda patlıyordu. Belki bu algoritma biraz geliştirilerek doğru sonuç verecek bir şeye çevrilebilir belli olmaz.

shultays.com/blog

Word press in tema düzenlemeye izin vermediğini farkedinci blog u taşıma kararı verdim. Bir süre ikisinde de yazacağım aynı yazıları daha sonra tamamen diğerine geçiş yapmayı düşünüyorum.

http://www.shultays.com/blog

şu anlık sub domain almadım, zaten server ı bedavaya veren bir arkadaş olduğu için utanıyorum daha fazla istek yapmaya 🙂

Ayrıca aklıma yeni bir proje geldi, blog postlarını mysql den okuyup shultays.com da gezegen olarak göstereceğim. gezegene tıklayınca javascript ile alakalı post u pop up olarak açacak. Eğer düzgün gösterebiliyorsa direk flash içinde de göstermeyi deneyebilirim ama flash ın html yorumlaması çok sınırlı olduğu için ne kadar iyi olacak bilmiyorum (zaten code taglarını gösteremeyecek, alıntılar görünmeyecek bir acayip olacak yatacak herhalde o fikir)

Hatta commentleri bile gezegenin etrafında dönen uydular gibi yapabilirim =D.  Bir evrende en fazla diyelimki 20 gezegen göstersin istiyorum, 20 den fazla post var ise aşağıda sayfa numarasına tıklayacağız, tıklayınca çok hızlı bir şekilde uzaklaşacak o evrenden ve “yeni” bir evrene geçecek. Bir gezegene tıklayınca yanına gidip alakalı sayfayı becerebilirsem sayfayı flash ta gösterecek ve commentler uydumuz olacak, olmaz ise alakalalı sayfayı pop-up olarak açacak.

Bakalım fikir güzel, eğer yapabilirsem sitenin flash ve php dosyalarını açabilirim. Şimdiye kadar pek açacak bir şey yoktu o yüzden açmamıştım =)

pff

1 hafta tatil, çok fazla iş, pek az istek.

Kimse düşmesin böyle bir duruma. En azından ‘tatil’imiz var diye sevineyim.

Z fighting

Opengl de bana ilginç bir anı ve şu anda kullandığım avatarımı vermiş olan konu.

Basit olarak anlatmak gerekirse 3d ile çizilen iki şeklin kameraya olan uzaklıklarının birbirine eşit (veya çok yakın) olması ile oluşan, opengl in hangi şekil üstte olmalı anlayamamasından oluşur.

En basit çözümü üstte görünülmesi istenilen şeklin bir birim daha öne kaydırılmasıdır, ama eğer bizim başta  “en fazla şu kadar uzaklıkta olan z lerin çizilmesine izin ver” diye verdiğimiz değer çok büyükse bu yeterli olmayabilir.

Diğer bir çözümde stencil buffer kullanmak. Önce altta kalmasını istediğimiz nesneyi hem ekrana hem de stencil bufferına çizeriz, daha sonrada üstte kalmasını istediğimiz nesneyi eğer stencil buffer 1 ise kesin çiz, 0 ise depth test yap öyle çiz deriz. Şu an da tam hangi değerleri vereceğiz aklımda olmadığı için böyle yarım yamalak bir tanım yaptım =)

Neyse asıl anlatmak istediğim bu z buffer ın bana bıraktığı hoş anı =) 3 boyutlu engebeli bir gezegen yapmak istiyordum, ve onunla uğraşırken şu şekli ortaya çıkardım.

interesting1

Ne olduğunu başta çözemedim, sonradan farkedebildim niye böyle bir şey çıktığını. İşte z fighting sonucu ortaya çıkan bir şekil, doğrusu gözüme çok hoş geldi ve avatar olarak kullanma kararı aldım =D İlerde birileri sorunca avatarın ne diye “Kendisi bir bugtır” diyeceğim.

Malesef programın o halini kaydetmemişim =( ama bir gün tekrar aynı “hata”yı ortaya çıkarmaya çalışacağım.

gezegen

Bu da şeklin olması gerek şey idi, malesef sadece çok küçük bir resmini tutmuşum. Soldaki şey engebeli bir gezegen aslında, döndürünce falan hoş duruyordu. İleride tekrar uğraşabilirim, yapmak istediğim proje küre şeklinde bir dünya yaratmak ve uçarak bu dünya üzerinde gezine bilmek idi (Spore oynayanlar demek istediğimi anlayabilmiştir) hatta binalar falan eklerim diyordum ama sonunda (diğer bir çok projeye olan şey gibi =D) yarım kaldı. Şu an dosyalarını bile bulamıyorum.

Amiral Battı

Java dersi projem idi. 2 kişilik bir amiral battı oyunu. Socket programming ile 2 farklı bilgisayardan (aynı bilgisayar da olabilir ama o zaman karşı tarafın gemilerini görebiliyorsunuz =)) oynanıyor. Host olacak taraf Host a Game butonuna tıklamalı, diğer oyuncuda hostun ip sini girip join a game ile host a bağlanıyor.

screenshot-battle-ship1

Oyun başladığında ilk iş gemileri yerleştirmek. Sol fare ile gemi yerleştiriliyor, eğer istenirse sağ fare tuşu ile 90 derece döndürülebilir. Hata yaptıysanız alttaki gemi resimlerinden gemiyi tekrar seçebilirsiniz.

Her iki taraf ta ready tuşuna basınca oyun başlıyor ve gemileri ilk tükenen oyunu kaybediyor.

Thread nedir ne değildir gibi bilgiler henüz bende yokken yaptığım için karşı taraftan mesaj bekleyen taraf sonsuz döngüde kalıyor. Bu arada da hiç bir çizim yapılamıyor. Genel olarak 2d çizim olayına da yeni olduğum için bazı bölümlerde hata olabiliyor (misal gemiler seçildikten sonra ilk elde ekran görünmüyor nedense. Çözememiştim bir türlü, projeyi gösterirken o kısmıda hızlı hızlı geçmiştim =D)

Windows ta eclipse üzerinden yazıldı, linux de javac ile derlenip çalıştığı görüldü. Grafikler başka bir amiral battı oyunundan araklandı =) (hatta o oyunda mesela tekli botlar yoktu onlar muhteşem grafik becerilerim ile üç kareye sahip olan geminin iki ucu birleştirilerek oluşturuldu. torpido şeklinde 2 karelik gemi de benzer şekilde deniz altıdan oluşturuldu)

http://www.shultays.com/amiral.tar.gz

shultays.com

shultays.com

Bir yıl kadar önce yaptığım, 3D grafik olayına giriş yaptığım kişisel web sitem. Hazırlık-1.sınıf zamanlarında AS2 olarak başlamıştım, daha sonra AS3 kullanmaya başladım. Asıl amacım flashta 3D site yapmak değilde bir 3D grafik motoru yazmak idi, bu yüzden hiç bir hazır kütüphane kullanmadım. AS2 hali hala duruyor, ama resimler eksik, mesela ortada bir küp vardı o görünmüyor, kenarda bir Otostopçunun Galaksi Rehberi vardı, hatta kapağı bile açılıyordu (vay be)

Pek kullanıcı dostu değil, zaten öyle olması için de tasarlanmadı =p Aslında aklımda göze güzel gelebilecek bir menü sistemi var ama hep üşeniyorum. Uzun süredir de flash kullanmadım, o yüzden de biraz çekinme var. Hem zaten zaman da yok =D

WASD tuşları ile kamera aşağı yukarı hareket ediyor. İleri gitmek için RF tuşlarını kullanarak ileri geri gidebilirsiniz. QE ekranı çevirir. Ayrıca farenin sol tuşunu basılı tutarakta kamerayı döndürebilirsiniz.

Renkli ve ünlemli gezegenler aslında bizim linklerimiz oluyor, onlara tıklayınca gezegene gidiyoruz ve onunla alakalı flash yükleniyor. Beyaz gezegenler de boş gezegenler, yanlarına gidebiliyorsunuz ama bir şey açmıyorlar.

Hayalimdeki proje evrende kişilere belirli bölgeler vermek, o bölgelerde kendi gezegenlerini oluşturmalarını sağlamak idi. Siz evrende gezinerek aslında siteler arasında geziniyor gibi olacaktınız. Lakin bir süre sonra artık sıkmaya başladı ve bitirilmemiş projeler arasında yerini aldı. Bir diğeride bu mesela. Multiplayer bir savaşlı yarışlı oyun yapayım dedim ama görebileceğiniz o daha başlarda yalan oldu =)

Now you are thinking with portals

Stencil buffer’ın ne olduğunu öğrenmem ve sonrasında “Portal yapılır bunla” fikrinin gelmesi ile başlayan proje.

Portal nedir diyenler için herkesin denemesini tavsiye edeceğim Valve’nin ürettiği bir oyun. Amaç oluşturduğumuz portallar yardımıyla başlangıç noktasından bitiş noktasına gitmek.

Peki “portal” nedir derseniz, şöyleki: iki tane kapı hayal edin, birinden girdiğimiz de aslında diğerinden çıkıyoruz. Türkçe de kurt deliği diye kullanılıyor (hoş aslında oda wormhole ya neyse) diye düşünüyorum.

Yani bir ss ile anlatmak gerekirse:

port11portal21

Bu dikdörtgen pencere gibi duranlar portallarımız oluyor, pembe renkli şekil sarı duvardaki portalın önünde, dikkat ederseniz kırmızı duvardaki portaldan baktığımızda hemen önde onu görüyoruz.

Daha iyi anlamak için programı deneyin =)

İki sürümü var, hemen hemen aynı. Başta windows ta yazmıştım, daha sonra linux üzerinde test ettim.

Windows sürümü için glut isimli kütüphaneyi kullanmanız gerekiyor. Kendisinin asıl amacı opengl komutlarını bir parça basitleştirmek ve opengl i platformdan bağımsız olarak çalıştırmak. Ama klavye fonksiyonları çok zayıf olduğu için windows.h kütüphanesinden bir fonksiyon kullanmak zorunda kaldım. Bu yüzdende linux sürümünde glfw diye glut yerine başka bir kütüphane kullandım.

glut hakında bilgi için
http://www.opengl.org/resources/libraries/glut/
glfw hakkında bilgi için
http://glfw.sourceforge.net/

glut sürümünde linker a glut opengl ve glu kütüphanelerini vermelisiniz. glfw için biraz daha fazla şu kütüphaneler lazım olaca: glfw, GLU, GL, X11, pthread, Xxf86m, m, Xrandr. Ayrıcı -L ile şu klasörüde vermelisiniz: /usr/X11R6/lib

Programı yazarken hiç comment yapmamıştım =) Şu an biraz eklesem de hala kaynak kodu açık olmaktan çok uzak. Şu an saat sabah 7 ve uykusuzluk sayesinde hiç şevkim kalmadı doğrusu =D İlerde projeyi geliştirmeye başlarsam daha açık bir şekilde anlatmayı düşünüyorum.

Çalıştırabilir dosyalar

Windows
Linux

Kaynak kodları (windows visual c++ da hazırlandı, direk olarak dsp dosyasını açabilirsiniz. linux eclipse ile hazırlandı. c eklentisini kurduktan sonra workspace ine atın)

Windows

Linux

Game of Life

Sıfır kişilik oyun diye anılan game of life isimli oyunun java kullanarak yazılmış hali. Staj zamanında yazdığımız için staj konusu (concurrent programming) oyunun kendisinden önemli idi. Burada ki amaç thread nasıl kullanılır, cyclic barrier nedir öğrenmek idi sanırım. Daha fazla bilgi için kodu inceleyebilirsiniz.

gameoflifeGame of life hakkında bilgi için,

http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life

Kaynak dosyaları,

http://www.shultays.com/gameoflife.zip

(Comment yazarken farkettim ki o kadar da iyi bir kod sayılmaz)

Ayrıca bir de cep telefonu versiyonu var bunun ^^Elbette diğeri kadar kaynak isteyen bir şey değil.

http://www.shultays.com/gameoflife_me.java

Yalnız nasıl kuruluyor derleniyor, telefona kuruluyor hiç hatırlamıyorum =)