XOX Oyunu

X-O-X Oyunu

Oyunun Kodları içerisinde açıklamalar bulunmaktadır. Gerekli olan .png dosyalarını Yan taraftan alabilirsiniz. Ayrıca Temel arayüzü Yazının kapağından alabilirsiniz.

import pygame as pg
import sys
import time
from pygame.locals import *

#Genel değişkenler
XO = 'x'
kazanan = None
berabere = False
width = 400 #en boyutumuz değiştirebilirsiniz
height = 400 #boy boyutumuz kare şeklinde olcak oyunumuz
cizgi = (0,0,0) #RGB şeklinde siyah çizgilerimiz olacak

#Oyun Tahtamız
tahta = [[None]*3,[None]*3,[None]*3] #Burda Liste Yöntemi ile 3er'li 3 tane alt alta sıra oluşturduk.

#Pygame Penceremizin Ayarını yapalım
pg.init() #Pygame'i çağırıp kendi içinde döndürmesini başlatıyoruz
fps = 30 #Frame Per Second Saniye başındaki resim sayısı demektir. Oyununuzun tazelenme hızıdır
saat = pg.time.Clock() # Oyunda süreyi göstermek için saat fonksiyonu.
ekran = pg.display.set_mode((width,height+100)) #Ekranın altında 100 pixellik açıklama kısmı için +100 dedik.
pg.display.set_caption("ikso Oyunu") #Ekranın en üstündeki yazımız.

#Resimlerimizi yükleyelim
anaekran = pg.image.load('ikso.png') #Projenizin olduğu dosyada olmasına dikkat etmeniz gerek
x_img = pg.image.load('ikso X.png')
o_img = pg.image.load('ikso O.png')

#Resim Boyutunu düzeltelim
x_img = pg.transform.scale(x_img, (80,80)) #400lük kutuya 3x3 yerleşebilsin önemli olan boyutu değiştirebilirsiniz
#boyutu değiştirirseniz XOciz tanımındaki hesaplarıda boyutunuza uyarlamanız gerek.
o_img = pg.transform.scale(o_img, (80,80))
anaekran = pg.transform.scale(anaekran, (width,height+100)) #Bu resmin %20 kadar uzamasına neden olacak.
#Yaparken benim gibi dikkatsiz davranmayın resmi hazırda 400x500 yapmanızı tavsiye ederim.

#Oyunun Açılışı (Ufak bir animasyon ile)
def oyun_acilis():
    ekran.blit(anaekran,(0,0))
    '''Burda aslında şunu yaptık: pygame.display.set_mode.blit ile 400x500 olan
    ana ekranımızı pygame penceremize çizdik. Burda blit çiz manasına gelir. blit komutundan önceki kodumuz ise
    ekran modunu tanımlama kodumuzdur.'''
    pg.display.update() #Ekranın güncellemesini sağlıyoruz.
    time.sleep(5) #Ekranı 1 saniyeliğine durdurup aşağıdada beyaz ile doldurcaz
    ekran.fill((255,255,255)) #Ekranın arka planını beyaz yapıyoruz.

    #Dikey çizgileri çizelim
    pg.draw.line(ekran, cizgi, (width / 3, 0), (width / 3, height), 7)
    pg.draw.line(ekran, cizgi, (width / 3*2, 0), (width / 3*2, height), 7)
    '''Burda pg.draw.line komutu ile çizgiyi çiz komutu verdik. Parantez içinde (yerini,rengini,başlangıç noktası(x,y)
    ,bitiş noktasını(x,y),kalınlık) olarak belirttik. Unutmayın rengini projenin en üstünde değişkenler kısmında
    belirttik. Başlangıç noktamız ilk kodumuzda x için: ekranın 3'te 1'i iken ikinci kodumuzda ekranın 3'te 2'sinde
    bulunmaktadır ve y ekseni 0'dan yüksekliğe kadar gidecektir'''

    #Yatay çizgileri çizelim
    pg.draw.line(ekran,cizgi,(0,height/3),(width,height/3),7)
    pg.draw.line(ekran,cizgi,(0,height/3*2),(width,height/3*2),7) #Dikey'in aynı prensibi
    durum_cubugu() #Oyun durumunu belirleyecek olan alt kısımda ayırdığımız 100px'lik kısmı çizdirecek.

