Android Satranç Uygulaması – Asgard Projesi

asgard-android-projesi-oyunAsgard 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.

asgard-android-projesi-acilis

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

 

 
comments powered by Disqus