Android Satranç Uygulaması – Asgard Projesi
- January 12, 2013
Asgard Projesi için hazırlamakta olduğum Android uygulamasının kaynak kodları. İlk mobil uygulama olduğu için kodlar çok dağınık. Yakın zamanda baştan yazmam gerekecek(en azından 2. uygulamayla karşılaştırınca fark gözüküyor).
Notlar:
– Program Windows, Linux, MacOS, Android ve iOS işletim sistemlerinde değişiklik yapılmadan çalışabilir(Apple ürünlerinde denemedim, derlemeyi bilen birileri derleyip haber verirse hep beraber sonucu görürüz.) Windows için .exe uzantılı hale getirilmesi de birkaç dakikalık işlem sonucu mümkündür, uğraşmak isteyen olursa “packaging kivy application for Windows” araması işlerini görecektir.
– Sunucu bağlantı kodları kullanılan framework sitesinden alınmış ve deneme amaçlı olarak eklenmiştir. Sunucuya oynanan konumun verilerini yollamaktadır. Sunucu kaynak kodunu güvenlik sebebiyle bir süre daha paylaşamıyorum ama herhangi basit bir sunucuyu istediğiniz dilde yazıp 4444 portundan(ya da istediğiniz porttan açıp programdan portu değiştirip) kurarsanız direk gözlemleyebilirsiniz. Ama bu gerekli değil çünkü sunucu bağlantısı olmazsa oyun yine de başlıyor.(Tekrar geliştirme sebebim 1).
– Oyunu başlattıktan sonra menüye dönünce problem ortaya çıkıyor(Sebep 2, menü eklemeye uygun olmayan kod yapısıyla girişmek). Normal bir şekilde oyuna başlayınca bir sıkıntı yok.
– Oyunda iki tarafı da çalıştıran kişi kontrol ediyor(test etmek için tek kişilik daha iyi bir çözüm şu anlık bulamadım).
– Taş renkleri pek iç açıcı olmayabilir (RGB kodları biraz uydurma oldu.).
– APK halini BURADAN indirebilirsiniz. (Neden 8mb? Python çekirdeği+birkaç kullanılan ve kullanılmayan kütüphaneler derlemeye dahil.)
– Geri dönüşler programcının yaşam kaynaklarındandır, ağır eleştirilere açığım.
– Tamamen OOP girmeyi gerektirdiğine inandığım bir framework ile minimum OOP oranında çalıştığımı kodlara 3 sn bakınca anlayabilirsiniz(Sebep 3).
– Şu ana kadar kullanılan modüller: Kivy, Socket, Twisted
– Son olarak da en önemli not: kodlarda from chess import * kısmı için chesspy adlı uygulamayı http://www.willmcgugan.com blogunun sahibinden izin alarak kullandım. Adreste kaynak kodu ve açıklamaları mevcut. İşine yarayan olursa bendeki halini de gönderirim.
Kaynak kodları:
#-*-coding:utf-8-*-
# Online icin ön tanimlamalar basliyor
from kivy.support import install_twisted_reactor
install_twisted_reactor()
from twisted.internet import reactor, protocol
class EchoClient(protocol.Protocol):
def connectionMade(self):
self.factory.app.on_connection(self.transport)
def dataReceived(self, data):
print "Gelen veri ", data
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def __init__(self, app):
self.app = app
def clientConnectionLost(self, conn, reason):
print "Connection lost"
def clientConnectionFailed(self, conn, reason):
print "Connection failed"
# Online icin ön tanimlamalar bitiyor
# Esas uygulama kodlari basliyor
from chess import *
from urllib import urlopen
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
#from kivy.core.window import Window
# Ekran Boyutlari: print Window.center, Window.size
x = False # Butun oyun bu degiskende tutuluyor.
liste = []
taslar = {"P" : "images/pawnw.gif", "p" : "images/pawnb.gif",
"r" : "images/rookb.gif", "R" : "images/rookw.gif",
"n" : "images/knightb.gif", "N" : "images/knightw.gif",
"b" : "images/bishopb.gif", "B" : "images/bishopw.gif",
"q" : "images/queenb.gif", "Q" : "images/queenw.gif",
"k" : "images/kingb.gif", "K" : "images/kingw.gif",
"." : "images/empty.gif"
} # Beyazlar buyuk, siyahlar kucuk
online = [False,]
class AnaMenu(GridLayout):
"""
Giris menusunun en basit halidir.
"""
def __init__(self):
GridLayout.__init__(self)
self.cols = 3
def f(self,*k):
print "basti"
class YourWidget(Widget):
pass
class Oyun():
def __init__(self,liste):
self.liste = liste
self.oyun = Game()
self.oyun.setup()
self.ongoing = True
self.sayac = 0
self.tut = ""
def send_message(self, dataToSend, *k):
msg = dataToSend
print msg
if msg and a.connection:
a.connection.write(msg)
def baslangicTasDuzeni(self):
self.ekranGuncelle()
def oyna(self,hareket,*k):
if hareket == "":
return False
self.tut += hareket
if len(self.tut) == 4:
self.knm = self.tut[:2]+" "+self.tut[2:]
self.konumYolla(self.knm)
self.tut = ""
def tahtaGoster(self,*k):
#print self.oyun.board
pass
def tasBul(self, yer):
abc = self.oyun.board
y = str(abc).split("n")[1:-2]
for i in xrange(8):
#print y[i][4:-2].split()
pass
def konumYolla(self,konum):
abc = self.oyun.board
y = str(abc).split("n")[1:-2]
try:
self.hareket = self.oyun.board.parse(konum)
self.oyun.move(self.hareket)
self.ekranGuncelle()
self.send_message(self.knm)
print "mesaj gonderildi"
except ParseError, error:
print "Hata: ", error
def sifirla(self):
pass
def ekranGuncelle(self):
abc = self.oyun.board
y = str(abc).split("n")[1:-2]
for i in xrange(8):
for k,j in enumerate(y[i][4:-2].split()):
liste[i][k].resim_id.source = taslar[j]
liste[i][k].tas = j
class Kutula(Button):
tahta_konum = StringProperty()
tas = StringProperty()
def hangieleman(self):
return "images/buton1.gif"
def on_press(self,*k):
x.oyna(self.tahta_konum)
class Satranc(App):
def menu(self,*k):
self.root.clear_widgets()
abcd = AnaMenu()
abcd.gb.on_press = self.oyunagir
self.root.add_widget(abcd)
def oyunagir(self):
self.root.clear_widgets()
btn1 = Widget(size_hint=(.2, 1))
tahta = GridLayout(rows = 8, cols = 8, padding = 3, size_hint=(.8,1))
self.connect_to_server()
self.arka = [(1,0,1,1),(0,1,1,1)]
onceki = 0
for i in xrange(8):
eklenecek = []
onceki += 1
for j in "abcdefgh":
kutu = Kutula(text = " ")
kutu.tahta_konum="%s%d" %(j,8-i) # Her karenin yeri
kutu.id = kutu.tahta_konum
kutu.resim_id.source = "images/empty.gif"
onceki+=1; renk = onceki % 2
kutu.background_color = self.arka[renk]
tahta.add_widget(kutu)
eklenecek.append(kutu)
print "bi kutu daha ekledim"
liste.append(eklenecek)
del eklenecek
self.root.add_widget(tahta)
a = YourWidget(size_hint = (.2,1)) # Ekranin sag kismi
a.buton.on_press = self.baslat
a.buton2.on_press = self.menu
self.root.add_widget(a)
def baslat(self,*k):
global x
x = Oyun(liste) # Oyunu baslat
print "Oyun baslatma fonk calisti"
x.ekranGuncelle()
print "ekran guncellendi"
def build(self):
# Action Time!
self.root = GridLayout(cols = 2, spacing = 5, padding = 5)
self.menu()
return self.root
def connect_to_server(self):
# reactor.connectTCP('SUNUCUIP', 4444, EchoFactory(self))
reactor.connectTCP('SUNUCUIP', 4444, EchoFactory(self))
def on_connection(self, connection):
global taraf
print "connected succesfully!"
self.connection = connection
taraf = 1 # TARAF
if __name__ == "__main__":
a = Satranc()
a.run()
satranc.kv dosyası:
<Kutula>:
resim_id: resim
pos: self.pos
size: self.size
Image:
id: resim
size: root.size # SORULACAK!!!
pos: root.pos
<YourWidget>:
buton: basla
buton2: menu
Button:
id: basla
text: "Başla!"
size: root.width,100
pos: root.pos
padding: 5,5
Button:
id: menu
text: "Menü!"
size: root.width, 100
pos: root.x, root.y+110
padding: 5,5
<AnaMenu>:
gb: giris
kb: kayit
Image:
size_hint: 0.5,1
source: "images/asgardlogo.gif"
Button:
id: giris
size_hint: (.25, 1)
text: "Giriş Yap"
padding: 5,5
Button:
id: kayit
size_hint: 0.25, 1
text: "Kayıt Ol"
pos_hint: 0.2