def durum_cubugu():
    global berabere #Her yere ulasabilecek bir berabere tanımı.

    if kazanan is None:
        mesaj = XO.upper() + " Sırada" #.upper() büyük harf yapmak için. Bildiğinizi umuyorum ama yine belirteyim.
    else:
        mesaj = kazanan.upper() + " kazandı!"
    if berabere:
        mesaj = 'Oyun Berabere!'

    font = pg.font.Font(None,30) #Font'u belirler eğer bir font dosyanız varsa None ile değiştirin, font boyutu.
    text = font.render(mesaj,1, (255,0,0)) #Yazımızı renderliyoruz. (yazı,antialias,renk,arkaplan) olarak ayarlanır.

    #Mesaj'ı oyun tahtamıza aktaralım
    ekran.fill((0,0,0), (0,400,500,100))
    text_kutu = text.get_rect(center=(width/2, 500-50)) #Burda yazımızın kutusunun orta noktasını belirledik
    ekran.blit(text,text_kutu) #Yazımızı blit komutu ile alt kutumuza yerleştirdik.
    pg.display.update() #Güncelleme yapmazsa değişim olmayacaktır yazıda bu yüzden güncellenmesi gerek.

def kazanan_kontrol():
    '''Burda kazananı kontrol edecek bir fonksiyon oluşturacağız. Burda önemli olan X veya O hamlelerinden 3 adet yan
    yana, alt alta veya çapraz olarak oluşturulduysa oyunun durmasın sağlamak. O zaman bu fonksiyon her hamleden sonra
    çağrılması gereken bir fonksiyondur bunu unutmayalım.'''

    global tahta, kazanan, berabere

    # Kazanan Satırı Kontrol edelim
    for row in range (0,3):
        if ((tahta[row][0]==tahta[row][1]==tahta[row][2]) and (tahta[row][0] is not None)):
            kazanan = tahta[row][0]
            pg.draw.line(ekran,(255,0,0),(5,(row+1)*height/3-height/6),\
                         (width-5,(row+1)*height/3-height/6),4)
            break
    '''Evet kafalar karıştı şimdi. Burda neler yaptık bir bakalım. Şimdi kısa olsun diye Satırı row olarak
    tanıtıp bir döngüye soktum. 3 satırımız olduğu için bunu bu aralık içinde yaptık. 
            
    Eğer satır listemizde bulunan ilk [0], ikinci[1] ve üçüncü[2] elemanı aynı ise kazandı durumu olacağı için bunlar eşit ise
    diyip ilk eleman None yani boş değil ise dedik. Burda illa ilk demek zorunda değiliz 1 yada 2 de 
    diyebilirdik. Önemli olan oyuna ilk başladığımızda liste elemanlarının hepsi boş olacağı için hemen 
    başlar başlamaz bir kazanma durumu oluşmasını engellemek.
            
    Kazananı döngümüzdeki kaçıncı döngüde ise ilk eleman olarak belirttik. Yine belirteyim burda 1 veya 2 de
    diyebilirdik
            
    Kazanma durumunda üstüne bir çizgi çekilsin diye çizme komutu oluşturduk ve parantez içini (nerde, renk,
    (x,y)başlangıcı,(x,y)bitişi,kalınlık) olarak düzenledik. Hemen ekrana bitişik başlayıp bitmesin diye
    5ten başlatıp sonunda 5 çıkardım.
            
    (x,y) kısmını için: ilk x = 5 dedik ilk y = döngüdeki sayı+1 çünkü döngü 0'dan başlıyor! çarpı yükseklik
    bölü 3 eksi yükseklik bölü 6 ((y/3)-(y/6)) dan Satırın orta noktasını bulmuş oluyoruz! '''

    #Kazanan Sütunu Kontrol edelim
    for col in range(0,3):
        if ((tahta[0][col]==tahta[1][col]==tahta[2][col]) and (tahta[0][col]is not None)):
            kazanan = tahta[0][col]
            pg.draw.line(ekran,(255,0,0),((col+1)*width/3-width/6,5),\
                         ((col+1)*width/3-width/6,height-5),4)
            break

    #Kazanan Çaprazı Kontrol edelim
    if (tahta[0][0]==tahta[1][1]==tahta[2][2]) and (tahta[0][0] is not None):
        kazanan = tahta[0][0]
        pg.draw.line(ekran,(255,0,0),(50,50),(350,350),4)

    if (tahta[0][2]==tahta[1][1]==tahta[2][0]) and (tahta[0][2] is not None):
        kazanan = tahta[0][2]
        pg.draw.line(ekran,(255,0,0),(350,50),(50,350),4)

    if (all([all(row) for row in tahta]) and kazanan is None):
        berabere = True
    durum_cubugu()

