Pazar, Kasım 21, 2010

ASP .Net ile Tic Tac Toe

Geçenlerde bir arkadaşımla msn'de sunucu tabanlı bir dille Tic Tac Toe yazılabilir mi,yazılamaz mı, yazılırsa nasıl olur şeklinde muhabbet etmiştik. İkimizinde hem fikir olduğumuz nokta böyle bir oyunu JavaScript ile yazmanın daha mantıklı olduğuydu ama meraktan sunucu tabanlı bir dille nasıl olabileceğini konuştuk. Bende bu aralar ASP .Net ile haşir neşir olduğumdan ve daha öncede Tic Tac Toe ile ilgili tecrübem olduğunda yazmaya karar verdim.

C++ ile yaptığım versiyonunda tek bir bilgisayarda iki kişi tarafından (fareyi sırayla kullanarak) oynanabiliyordu. Buna ufak bir yapay zeka(AI) yazarak bilgisayara karşı oynayabilecek şekilde yaptım.

Kodlar

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace TicTacToe
{
public partial class Default : System.Web.UI.Page
{
//Hangi şekillerde karakterden 3 tane aynı hizaya gelebilir
private static int[,] ihtimaller = new int[,] { {0,1,2}, {3,4,5},
{6,7,8}, {0,3,6},
{1,4,7}, {2,5,8},
{0,4,8}, {2,4,6}};

protected void Page_Load(object sender, EventArgs e)
{
int[] harita = haritaOlustur();

if (Request.QueryString["hucre"] != null)
{
int index = Convert.ToInt32(Request.QueryString["hucre"]);
harita[index] = 1;
bilgisayarOyna();
}
else if (Request.QueryString["yeniOyun"] != null)
{
Session.Clear();
Response.Redirect("Default.aspx");
}

/*kazananVarMi() fonksiyonu 3 farklı sayı döndürebilir:
0 => Kazanan yok
1=>Oyuncu kazandı
2=>Bilgisayar Kazandı*/
int kazanan = kazananVarMi();
if (kazanan > 0)
{
string strKazanan = "<center><span style='font-size:35pt;font-weight:bold'>";
strKazanan += (kazanan == 1 ? "Sen Kazandın" : "Bilgisayar Kazandı")
+ "</span></center>";
Response.Write(strKazanan);
}
else if (berabereMi())
{
string strKazanan = "<center><span style='font-size:35pt;font-weight:bold'>"
+ "BERABERE</span></center>";
Response.Write(strKazanan);
}
else
{
tabloOlustur(harita);
Session["harita"] = harita;
}


}

private void tabloOlustur(int[] pHarita)
{
int sayac = 0;
for (int i = 0; i < 3; i++)
{
TableRow satir = new TableRow();
for (int k = 0; k < 3; k++)
{
TableCell hucre = new TableCell();
hucre.Width = 75;
hucre.Height = 75;
hucre.HorizontalAlign = HorizontalAlign.Center;
hucre.Attributes.Add("onMouseOver", "this.bgColor='#00c0ff'");
hucre.Attributes.Add("onMouseOut", "this.bgColor=''");
if (Convert.ToUInt32(pHarita[sayac]) == 0)
hucre.Text = "<a href='Default.aspx?hucre=" + sayac.ToString() + "'>Tıkla</a>";
else if (Convert.ToUInt32(pHarita[sayac]) == 1)
hucre.Text = "<span style='font-size:35pt;font-weight:bold'>X</span>";
else
hucre.Text = "<span style='font-size:35pt;font-weight:bold'>O</span>";

satir.Cells.Add(hucre);
sayac++;
}
tablo.Rows.Add(satir);
}
}

private int[] haritaOlustur()
{
int[] harita = new int[9];
if (Session["harita"] != null)
{
harita = (int[])Session["harita"];
}
else
{
for (int i = 0; i < 9; i++)
harita[i]=0;
}

return harita;
}

private int kazananVarMi()
{
int[] harita = haritaOlustur();
int durum = 0;
int hucre1 = 0, hucre2 = 0, hucre3 = 0;
for (int i = 0; i < 8; i++)
{
hucre1 = ihtimaller[i, 0];
hucre2 = ihtimaller[i, 1];
hucre3 = ihtimaller[i, 2];

if (harita[hucre1] != 0 && harita[hucre2] != 0 && harita[hucre3] != 0)
{
if (harita[hucre1] == harita[hucre2] && harita[hucre1] == harita[hucre3])
durum = harita[hucre1];
}
}

return durum;
}

private bool berabereMi()
{
//Eğer harita dizisinde değeri 0 olan eleman yoksa oyun Berabere bitmiş demektir
int[] harita = haritaOlustur();
for (int i = 0; i < 9; i++)
{
if (harita[i] == 0)
return false;
}

return true;
}

private void bilgisayarOyna()
{
int hucre1 = 0, hucre2 = 0, hucre3 = 0;
bool durum = false;
int[] harita = haritaOlustur();
for (int i = 0; i < 8; i++)
{
hucre1 = ihtimaller[i,0];
hucre2 = ihtimaller[i,1];
hucre3 = ihtimaller[i,2];

//Bilgisayarın tek hamlede kazanma ihtimali var mı ?
if (harita[hucre1] == 2 && harita[hucre2] == 2 && harita[hucre3] == 0)
{
durum = true;
harita[hucre3] = 2;
break;
}
else if (harita[hucre1] == 2 && harita[hucre3] == 2 && harita[hucre2] == 0)
{
durum = true;
harita[hucre2] = 2;
break;
}
else if (harita[hucre2] == 2 && harita[hucre3] == 2 && harita[hucre1] == 0)
{
durum = true;
harita[hucre1] = 2;
break;
}
//Karşıdaki oyuncunun tek hamlede kazanma ihtimali var mı ?
else if (harita[hucre1] == 1 && harita[hucre2] == 1 && harita[hucre3] == 0)
{
durum = true;
harita[hucre3] = 2;
break;
}
else if (harita[hucre1] == 1 && harita[hucre3] == 1 && harita[hucre2] == 0)
{
durum = true;
harita[hucre2] = 2;
break;
}
else if (harita[hucre2] == 1 && harita[hucre3] == 1 && harita[hucre1] == 0)
{
durum = true;
harita[hucre1] = 2;
break;
}
}

/*Oyunun bitme ihtimali yoksa rasgele oynar.
*Aslında burayıda nasıl oynayacağını detaylandıracak
*kodlar yazılarak daha akıllı hale getirilebilir
*/
if (!durum)
harita[bosHucreBul()] = 2;
}

private int bosHucreBul()
{
Random sayi = new Random();
int hucre = sayi.Next(0, 9);
int[] harita = haritaOlustur();

/*BerabereMi fonksiyonu boş hücre varmı diye kontrol eder.
Eğer kontrole bunu da eklemezsek ve hiç boş hücre yoksa
Sonsuz döngüye girer*/
while (harita[hucre] != 0 && !berabereMi())
{
hucre = sayi.Next(0, 9);
}

return hucre;
}
}
}



Ekran Görüntüsü

Proje Olarak indirmek için aşağıdaki linki kullanabilirsiniz. Visual Studio 2010 ile hazırlanmıştır. İsteyen için PHP versiyonu da mevcut :)
İNDİR

Hiç yorum yok: