Makale Özeti

İlkokuldan beri oynadığı, basit, zevkli ve dikkat çekici Tic Tac Toe oyununu web için yapalım

Makale

AJAX Uygulamaları - Tic Tac Toe

    Merhabalar. AJAX (Asynchronous JavaScript language and XML) dan daha önce bahsetmiş ve kullanım örneklerine yer vermiştik. İsterseniz tanımına, dropdownlist örneğine ve suggest box örneğine bakabilirsiniz. Şimdi ise, kontrollerin dışında bir uygulama, hepimizin ilkokuldan beri oynadığı, basit, zevkli ve dikkat çekici Tic Tac Toe oyununu web için yapacağız.


Oyun sırasında sayfanın hiç refresh olmadığına dikkat!

    Tic Tac Toe'nun nasıl yapılacağı, nasıl çözüleceği ile ilgili internette bir çok örnek uygulama bulabilirsiniz, windows uygulamaları, web uygulamaları, çok farklı diller ve farklı platformlar için yazılmış bir çok versiyonu mevcuttur. Biz bu case study yi AJAX kullanarak yapacağız. Yani, iş mantığımız server da olacak, sayfamız aktif olarak kullanılırken server ile haberleşilecek, servera bilgi gidip gelecek fakat kullanıcının direct etkileşimli olduğu, sayfanın interaktif görünümünde bir değişiklik, bozulma ve ya post-back olmayacak. Bu durumda serverdaki metodlarımızı AJAX yapıları ile çağıracağız.

    Yapmamız gereken şeyleri hatırlayalım, sayfamızı ICallbackEventHandler interface'ini implement edecek şekilde yazmalıyız. Fakat daha da öncesinde görsel arayüzü nasıl yapacağımızı düşünelim. Animasyonda gördüğünüz şekli nasıl oluşturabiliriz? Bunun için 5x5 bir html tablo oluşturdum ve çizgi olarak gördüğünüz td lerin widh ve height özelliklerini değiştirdim. Bu td'lerin bgcolor özelliklerini de siyah verince, işte oyun tahtamız hazır bile. Sonrasında her kareye (toplam 3 x 3 = 9 adet) birer asp image box koydum ve default değerlerini, içi tamamen beyaz bir görüntüden oluşan bos.jpg ye eşitledim. image'ları  adlandırırken de Image(SatırNo)_(SütunNo) yapısını kolay kullanım açısından bir standart olarak kullandım.

<table>
                <tr>
                    <td>
                        <asp:Image ID="Image0_0" runat="server" ImageUrl="~/bos.jpg" /></td>
                    <td bgcolor="black" width="2px">
                    </td>
                    <td>
                        <asp:Image ID="Image0_1" runat="server" ImageUrl="~/bos.jpg" /></td>
                    <td bgcolor="black" width="2px">
                    </td>
                    <td>
                        <asp:Image ID="Image0_2" runat="server" ImageUrl="~/bos.jpg" /></td>
                </tr>
                <tr bgcolor="black" height="3px">
                    <td colspan="5">
                    </td>
                </tr>
 

    Yukarıda oyun tablomuzdaki ilk satırı görüyorsunuz. Diğer satırlar da aynı yapı ile oluşturulmakta.

    Peki X ve O yu nasıl göstereceğiz? Onları image olarak göstereceğimiz için herhangi bir çizim editoründe oluşturabileceğimiz X.jpg ve O.jpg dosylarından kullanacağım. (download bolumunden projeyi indirdiğinizde image'lar da gelecektir)

    Şimdi programımızdan bahsedelim. AJAX tan bahsediyor isek, hemen sayfamızı ICallbackEventHandler interface'ini implement eden bir yapıya getirelim ve kodlamaya başlayalım.

public partial class Oyun : System.Web.UI.Page, ICallbackEventHandler
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
        if (!IsPostBack)
        {
            CozumKumesi = new string[3, 3];
            Session["CozumKumesi"] = CozumKumesi;
      
        }
 
        OyunSeviyesi = int.Parse(Request.QueryString["Seviye"]);
        string ScriptRef = "";
        foreach (Control c in this.form1.Controls)
        {
            if (c.ClientID.Length >= 5)
 
                if (c.ID.Substring(0, 5) == "Image")
                {
                    ScriptRef = this.ClientScript.GetCallbackEventReference(
                        this,
                        "'" + c.ID + "'",
                        "OnCallback",
                        "'" + c.ID + "'",
                        "OnCallback",
                        true);
                    Image hc = (Image)c;
                    hc.Attributes.Add("onClick", ScriptRef);
                }
        }
    }
 

    Gördüğünüz gibi, sayfamızı ICallbackEventHandler' dan ürettik ve sayfa yüklenirken de tüm imajlara onClick te çalışacak olan fonksiyonlarını attribute olarak ekledik.

  void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
    {
        this.eventArgument = eventArgument;
    }
 
 string ICallbackEventHandler.GetCallbackResult()
    {
        CozumKumesi = (string[,])Session["CozumKumesi"];
        int X = int.Parse(eventArgument.Substring(5, 1));
        int Y = int.Parse(eventArgument.Substring(7, 1));
 
        CozumKumesi[X, Y] = "X";
 
        string RetVal;
        if (OyunSeviyesi < 1)
            RetVal = SiradanOyna();
        else
            RetVal = AkilliOyna();
 
        return RetVal;
    }
 

    Yukarıdaki gibi, hangi imaja basıldığında o imajın hangisi olduğunu belirleyen ve CozumKumesi olarak adlandırdığım 3 x 3 lük string array'e atan kodlarımızı belirledik. Aslında AJAX mantığı için yapmamız gereken çok az iş kaldı. Dikkat ederseniz şimdiye kadarki kodlarımız sadece clienttan bilgi alıp onu işlemek üzerine. Peki serverdan geri dönen cevabı (RetVal) client nasıl işleyecek? Elbetteki Java Script ile. Client tarafında, RetVal değerindeki mesaji decode edip ona göre o hamleyi yapacak, görsel olarak işlemi gerçekleştirecek olan kodlarımız da aşağıdaki gibi.   

    <script>
     function OnCallback(ServerOyunu,ClientOyunu)
    {     
    var arSonuc=ServerOyunu.split("+");
    var c = document.getElementById(ClientOyunu);
    c.src="X.jpg";
   
    if (arSonuc[0].length==8) //image isimleri sadece 8 karakter olacaktir.
    {
    c = document.getElementById(arSonuc[0]);
    c.src="O.jpg";
    }
   
    if (arSonuc[1].substr(0,1)=="*") //gosterilecek mesajlar * ile baslayacaklardir.
      alert(arSonuc[1]);
    
    }
    </script>
 

    Sizinde gördüğünüz gibi, ServerOyunu olarak gelen parametre serverdan üretilerek gelen RetVal değeri. Buna bir iki örnek verecek olursak "Image0_0+devam" ve "null+*X kazandi.....!" stringlerini gösterebiliriz. Bu çok hoşuma gitmeyen ama ilk akla gelen ve uygulanması kolay olan bir yöntem. Dolayısıyla javascript ile serverdan gelen bu stringi parse ederek uygulamanın ne şekilde devam edeceğini belirleyebiliyorum.

    Açıklamadığımız sadece uygulamada oyun kazanma metodları ve hamle üretme metodları kaldı. Bunlar incelendiğinde oldukça kolay anlaşılacak şeyler olsa da, hamle üreten iki metoddan bahsetmek istiyorum. Oyunda (animasyonda da gördüğünüz gibi) iki seviye bulunmakta. Her iki seviye de önce oyunda kazanan olup olmadığını, oyun sahasında boş alan olup olmadığını kontrol eder, sonrasında kolay olan seviyede, sol üstten başlayarak sol alta sonra orta üste... şeklinde bir sıra izleyerek boş gördüğü ilk alana O işaretini koyar. Bu hiçbir analize dayalı olmayan bir oyun şeklidir ve oyuncunun galibiyetine fazlasıyla açıktır. "Akıllı oyna"  modu ise daha stratejik bir açıdan çözüme bakar. Stratejik açıdan oyuna bakmamız gerekir ise 4 adım karşımıza çıkar.

  1. Kazanan hamle var mı?
  2. Kaybeden hamle var mı? (boş bırakıldığı durumda karşı tarafın ilk hamlesi ile oyun kaybedilebilir durumda mı?)
  3. Orta kare boş mu?
  4. Sıradan oyna (basit oynama şekli)

    1 2 ve 3. sorulardan birinin cevabı evet ise hemen o hamle gerçekleşir. Cevap hepsinde de hayır geliyor ise, rastgele bir hamle oynanır. Çünkü ne kazanılan ne kaybedilen ne de stratejik olabilinecek bir durum vardır. (elbette daha güçlü stratejiler gerçekleştirilebilir)

    Dolayısıyla basit ve zor seviyede bir hamle üretilir, bu hamle mesaj olarak formatlanır ve clienta gönderilir. Yukarıda gördüğümüz JavaScript kodu bu mesajı parse ederek görsel olarak gerekli işlemi yapar.

    Sonuç olarak, post-back olmayan, AJAX yapısı ile çalışan bir Tic Tac Toe oyunumuz oldu. Bir sonraki versiyonunda hamleleri server tarafından üretmek yerine, o anda servera bağlanan iki kişinin oynayabileceği bir sistemin nasıl olabiliceğini göreceğiz. Bu sayede (görsel olarak olmasada)  yahoo games gibi uygulama mantıklarının temellerini atacağız.

İyi Eğlenceler.

Kivanc OZUOLMEZ

VS.NET 2005 projesi