def XOsec(row,col):
    global tahta, XO
    if row == 1:
        posx = 30
    if row == 2:
        posx = width/3+30
    if row == 3:
        posx = width/3*2+30

    if col == 1:
        posy = 30
    if col == 2:
        posy = height/3+30
    if col == 3:
        posy = height/3*2+30

    tahta[row-1][col-1] = XO
    if(XO == 'x'): #başlangıcı x ile yapıp sıramızı o'ya veriyoruz.
        ekran.blit(x_img,(posy,posx))

        XO= 'o'
    else: #if komutuyla o'ya sıramızı verdiğimiz için artık bu komut geçerli olacaktır if(XO =='o') olarakta yapılırdı
        #gereksiz fazla if komutu sistem şişmesine neden olmakta bu yüzden tavsiye etmem düzgün kod değildir!
        ekran.blit(o_img,(posy,posx))
        XO='x'
    pg.display.update()
    #print(posx,posy) komutu ile isterseniz terminalde hareketleri görebilirsiniz
    #print(tahta) komutu ile isterseniz tahtla Liste durumunu görebilirsiniz.

def secim(): #Yaptığımız tıklama sonucu seçim tanımımız.
    x,y = pg.mouse.get_pos() #Farenin x ve y pozisyonunu seçen komuttur.

    if(x<width/3):
        col = 1
    elif(x<width/3*2):
        col = 2
    elif(x<width):
        col = 3
    else:
        col = None

    if (y<height/3):
        row = 1
    elif (y<height/3*2):
        row = 2
    elif (y<height):
        row = 3
    else:
        row = None
    #print (row,col) satır ve sütun çıktısnı terminalde isterseniz kullanabilirsiniz.

    '''Yine bir açıklama yapalım. Şimdi programımızın penceresindeki x ve y kooordinatlarını ve yine programımızın 
    penceresinde tıkladığımız x ve y koordinatlarını kıyaslamış olacağız yukarıdaki açıklamada. Ve bu bilgileri
    de XOsec komutumuza aktaracağız.'''

    if (row and col and tahta[row-1][col-1] is None): #Burda -1 yaptık çünkü liste 0'dan başlar!
        global XO
        XOsec(row, col)
        kazanan_kontrol() #Kazananı her hamlede kontrol ettiriyoruz!

def yeniden_baslat():
    global tahta, kazanan, XO, berabere
    time.sleep(3)
    XO = 'x'
    berabere = False
    oyun_acilis()
    kazanan = None
    tahta = [[None]*3,[None]*3,[None]*3]
    #Oyunu sıfırladık

'''Oyunu başlatıp çağırma vaktimiz geldi. Sonrasında bir sonsuz döngü oluşturup faremiz ile işlem yapıp yapmadığımıza
bakacağız. Eğer bir yenme yada berabere durumu oluşursada oyunu yeniden_baslat fonksiyonu ile sıfırlayacağız. '''

oyun_acilis()
while(True):
    for event in pg.event.get():
        if event.type == QUIT:
            pg.quit()
            sys.exit()
        elif event.type is MOUSEBUTTONDOWN :
            secim()
            if(kazanan or berabere):
                yeniden_baslat()
    pg.display.update()
CLOCK.tick(fps)

Yorum bırakın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir