OKEY 101 OYUNUN KOD DOKUMANI
encode Fonksiyonu
Parametre (b) – byte
dizisi
encode fonksiyonu, girilen byte dizisini base64 formatında bir string'e çevirir.
encode fonksiyonu, girilen byte dizisini base64 formatında bir string'e çevirir.
Base64 Kullanımı –
Amaç
Base64, ikili veriyi metin olarak güvenli taşımak veya saklamak için yaygın olarak kullanılır.
Base64, ikili veriyi metin olarak güvenli taşımak veya saklamak için yaygın olarak kullanılır.
func encode(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}
decode Fonksiyonu
Parametre (s) – base64 formatında
metin
decode fonksiyonu, base64 ile kodlanmış metni çözerek orijinal byte dizisine dönüştürür.
decode fonksiyonu, base64 ile kodlanmış metni çözerek orijinal byte dizisine dönüştürür.
Base64 Çözme – Amaç
Şifreleme veya veri iletiminde base64 kullanılan veriler, bu fonksiyon ile tekrar ham veriye dönüştürülür.
Şifreleme veya veri iletiminde base64 kullanılan veriler, bu fonksiyon ile tekrar ham veriye dönüştürülür.
func decode(s string) ([]byte, error) {
data, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, err
}
return data, nil
}
Encrypt Fonksiyonu
Parametre (text) – Şifrelenecek düz
metin
AES algoritması ile şifrelenmek üzere kullanıcıdan alınan ham veri.
AES algoritması ile şifrelenmek üzere kullanıcıdan alınan ham veri.
Parametre (MySecret) – Anahtar
(key)
AES algoritmasında kullanılacak olan şifreleme anahtarı (string olarak verilmelidir).
AES algoritmasında kullanılacak olan şifreleme anahtarı (string olarak verilmelidir).
Amaç – AES Şifreleme
Bu fonksiyon, verilen metni AES algoritması (CFB modu) ile şifreler ve base64 string olarak geri döner.
Bu fonksiyon, verilen metni AES algoritması (CFB modu) ile şifreler ve base64 string olarak geri döner.
func Encrypt(text, MySecret string) (string, error) {
block, err := aes.NewCipher([]byte(MySecret))
if err != nil {
return "", err
}
plainText := []byte(text)
cfb := cipher.NewCFBEncrypter(block, bytes)
cipherText := make([]byte, len(plainText))
cfb.XORKeyStream(cipherText, plainText)
return encode(cipherText), nil
}
Decrypt Fonksiyonu
Parametre (text) – Şifrelenmiş veri
(base64)
decode fonksiyonuyla çözülecek base64 formatındaki şifrelenmiş metindir.
decode fonksiyonuyla çözülecek base64 formatındaki şifrelenmiş metindir.
Parametre (MySecret) – Anahtar
(key)
AES algoritmasında çözümleme işlemi için kullanılan şifreleme anahtarıdır.
AES algoritmasında çözümleme işlemi için kullanılan şifreleme anahtarıdır.
Amaç – Şifre Çözme
Bu fonksiyon, AES algoritması (CFB modu) ile şifrelenmiş metni çözerek orijinal düz metni elde eder.
Bu fonksiyon, AES algoritması (CFB modu) ile şifrelenmiş metni çözerek orijinal düz metni elde eder.
func Decrypt(text, MySecret string) (string, error) {
block, err := aes.NewCipher([]byte(MySecret))
if err != nil {
return "", err
}
cipherText, err := decode(text)
if err != nil {
return "", err
}
cfb := cipher.NewCFBDecrypter(block, bytes)
plainText := make([]byte, len(cipherText))
cfb.XORKeyStream(plainText, cipherText)
return string(plainText), nil
}
HashAndSalt Fonksiyonu
Parametre (pwd) – Parola (byte
dizisi)
Şifrelenmek üzere alınan ham parola verisi. `[]byte` formatında olmalıdır.
Şifrelenmek üzere alınan ham parola verisi. `[]byte` formatında olmalıdır.
Amaç – Parola Hashleme
Bu fonksiyon, kullanıcı parolasını bcrypt algoritması ile hash'ler ve güvenli biçimde string olarak döndürür.
Bu fonksiyon, kullanıcı parolasını bcrypt algoritması ile hash'ler ve güvenli biçimde string olarak döndürür.
bcrypt.MinCost – Güvenlik
seviyesi
Şifreleme işlemi için minimum işlem maliyeti ayarlanır (düşük CPU kullanımı sağlar).
Şifreleme işlemi için minimum işlem maliyeti ayarlanır (düşük CPU kullanımı sağlar).
func HashAndSalt(pwd []byte) string {
hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost)
if err != nil {
log.Println(err)
}
return string(hash)
}
ComparePasswords Fonksiyonu
Parametre (hashedPwd) – Hash'lenmiş
şifre
Daha önce `HashAndSalt` fonksiyonu ile hash'lenmiş olan parola string formatında verilir.
Daha önce `HashAndSalt` fonksiyonu ile hash'lenmiş olan parola string formatında verilir.
Parametre (plainPwd) – Ham
şifre
Kullanıcının giriş sırasında girdiği gerçek (ham) parola byte dizisi olarak alınır.
Kullanıcının giriş sırasında girdiği gerçek (ham) parola byte dizisi olarak alınır.
Amaç – Doğrulama
Hash'lenmiş parola ile kullanıcının girdiği ham parola eşleşiyor mu kontrol edilir. Eşleşiyorsa true, değilse false döner.
Hash'lenmiş parola ile kullanıcının girdiği ham parola eşleşiyor mu kontrol edilir. Eşleşiyorsa true, değilse false döner.
func ComparePasswords(hashedPwd string, plainPwd []byte) bool {
byteHash := []byte(hashedPwd)
err := bcrypt.CompareHashAndPassword(byteHash, plainPwd)
if err != nil {
log.Println(err)
return false
}
return true
}
DetermineOkeyTile Fonksiyonu
Parametre (indicator)
– Gösterge taşı
Oyun başladığında rastgele belirlenen taş. Gerçek okey taşını bulmak için kullanılır.
Oyun başladığında rastgele belirlenen taş. Gerçek okey taşını bulmak için kullanılır.
Kullanımı – Amaç
- Gösterge taşının numarasını 1 artırarak gerçek okey taşını belirler.
- Renk olarak gösterge taşıyla aynı kalır.
- Numara 13’ten büyükse 1’e sarar (dönel yapı).
- `IsOkey = true`, `IsJoker = false` olacak şekilde okey nesnesi döndürür.
// OkeyTaşınıBelirle, gösterge taşına göre gerçek okey taşını döner
func DetermineOkeyTile(indicator Model.Tile) Model.Tile {
nextNumber := indicator.Number + 1 // Gösterge numarasının bir fazlası alınır
if nextNumber > 13 { // Okey taş numarası 13'ü aşarsa 1'e sarar
nextNumber = 1
}
return Model.Tile{ // Gerçek okey taşı nesnesi döndürülür
Number: nextNumber, // Hesaplanan numara
Color: indicator.Color, // Gösterge taşıyla aynı renk
IsOkey: true, // Bu taş gerçek okeydir
IsJoker: false, // Joker değildir
}
}
MarkOkeyTiles Fonksiyonu
Parametre (indicator)
– Gösterge taşı
Oyun başlangıcında seçilen taş olup, gerçek okey taşının hesaplanmasında temel alınır.
Oyun başlangıcında seçilen taş olup, gerçek okey taşının hesaplanmasında temel alınır.
Kullanımı – Amaç
- Gösterge taşına göre gerçek okey taşını hesaplar.
- Gösterge taşını sahte okey (joker) olarak işaretler.
- Renksiz ve numarasız joker taşlara, gerçek okey taşının bilgilerini atar.
- Diğer tüm taşları joker/okey olmayan taş olarak sıfırlar.
func (tiles *TileBag) MarkOkeyTiles(indicator Model.Tile) {
okey := DetermineOkeyTile(indicator) // Gösterge taşına göre gerçek okey belirlenir
for i := range *tiles { // Tüm taş torbası gezilir
tile := &(*tiles)[i] // İlgili taşın referansı alınır
if tile.Number == indicator.Number && tile.Color == indicator.Color {
// Bu taş gösterge taşıysa sahte okey olur
tile.IsJoker = true // Sahte okey olarak işaretlenir
tile.IsOkey = false // Gerçek okey olmadığı belirtilir
} else if tile.Number == okey.Number && tile.Color == okey.Color && !tile.IsJoker {
// Bu taş gerçek okey taşına eşitse ve joker değilse
tile.IsOkey = true // Gerçek okey olarak işaretlenir
} else if tile.Number == 0 && tile.Color == ColorEnum.None && tile.IsJoker {
// Ön tanımlı renksiz-numarasız joker taşlar
tile.Number = okey.Number // Gerçek okeyin numarası atanır
tile.Color = okey.Color // Gerçek okeyin rengi atanır
} else {
// Diğer tüm taşlar için sıfırlama yapılır
tile.IsOkey = false
tile.IsJoker = false
}
}
}
CreateFullTileSet Fonksiyonu
Parametre
– Yok
Bu fonksiyon herhangi bir dış parametre almaz. Tüm taş yapısını kendi içinde oluşturur.
Bu fonksiyon herhangi bir dış parametre almaz. Tüm taş yapısını kendi içinde oluşturur.
Kullanımı – Amaç
- Okey oyunu için gerekli olan 106 taşlık tam seti oluşturur.
- Her bir taş, dört renkten biriyle (Kırmızı, Sarı, Mavi, Siyah) ve 1–13 arası numarayla üretilir.
- Her taşın oyunda tanımlanabilir olması için benzersiz bir ID atanır.
- Her taş türünden 2 adet üretildiği için toplamda 104 taş oluşur.
- Ek olarak, oyun kurallarına uygun olarak 2 adet sahte okey taşı (renksiz, numbersız, joker) eklenir.
- Oluşturulan taşlar, karıştırma algoritması (`ShuffleTilesSecure`) ile güvenli biçimde rastgele dizilir.
- Bu fonksiyon genellikle oyun başlangıcında bir kez çağrılır ve başlangıç torbasını (TileBag) oluşturur.
func CreateFullTileSet() TileBag {
var tiles []Model.Tile // Taşları tutacak ana liste
id := 0 // Her taşa atanacak benzersiz ID
colors := []int{
ColorEnum.Red,
ColorEnum.Yellow,
ColorEnum.Blue,
ColorEnum.Black,
}
for _, color := range colors { // Tüm renkler için
for number := 1; number <= 13; number++ { // 1–13 arası sayılar
for i := 0; i < 2; i++ { // Her renkten 2 taş
tiles = append(tiles, Model.Tile{
ID: id,
Number: number,
Color: color,
IsJoker: false,
IsOkey: false,
IsOpend: false,
})
id++
}
}
}
// 2 adet sahte okey taşı (renksiz, numbersız)
for i := 0; i < 2; i++ {
tiles = append(tiles, Model.Tile{
ID: id,
Number: 0,
Color: ColorEnum.None,
IsJoker: true,
IsOkey: false,
})
id++
}
return ShuffleTilesSecure(tiles) // Taşları karıştırarak döndür
}
ShuffleTilesSecure Fonksiyonu
Parametre (tiles)
– Karıştırılacak taş dizisi
Oyun başında oluşturulmuş olan tam taş setidir. Rastgele ve güvenli biçimde karıştırılması için bu fonksiyona verilir.
Oyun başında oluşturulmuş olan tam taş setidir. Rastgele ve güvenli biçimde karıştırılması için bu fonksiyona verilir.
Kullanımı – Amaç
- Fisher–Yates algoritmasını kullanarak taşları karıştırır.
- Standart `math/rand` yerine kriptografik olarak güvenli `crypto/rand` fonksiyonu ile çalışır.
- Güvenli oyun deneyimi ve öngörülemezlik sağlamak için rastgelelik önemlidir.
- Her taşın yeri diğerlerinden bağımsız olarak güvenli biçimde değiştirilir.
- Hata durumunda orijinal sıralı taş dizisi geri döner.
// Fisher-Yates Shuffle :)
// ShuffleTilesSecure, taşları kriptografik olarak güvenli şekilde karıştırır
func ShuffleTilesSecure(tiles []Model.Tile) TileBag {
shuffled := make([]Model.Tile, len(tiles)) // Yeni boş bir dizi oluştur
copy(shuffled, tiles) // Orijinal taşları kopyala
for i := len(shuffled) - 1; i > 0; i-- { // Diziyi sondan başa gez
j, err := cryptoRandInt(i + 1) // 0–i arasında güvenli bir sayı üret
if err != nil {
// Hata durumunda karıştırılmadan orijinal dizi döner
return tiles
}
shuffled[i], shuffled[j] = shuffled[j], shuffled[i] // i ve j indekslerini yer değiştir
}
return shuffled // Karıştırılmış diziyi döndür
}
cryptoRandInt Fonksiyonu
Parametre (max)
– Üst sınır
Üretilecek rastgele sayının dahil olmayacağı en büyük değerdir. 0 ile max-1 arasında sayı üretir.
Üretilecek rastgele sayının dahil olmayacağı en büyük değerdir. 0 ile max-1 arasında sayı üretir.
Kullanımı – Amaç
- Bu fonksiyon, güvenli bir şekilde 0 ile
max-1arasında bir tamsayı üretmek için kullanılır. math/randyerinecrypto/randkullanılarak tahmin edilemez sonuçlar elde edilir.- Genellikle oyun taşlarını güvenli karıştırma işlemleri gibi hassas alanlarda kullanılır.
- Hatalı durumlarda varsayılan olarak
0veerrordöner.
// cryptoRandInt returns a random int between 0 and max-1 using crypto/rand
func cryptoRandInt(max int) (int, error) {
nBig, err := rand.Int(rand.Reader, big.NewInt(int64(max))) // Büyük sayı üretimi
if err != nil {
return 0, err // Hata varsa varsayılan 0 döndürülür
}
return int(nBig.Int64()), nil // Güvenli sayı int'e çevrilerek döndürülür
}
GetTiles Fonksiyonu
Parametre (count)
– Çekilecek taş adedi
Taş torbasından kaç adet taş çekileceğini belirtir. Eğer torbada yeterli taş yoksa elde kalan taş kadar döner.
Taş torbasından kaç adet taş çekileceğini belirtir. Eğer torbada yeterli taş yoksa elde kalan taş kadar döner.
Kullanımı – Amaç
- TileBag içerisinden istenilen sayıda taşı çekmek için kullanılır.
- Seçilen taşlar `selected` listesine eklenir ve TileBag'den çıkarılır.
- Bu fonksiyonla oyunculara oyun başında veya oyun esnasında taş dağıtımı yapılabilir.
- Güvenlik amacıyla, eğer istenenden az taş varsa sadece kalanları verir ve hata vermez.
- Çekilen taşlar yeni bir TileBag olarak döndürülür.
func (tiles *TileBag) GetTiles(count int) *TileBag {
if len(*tiles) < count {
count = len(*tiles) // Taş sayısı yetersizse, kalan kadarını al
}
selected := (*tiles)[:count] // Seçilen taşlar
*tiles = (*tiles)[count:] // Geriye kalan taşları TileBag'e geri yaz
return &selected // Seçilen taşları geri döndür
}
ShowPlayerTiles Fonksiyonu
Parametre (tiles)
– TileBag (Taş torbası)
Tüm taşları içeren TileBag referansı. Bu torbadan oyuncuya taş dağıtımı yapılır.
Tüm taşları içeren TileBag referansı. Bu torbadan oyuncuya taş dağıtımı yapılır.
Parametre (name)
– Oyuncu adı
Ekrana yazdırılacak olan oyuncunun adıdır. Konsol çıktısı için kullanılır.
Ekrana yazdırılacak olan oyuncunun adıdır. Konsol çıktısı için kullanılır.
Parametre (topCount)
– Çekilecek taş sayısı
Oyuncuya kaç taş verileceğini belirtir. Bu sayı kadar taş torbadan çekilir ve gösterilir.
Oyuncuya kaç taş verileceğini belirtir. Bu sayı kadar taş torbadan çekilir ve gösterilir.
Kullanımı – Amaç
- Bir oyuncuya dağıtılan taşları almak ve konsola görsel olarak yazdırmak için kullanılır.
- Taşların ID, renk, numara, joker ve okey olup olmadığı bilgileri yazdırılır.
- Dağıtılan taşlar, TileBag'den çıkartılır ve oyuncuya atanır.
- Fonksiyon sonunda, oyuncuya ait taşlar geri döndürülür.
func ShowPlayerTiles(tiles *TileBag, name string, topCount int) *TileBag {
player := tiles.GetTiles(topCount) // Belirtilen sayıda taşı al
fmt.Println(name) // Oyuncu adı yazdırılır
fmt.Println(strings.Repeat("-", 30)) // Görsel ayraç
for i, tile := range *player {
colorName := GetEnumName(ColorEnum, tile.Color) // Renk ismini al
fmt.Printf("%d-) ID: %d, %s %d, Joker: %v Okey: %v\n",
i+1, tile.ID, colorName, tile.Number, tile.IsJoker, tile.IsOkey)
}
fmt.Println() // Satır atla
fmt.Printf("Kalan taş sayısı: %d\n", len(*tiles)) // TileBag'deki taş sayısını yazdır
return player // Oyuncuya verilen taşlar döndürülür
}
GetRandomIndicatorFromTiles Fonksiyonu
Parametre (tiles)
– TileBag referansı
Oyun başında rastgele gösterge taşı seçimi yapılacak taş torbası. Fonksiyon bu taş torbası üzerinden rastgele geçerli bir taş (joker olmayan) seçecektir.
Oyun başında rastgele gösterge taşı seçimi yapılacak taş torbası. Fonksiyon bu taş torbası üzerinden rastgele geçerli bir taş (joker olmayan) seçecektir.
Kullanımı – Amaç
- Okey oyununda başlangıç gösterge taşını güvenli şekilde belirlemek için kullanılır.
- Joker olmayan taşlar arasından kriptografik olarak güvenli rastgele seçim yapar.
- Seçilen taş, gösterge taşı olarak işaretlenir ve TileBag’den çıkarılır.
- Kodun sonunda seçilen taş `indicator` olarak döndürülür.
func (tiles *TileBag) GetRandomIndicatorFromTiles() Model.Tile {
validTiles := make([]Model.Tile, 0) // Joker olmayan taşlar için boş bir liste oluştur
for _, tile := range *tiles {
if !tile.IsJoker {
validTiles = append(validTiles, tile) // Joker olmayanları ekle
}
}
if len(validTiles) == 0 {
log.Fatal("TileBag contains no valid (non-Joker) tiles for indicator selection")
}
max := big.NewInt(int64(len(validTiles))) // Liste boyutunu BigInt olarak al
n, err := rand.Int(rand.Reader, max) // Rastgele index üret (crypto güvenli)
if err != nil {
log.Fatalf("crypto/rand failed: %v", err) // Hata varsa programı durdur
}
randomIndex := int(n.Int64()) // Rastgele index'e karşılık gelen taş alınır
indicator := validTiles[randomIndex]
DropTileFromTiles((*[]Model.Tile)(tiles), indicator) // Seçilen taş torbadan çıkarılır
return indicator // Gösterge taşı döndürülür
}
TakeOneFromBag Fonksiyonu
Parametre (tiles)
– Taş torbası (TileBag)
Taş çekiminin yapılacağı mevcut taş torbasıdır. İçinden bir taş alınır ve kalanlar güncellenir.
Taş çekiminin yapılacağı mevcut taş torbasıdır. İçinden bir taş alınır ve kalanlar güncellenir.
Parametre (player)
– Oyuncunun taş listesi
Çekilen taş, bu diziye (oyuncunun taşları) eklenir.
Çekilen taş, bu diziye (oyuncunun taşları) eklenir.
Kullanımı – Amaç
- TileBag’den bir adet taş çeker.
- Çekilen taşı oyuncunun eline ekler.
- TileBag’in ilk elemanını çıkararak torbayı günceller.
- Boş torba durumunda programı durdurur (log.Fatal).
- Genellikle oyun sırasında bir oyuncunun ortadan taş çekmesi gibi işlemlerde kullanılır.
func (tiles *TileBag) TakeOneFromBag(player *[]Model.Tile) Model.Tile {
if len(*tiles) == 0 {
log.Fatal("TileBag contains no valid (non-Joker) tiles for indicator selection") // Boşsa hata ver
}
var tile = (*tiles)[0] // İlk taşı seç
*tiles = (*tiles)[1:] // TileBag'den çıkar
*player = append(*player, tile) // Oyuncunun taş listesine ekle
return tile // Seçilen taşı döndür
}
TakeOneFromTable Fonksiyonu
Parametre (player)
– Oyuncunun taş listesi
Oyuncuya ait mevcut taş dizisini temsil eder. Yeni taş bu diziye eklenecektir.
Oyuncuya ait mevcut taş dizisini temsil eder. Yeni taş bu diziye eklenecektir.
Parametre (tile)
– Alınacak taş
Ortadan alınan ya da başka bir kaynaktan gelen taş. Bu taş oyuncunun eline eklenecektir.
Ortadan alınan ya da başka bir kaynaktan gelen taş. Bu taş oyuncunun eline eklenecektir.
Kullanımı – Amaç
- Bir oyuncuya dış kaynaktan (örneğin masa ortası) taş verme işlemini yapar.
- Gönderilen taşı oyuncunun taş listesine ekler.
- Yardımcı bir fonksiyondur ve basit veri ekleme işlemi içerir.
func TakeOneFromTable(player *[]Model.Tile, tile Model.Tile) {
*player = append(*player, tile) // Taşı oyuncuya ekle
}
DropTileFromTiles Fonksiyonu
Parametre (playerTiles)
– Oyuncunun taş listesi
Oyuncunun elinde bulunan taşların dizisidir. İçinden bir taş çıkarılacaktır.
Oyuncunun elinde bulunan taşların dizisidir. İçinden bir taş çıkarılacaktır.
Parametre (dropTile)
– Atılacak taş
Oyuncunun elinden çıkarmak istediği taşı temsil eder. Bu taşın `ID` değeri eşleşmelidir.
Oyuncunun elinden çıkarmak istediği taşı temsil eder. Bu taşın `ID` değeri eşleşmelidir.
Kullanımı – Amaç
- Bir oyuncunun elinden belirli bir taşı (`dropTile`) çıkarmak için kullanılır.
- Taş `ID` değeriyle eşleştiğinde listeden silinir.
- Taş başarılı şekilde silinirse
true, bulunamazsafalsedöner. - Listeyi manuel olarak güncellemek yerine bu fonksiyon güvenli ve kontrol edilebilir silme sunar.
func DropTileFromTiles(playerTiles *[]Model.Tile, dropTile Model.Tile) bool {
var isFound bool = false // Taşın bulunup bulunmadığını tutar
for i, tile := range *playerTiles { // Oyuncunun elindeki taşları döngüyle tara
if tile.ID == dropTile.ID { // ID eşleşiyorsa
*playerTiles = append( // Bu index'teki taşı çıkar
(*playerTiles)[:i],
(*playerTiles)[i+1:]...,
)
isFound = true // Bulundu ve silindi
break
}
}
return isFound // Sonuç olarak true veya false döndür
}
FloatPtr Fonksiyonu
Parametre (f)
– float64 türünde bir sayı
Bellekte işaretçisini almak istediğimiz ondalıklı sayıdır.
Bellekte işaretçisini almak istediğimiz ondalıklı sayıdır.
Kullanımı – Amaç
- Bir `float64` sayının işaretçisini döndürür.
- Struct gibi yapılarda opsiyonel alanlar pointer olarak tutulmak istenirse bu fonksiyon kullanılır.
- Kodda sabit ya da literal float değerlerin kolayca pointer'a çevrilmesini sağlar (örn: `FloatPtr(3.14)`).
- Yardımcı (utility) fonksiyondur ve genellikle veri modellerinde null/boş olasılıklı alanlar için kullanılır.
func FloatPtr(f float64) *float64 {
return &f // f'nin adresini döndür (pointer)
}
IntPtr Fonksiyonu
Parametre (i)
– int türünde bir değer
Pointer’a çevrilmek istenen tamsayı değeridir.
Pointer’a çevrilmek istenen tamsayı değeridir.
Kullanımı – Amaç
- Bir `int` sayının bellek adresini (işaretçisini) döndürür.
- Struct yapılarında opsiyonel `int` alanlarını tanımlamak için kullanılır.
- Fonksiyonlara doğrudan integer pointer göndermek gerektiğinde pratiklik sağlar.
- Örnek:
IntPtr(5)→*inttüründe dönüş sağlar.
func IntPtr(i int) *int {
return &i // i'nin adresini döndür
}
BoolPtr Fonksiyonu
Parametre (b)
– bool türünde bir değer
Pointer’a çevrilmek istenen boolean (true/false) değeri.
Pointer’a çevrilmek istenen boolean (true/false) değeri.
Kullanımı – Amaç
- Bir `bool` (mantıksal) değerin adresini döndürür.
- Genellikle opsiyonel ayarlar, tercihler veya JSON/DB veri modellerinde null olabilen boolean alanlar için kullanılır.
- True veya false değerleri işaretçi olarak başka yapılara aktarılabilir.
- Örnek:
BoolPtr(true)→*booltipinde sonuç verir.
func BoolPtr(b bool) *bool {
return &b // b değerinin adresini döndür
}
ResetGame Fonksiyonu
Global Değişken:
`GameGroupState` türünden global bir değişkendir. Oyun grubu ile ilgili genel durumu temsil eder.
Game`GameGroupState` türünden global bir değişkendir. Oyun grubu ile ilgili genel durumu temsil eder.
Fonksiyon:
ResetGame()- Global
Gamedeğişkenini sıfırlamak için kullanılır. GroupIDCounteralanını 0 yaparak, yeni bir oyun oturumu için başlangıç durumu sağlar.- Yeni bir oyun başlatıldığında, önceki oyunla ilgili veriler temizlenmiş olur.
- Uygulama içinde global oyun durumu takibi için ideal bir başlangıç fonksiyonudur.
var Game GameGroupState
func ResetGame() {
Game = GameGroupState{
GroupIDCounter: 0, // Sayacı sıfırla
}
}
Game & GameGroupState Yapısı
Global Değişken:
`Game`, uygulama içinde merkezi olarak tanımlanan bir global değişkendir. Tipi
Game`Game`, uygulama içinde merkezi olarak tanımlanan bir global değişkendir. Tipi
GameGroupState olup oyun grubu durumunu takip eder.
Yapı:
Oyun grupları ile ilgili yönetimi sağlayan bir veri yapısıdır. Aşağıdaki alanı içerir:
GameGroupStateOyun grupları ile ilgili yönetimi sağlayan bir veri yapısıdır. Aşağıdaki alanı içerir:
- GroupIDCounter (int) – Oyun gruplarına benzersiz ID atamak için kullanılan sayaçtır. Her yeni grup oluşturulduğunda artırılır.
Kullanımı – Amaç
- Sunucudaki tüm oyun gruplarının kontrolü merkezi olarak `Game` değişkeniyle yapılır.
GroupIDCounter, benzersiz grup kimlikleri üretmek için kullanılır.ResetGame()veyaGenerateGroupID()gibi fonksiyonlarla birlikte çalışır.- Çok oyunculu sistemlerde oturum ve grup yönetimini kolaylaştırır.
// Global oyun durumu
var Game GameGroupState
// Oyun grup bilgilerini tutar
type GameGroupState struct {
GroupIDCounter int // Grup ID üretimi için sayaç
}
GenerateGroupID Fonksiyonu
Parametre (g *GameGroupState)
`GameGroupState` yapısına ait bir referanstır. Bu fonksiyon struct üzerinden çağrılır.
`GameGroupState` yapısına ait bir referanstır. Bu fonksiyon struct üzerinden çağrılır.
Kullanımı – Amaç
- Her yeni oyun grubu için benzersiz bir grup ID'si üretir.
GroupIDCountersayacını bir artırır ve yeni değeri döner.- Çok oyunculu sistemlerde her oyuncu grubunu ayırt etmek için kullanılır.
- Global
Gamenesnesi üzerinden çağrılır:Game.GenerateGroupID()
func (g *GameGroupState) GenerateGroupID() int {
g.GroupIDCounter++ // Sayaç 1 artırılır
return g.GroupIDCounter // Yeni grup ID değeri döndürülür
}
IsValidGroupOrRun Fonksiyonu
Parametre (tiles) – Taş
dizisi
Kontrol edilecek taş dizisi. Her taş Model.Tile türündedir.
Kontrol edilecek taş dizisi. Her taş Model.Tile türündedir.
Kullanımı – Amaç
- Okey oyununda 3 veya daha fazla taştan oluşan bir dizinin geçerli olup olmadığını kontrol eder.
- Geçerli dizi koşulları: Grup (aynı sayı, farklı renk) veya Sıralı Seri (aynı renk, ardışık sayılar).
- Okey (joker) taşları varsa, bu taşlar eksik taşların yerine sayılır.
func IsValidGroupOrRun(tiles []*Model.Tile) bool {
if len(tiles) < 3 {
return false
}
okeyCount := countOkeys(tiles) // Joker (okey) taşlarını sayar
nonOkeyTiles := filterNonOkeys(tiles) // Gerçek taşları ayıklar
// Grup veya sıralı dizi kontrolü yapılır
return isGroup(nonOkeyTiles, okeyCount) || isSequence(nonOkeyTiles, okeyCount)
}
isGroup Fonksiyonu
Parametre (tiles) – Gerçek
taşlar
Joker olmayan taşların dizisidir. Aynı sayı ve farklı renk şartı burada kontrol edilir.
Joker olmayan taşların dizisidir. Aynı sayı ve farklı renk şartı burada kontrol edilir.
Parametre (okeyCount) – Joker
sayısı
Eksik taşları tamamlamak için kullanılabilecek joker (okey) taşı sayısı.
Eksik taşları tamamlamak için kullanılabilecek joker (okey) taşı sayısı.
Kullanımı – Amaç
- Aynı sayıya sahip ama farklı renklere ait taşlardan oluşan geçerli bir “grup” dizisinin doğruluğunu kontrol eder.
- Joker taşları, eksik olan renkleri tamamlamak için gruba sayılabilir.
- Geçerli olması için grup toplamı en az 3 taş olmalıdır.
// Örnek: Kırmızı 5, Mavi 5, Sarı 5
func isGroup(tiles []*Model.Tile, okeyCount int) bool {
if len(tiles) == 0 {
return false
}
number := tiles[0].Number // Tüm taşların bu sayıya sahip olması gerekir
colors := make(map[int]bool) // Kullanılan renkleri takip etmek için map
for _, tile := range tiles {
if tile.Number != number || colors[tile.Color] {
return false // Farklı sayı veya tekrar eden renk varsa geçersiz
}
colors[tile.Color] = true
}
return len(tiles) + okeyCount >= 3 // Toplam (taş + joker) en az 3 olmalı
}
isSequence Fonksiyonu
Parametre (tiles) – Gerçek
taşlar
Joker olmayan taşların dizisidir. Sıralı ve aynı renk kontrolü burada yapılır.
Joker olmayan taşların dizisidir. Sıralı ve aynı renk kontrolü burada yapılır.
Parametre (okeyCount) – Joker
sayısı
Sıralamada eksik taşları tamamlamak için kullanılabilecek okey (joker) sayısı.
Sıralamada eksik taşları tamamlamak için kullanılabilecek okey (joker) sayısı.
Kullanımı – Amaç
- Taşların sıralı ve aynı renkten olup olmadığını kontrol eder (örnek: Siyah 3-4-5).
- Taşlar sıralı olmasa bile, fonksiyon sıralayıp kontrol yapar.
- Eksik taşlar varsa, belirtilen okey (joker) sayısı kadar tamamlamaya izin verir.
- Toplam taş sayısı (joker dahil) 3’ten az ise geçersiz kabul edilir.
// Örnek: Siyah 3, Siyah 4, Siyah 5
func isSequence(tiles []*Model.Tile, okeyCount int) bool {
if len(tiles) == 0 {
return false
}
// Aynı renkte değillerse seri olamaz
if !allSameColor(tiles) {
return false
}
// Sayı sıralamasına göre sırala
sort.Slice(tiles, func(i, j int) bool {
return tiles[i].Number < tiles[j].Number
})
// Eksik taşlar için gereken joker sayısını hesapla
neededOkeys := calculateNeededOkeysForRun(tiles, okeyCount)
// Joker yetmiyorsa veya toplam sayı yetersizse geçersiz
return neededOkeys <= okeyCount && len(tiles) + okeyCount >= 3
}
calculateNeededOkeysForRun Fonksiyonu
Parametre (tiles)
– Sıralı taşlar
Joker olmayan ve sıralanmış taşların listesi. Fonksiyon aradaki boşlukları tespit etmek için kullanır.
Joker olmayan ve sıralanmış taşların listesi. Fonksiyon aradaki boşlukları tespit etmek için kullanır.
Parametre (maxOkeys)
– Maksimum izin verilen joker sayısı
Gerek duyulacak joker (okey) sayısının bu değeri aşması durumunda geçersiz kombinasyon kabul edilir.
Gerek duyulacak joker (okey) sayısının bu değeri aşması durumunda geçersiz kombinasyon kabul edilir.
Kullanımı – Amaç
- Sıralı taşlar arasında eksik olan (boşluklu) sayıları tespit eder.
- Her bir boşluk için 1 veya daha fazla joker gerekiyorsa bu sayı `neededOkeys` olarak hesaplanır.
- Fark 1 ise sorun yok; fark 2 ise 1 joker, fark 3 ise 2 joker gerekir.
- Fark 3’ten büyükse yapı geçersiz kabul edilir ve `maxOkeys + 1` döndürülür.
func calculateNeededOkeysForRun(tiles []*Model.Tile, maxOkeys int) int {
neededOkeys := 0
for i := 1; i < len(tiles); i++ {
diff := tiles[i].Number - tiles[i-1].Number
switch diff {
case 1:
continue // Arada boşluk yoksa
case 2:
neededOkeys++ // 1 boşluk → 1 joker gerekir
case 3:
neededOkeys += 2 // 2 boşluk → 2 joker gerekir
default:
return maxOkeys + 1 // Çok büyük boşluk varsa geçersiz
}
}
return neededOkeys
}
countOkeys Fonksiyonu
Parametre (tiles)
– Taş dizisi
Oyun sırasında kontrol edilen taşların bulunduğu slice’dır. Her bir taşın okey olup olmadığı incelenir.
Oyun sırasında kontrol edilen taşların bulunduğu slice’dır. Her bir taşın okey olup olmadığı incelenir.
Kullanımı – Amaç
- Verilen taşlar içinde kaç adet
IsOkey = trueolan taş olduğunu sayar. - Seri ve grup kontrollerinde, eksik taşların yerine joker kullanımı için gereklidir.
- Fonksiyon, toplam joker (gerçek okey) sayısını geri döner.
func countOkeys(tiles []*Model.Tile) int {
count := 0
for _, tile := range tiles {
if tile.IsOkey {
count++
}
}
return count
}
filterNonOkeys Fonksiyonu
Parametre (tiles)
– Taş dizisi
Bu parametre, oyuncunun elindeki tüm taşları (joker dahil) içeren slice'tır.
Bu parametre, oyuncunun elindeki tüm taşları (joker dahil) içeren slice'tır.
Kullanımı – Amaç
- Elinizdeki taşlar arasından
IsOkey = trueolanları hariç tutarak, yalnızca normal taşları döner. - Seri (run) ve grup kontrollerinde sadece gerçek taşlarla kontrol yapılmasını sağlar.
- Fonksiyonun çıktısı, joker (okey) olmayan taşlardan oluşan bir slice’tır.
func filterNonOkeys(tiles []*Model.Tile) []*Model.Tile {
result := make([]*Model.Tile, 0, len(tiles))
for _, tile := range tiles {
if !tile.IsOkey {
result = append(result, tile)
}
}
return result
}
allSameColor Fonksiyonu
Parametre (tiles)
– Taş dizisi
Bu parametre, kontrol edilecek olan taş grubunu temsil eder. Her taşın rengi incelenir.
Bu parametre, kontrol edilecek olan taş grubunu temsil eder. Her taşın rengi incelenir.
Kullanımı – Amaç
- Tüm taşların aynı renge sahip olup olmadığını kontrol eder.
- Seri (run) setlerinin doğrulanmasında kullanılır, çünkü seri aynı renkte olmalıdır.
- Hiç taş yoksa (boş slice)
truedöner, çünkü renk çelişkisi oluşmaz. - İlk taşın rengi referans alınır ve diğer tüm taşlarla karşılaştırılır.
func allSameColor(tiles []*Model.Tile) bool {
if len(tiles) == 0 {
return true
}
color := tiles[0].Color
for _, tile := range tiles {
if tile.Color != color {
return false
}
}
return true
}
CalculateTileScore Fonksiyonu
Parametreler
tile: Değeri hesaplanacak taşindex: Bu taşın bulunduğu pozisyontiles: Grubu oluşturan taş dizisiisSequence: Taşlar bir sequence (seri) mi yoksa group (grup) mu belirtir
Amaç ve Kullanımı
- Bu fonksiyon, joker/okey taşlarının hangi değeri temsil ettiğini hesaplar.
- Grup ise: Tüm taşların sayıları aynı olmalı. İlk gerçek taşın
numberdeğeri alınır. - Sıralı set ise: Eksik sıra aralığı bulunarak okey’in değeri tahmin edilir.
- Hiç okey yoksa, normal taşın kendi değeri döndürülür.
- 1 ile 13 aralığı sınır olarak kabul edilir. Sona eklenemeyen taş başa koyulabilir.
func CalculateTileScore(tile *Model.Tile, index int, tiles []*Model.Tile, isSequence bool) int {
if !tile.IsOkey {
return tile.Number
}
if !isSequence {
for _, t := range tiles {
if !t.IsOkey {
return t.Number
}
}
return tile.Number
}
nonOkeys := filterNonOkeys(tiles)
if len(nonOkeys) == 0 {
return 1
}
sort.Slice(nonOkeys, func(i, j int) bool {
return nonOkeys[i].Number < nonOkeys[j].Number
})
numbers := []int{}
for _, t := range nonOkeys {
numbers = append(numbers, t.Number)
}
for i := 0; i < len(numbers)-1; i++ {
if numbers[i+1]-numbers[i] > 1 {
return numbers[i] + 1
}
}
if numbers[len(numbers)-1] < 13 {
if index == 0 {
return numbers[0] - 1
} else {
return numbers[len(numbers)-1] + 1
}
}
if numbers[0] > 1 {
return numbers[0] - 1
}
return 1
}
CanOpenTiles Fonksiyonu
Parametreler
opened: Açılmak istenen taş gruplarını içeren 2D dizi ([][]*Model.Tile)
Amaç ve Kullanımı
- Okey 101 oyununda bir oyuncunun taşları açabilmesi için, toplam puanının 101 veya üzeri olması gerekir.
- Bu fonksiyon, açılmak istenen taşların her birini kontrol eder.
- Açık taş (IsOpend) içeren gruplar geçersiz sayılır.
- Her grup geçerli group ya da sequence olmalıdır. Aksi halde işlem iptal edilir.
- Geçerli grupların her biri
CalculateTileScoreile puanlanır ve toplam puan hesaplanır. - Eğer toplam puan 101 veya üzeri ise, taşlar
SetOpentilesile açılmış olarak işaretlenir. - Fonksiyon sonucunda işlem geçerli ise
true, aksi durumdafalsedöner.
func CanOpenTiles(opened [][]*Model.Tile) bool {
totalScore := 0
for _, group := range opened {
// İçlerinde zaten açılmış taş varsa hata döner
if HasOpenTail(group...) {
return false
}
// Grup geçerli mi kontrol edilir
if !IsValidGroupOrRun(group) {
return false
}
isSeq := isSequence(filterNonOkeys(group), countOkeys(group))
for index, tile := range group {
totalScore += CalculateTileScore(tile, index, group, isSeq)
}
}
var result = totalScore >= 101
// Eğer toplam skor uygunsa, taşları açık olarak işaretle
if result {
SetOpentiles(opened)
}
return result
}
CanOpenTilesWithRemaining Fonksiyonu
Parametreler
tiles: Oyuncunun elindeki tüm taşlar ([]*Model.Tile)opened: Açılmak istenen taş grupları ([][]*Model.Tile)
Amaç ve Kullanımı
- Oyuncunun açmak istediği taş gruplarının geçerli olup olmadığını kontrol eder.
- Her grup için:
- İçinde önceden açılmış taş varsa
falsedöner. - Geçerli bir grup (group/run) değilse işlem iptal edilir.
- İçinde önceden açılmış taş varsa
- Her taş için
CalculateTileScorefonksiyonu ile skor hesaplanır. - Toplam skor 0’dan büyükse, elde kalan taşlar
getRemainingInOpenedTilesile bulunur. SetOpentilesçağrısı bilinçli olarak iptal edilmiştir. (Bayram’ın isteğiyle)
Dönüş Değerleri
remaining: Açılmayan, elde kalan taşlarscore: Açılan taşlardan elde edilen toplam skorerror: Taşlar başarılı şekilde açılabildiysetrue, aksi haldefalse
func CanOpenTilesWithRemaining(tiles []*Model.Tile, opened [][]*Model.Tile) (remaining []*Model.Tile, score int, error bool) {
totalScore := 0
var remainList []*Model.Tile
for _, group := range opened {
if HasOpenTail(group...) {
return remainList, 0, false
}
if !IsValidGroupOrRun(group) {
return remainList, 0, false
}
isSeq := isSequence(filterNonOkeys(group), countOkeys(group))
for index, tile := range group {
totalScore += CalculateTileScore(tile, index, group, isSeq)
}
}
var result = totalScore > 0
if result {
remainList = getRemainingInOpenedTiles(tiles, opened)
}
return remainList, totalScore, result
}
CanOpenTilesWithRemainingWithAllGroups Fonksiyonu
Parametreler
groups: Oyuncunun elindeki taşlar, gruplanmış olarak ([][]*Model.Tile)
Amaç ve Kullanımı
- Elimizdeki tüm grupları değerlendirerek hangilerinin açılabilir (geçerli) olduğunu belirler.
- Her grup için:
- İçinde daha önce açılmış taş varsa işlem iptal edilir.
- Geçerli değilse
remainListlistesine alınır. - Geçerliyse,
CalculateTileScoreile skor hesaplanır veopenedListlistesine eklenir.
totalScore> 0 ise başarılı kabul edilir.- Not: Önceden
SetOpentilesçağrılırken, Bayram’ın isteğiyle bu işlem kaldırılmıştır.
Dönüş Değerleri
opened: Geçerli olarak açılan taş gruplarıremaining: Geçersiz kalan taş grupları (elde kalanlar)score: Açılan taşlardan elde edilen toplam puanerror: Başarı durumu – geçerli set varsatrue, yoksafalse
func CanOpenTilesWithRemainingWithAllGroups(groups [][]*Model.Tile)
(opened [][]*Model.Tile, remaining [][]*Model.Tile, score int, error bool) {
totalScore := 0
var remainList [][]*Model.Tile
var openedList [][]*Model.Tile
for _, group := range groups {
if HasOpenTail(group...) {
return openedList, remainList, 0, false
}
if !IsValidGroupOrRun(group) {
remainList = append(remainList, group)
} else {
openedList = append(openedList, group)
isSeq := isSequence(filterNonOkeys(group), countOkeys(group))
for index, tile := range group {
totalScore += CalculateTileScore(tile, index, group, isSeq)
}
}
}
var result = totalScore > 0
return openedList, remainList, totalScore, result
}
getRemainingInOpenedTiles Fonksiyonu
Parametreler
tiles: Oyuncunun elindeki tüm taşlaropened: Açılmış taş grupları ([][]*Model.Tile)
Amaç ve Kullanımı
- Bu fonksiyon, oyuncunun elindeki taşlardan hangilerinin henüz açılmadığını bulmak için kullanılır.
- Önce
openedlistesindeki taşları renk ve numaraya göreusedmap’inde tutar. - Sonra,
tileslistesindeki her taşı kontrol ederek:- Eğer o taş daha önce açılmışsa, kullanılmış listeden düşer.
- Eğer hiç kullanılmamışsa,
remainList'e eklenir.
- Sonuçta geriye kalan (kullanılmamış) taşlar döndürülür.
Dönüş Değeri
remaining: Açılmamış, elde kalan taşlar listesi
func getRemainingInOpenedTiles(tiles []*Model.Tile, opened [][]*Model.Tile) (remaining []*Model.Tile) {
type pairKey struct {
Color int
Number int
}
used := make(map[pairKey][]*Model.Tile)
var remainList []*Model.Tile
for _, group := range opened {
for _, tile := range group {
key := pairKey{Color: tile.Color, Number: tile.Number}
used[key] = append(used[key], tile)
}
}
for _, tile := range tiles {
key := pairKey{Color: tile.Color, Number: tile.Number}
if usedList, ok := used[key]; ok && len(usedList) > 0 {
used[key] = usedList[1:]
} else {
remainList = append(remainList, tile)
}
}
return remainList
}
SetOpentiles Fonksiyonu
Parametreler
opened [][]*Model.Tile: Açılmış tüm grup veya sıra taşlarının 2D dizisi.
Amaç ve Kullanımı
- Bu fonksiyon, geçerli bir hamlede (örneğin ilk açma sırasında) 101 puanı geçen tüm taşları açık hale getirir.
- Her bir grup (set) için ayrı
GroupIDtanımlanır. - Her taşın
IsOpendözelliğitrueyapılır veGroupIDreferansı atanır.
Ne Zaman Çağrılır?
CanOpenTilesfonksiyonunda, eğer oyuncunun toplam puanı 101 ve üzeri ise çağrılır.- Oyuncunun masaya açtığı tüm setlerin oyun alanına yerleştirildiğini göstermek için kullanılır.
func SetOpentiles(opened [][]*Model.Tile) {
for _, group := range opened {
//101'i geçen elde açılan tüm array gruplara ayrı ayrı unique groupID tanımlanır.
var groupID = Game.GenerateGroupID()
for _, tile := range group {
tile.IsOpend = true
tile.GroupID = &groupID
}
}
}
SetOpenPairtiles Fonksiyonu
Parametreler
setTiles []*Model.Tile: Açılacak çift taşları içeren dilim.grpID ...int: (Opsiyonel) Eğer verildiyse, taşlara atanacak olan mevcut birGroupID.
Amaç ve Kullanımı
- Çift olarak açılmış taşları (
pair) masa üzerine açık set olarak işaretler. - Eğer bir
GroupIDparametre olarak verilirse, o ID kullanılır. - Eğer parametre verilmezse, yeni bir
GroupIDotomatik olarak üretilir. - Tüm taşların
IsOpendalanıtrueyapılır. GroupIDreferansı taşlara atanır.
Ne Zaman Çağrılır?
- Oyuncunun çift taşları (pair) masa üzerine açması durumunda çağrılır.
- Özellikle
CanAddPairToPairSetsveyaCanAddTilesToSetgibi fonksiyonlarda kullanılır. - Yeni açılan çiftlerin açık olarak kabul edilmesini sağlar.
func SetOpenPairtiles(setTiles []*Model.Tile, grpID ...int) {
var groupID int
if len(grpID) > 0 {
groupID = grpID[0]
} else {
groupID = Game.GenerateGroupID()
}
for _, tile := range setTiles {
tile.IsOpend = true
tile.GroupID = &groupID
}
}
HasOpenTail Fonksiyonu
Parametreler
tiles ...*Model.Tile: Kontrol edilecek taşların listesi (variadic parametre olarak gönderilir).
Amaç ve Kullanımı
- Bu fonksiyon, verilen taşlar arasında daha önce açılmış (oyuna dahil edilmiş) bir taş olup olmadığını kontrol eder.
- Eğer taşlardan herhangi birinin
IsOpendalanıtrueisetruedöner. - Hiçbir taş daha önce açılmamışsa, sonuç
falseolur.
Ne Zaman Kullanılır?
- Oyuncunun açılmış taşları tekrar kullanmasını engellemek için.
- Örneğin:
CanOpenTiles,CanAddTilesToSet,IsValidPairgibi fonksiyonlarda kontrol mekanizması olarak çağrılır.
func HasOpenTail(tiles ...*Model.Tile) bool {
for _, tile := range tiles {
if tile.IsOpend {
return true
}
}
return false
}
HasAtLeastFivePairs Fonksiyonu
Parametreler
opened [][]*Model.Tile: Oyuncunun açmak istediği çiftlerden oluşan liste.
Amaç ve Kullanımı
- Oyuncunun açmak istediği çiftleri değerlendirerek, geçerli olup olmadıklarını kontrol eder.
- Toplamda en az 5 geçerli çift varsa
truedöner, aksi haldefalse. - Geçerli çift, sayıların eşleştiği ve en az birinin rengi aynı veya okey olması durumudur.
- İçinde sahte okeyten (joker) oluşan bir çift varsa veya taş zaten açılmışsa fonksiyon
falsedöner.
Ek Davranış
- Geçerli çift sayısı 5 veya daha fazlaysa, bu çiftler
SetOpentilesfonksiyonu ile açılmış olarak işaretlenir.
func HasAtLeastFivePairs(opened [][]*Model.Tile) bool {
pairCount := 0
for _, group := range opened {
if len(group) == 2 {
tile1, tile2 := group[0], group[1]
if HasOpenTail(tile1, tile2) {
return false
}
if tile1.IsJoker && tile2.IsJoker {
return false
}
score1 := CalculateTileScore(tile1, 0, group, false)
score2 := CalculateTileScore(tile2, 1, group, false)
if score1 == score2 {
if tile1.IsOkey || tile2.IsOkey || tile1.Color == tile2.Color {
pairCount++
} else {
return false
}
} else {
return false
}
}
}
var result = pairCount >= 5
if result {
SetOpentiles(opened)
}
return result
}
HasAtLeastFivePairsForSetNewPair Fonksiyonu
Parametreler
opened [][]*Model.Tile: Oyuncunun açmak üzere hazırladığı çift (pair) setleri
Amaç ve Kullanımı
- Oyuncunun elindeki çift sayısının 5 veya daha fazla olup olmadığını kontrol eder.
- Geçerli bir çift, aynı sayıya sahip taşlar olup, aynı renkte olmaları veya en az birinin okey olması gerekir.
- Eğer her iki taş da
joker(sahte okey) ise çift geçersiz sayılır. - Bu fonksiyon taşlar açılmaz, yalnızca kontrol yapılır. (Yani
SetOpentilesçağrısı yoktur.)
Notlar
HasAtLeastFivePairsfonksiyonuna benzer, fakat burada taşlar açılmaz (işaretlenmez).- Yeni eşleşme eklenmeden önce kural kontrolü için kullanılır.
func HasAtLeastFivePairsForSetNewPair(opened [][]*Model.Tile) bool {
pairCount := 0
for _, group := range opened {
if len(group) == 2 {
tile1, tile2 := group[0], group[1]
if tile1.IsJoker && tile2.IsJoker {
return false
}
score1 := CalculateTileScore(tile1, 0, group, false)
score2 := CalculateTileScore(tile2, 1, group, false)
if score1 == score2 {
if tile1.IsOkey || tile2.IsOkey || tile1.Color == tile2.Color {
pairCount++
} else {
return false
}
} else {
return false
}
}
}
var result = pairCount >= 5
return result
}
CanAddTilesToSet Fonksiyonu
Parametreler
set []*Model.Tile: Var olan açık taş grubutiles ...*Model.Tile: Bu gruba eklenmek istenen 1 veya 2 yeni taş
Amaç ve Kullanımı
- Var olan açık bir taş grubuna, yeni taşların eklenip eklenemeyeceğini kontrol eder.
- Eklenmek istenen taşlar en fazla 2 adet olmalıdır ve zaten açık olmamalıdır.
- Yeni taşlarla oluşturulacak birleşik grup geçerli bir Group (aynı sayı, farklı renk) veya Sequence (aynı renk, artan sıra) olmalıdır.
- Eğer geçerli ise, grup ID ile birlikte tüm taşlar açık olarak işaretlenir.
Notlar
SetOpenPairtilesçağrısı ile orijinal grubunGroupIDdeğeri yeni taşlara da atanır.- Oyun kurallarına göre grup büyütme işlemleri buradan kontrol edilir.
func CanAddTilesToSet(set []*Model.Tile, tiles ...*Model.Tile) bool {
if len(tiles) == 0 || len(set) == 0 || len(tiles) > 2 || len(set) < 3 {
return false
}
if HasOpenTail(tiles...) {
return false
}
newSet := append([]*Model.Tile{}, set...)
newSet = append(newSet, tiles...)
var result = IsValidGroupOrRun(newSet)
if result {
SetOpenPairtiles(newSet, *set[0].GroupID)
}
return result
}
TryAddTilesToSet Fonksiyonu
Parametreler
set *[]*Model.Tile: Ek yapılacak mevcut açık taş grubu (referans ile)tiles ...*Model.Tile: Bu gruba eklenmek istenen 1 veya 2 yeni taş
Amaç ve Kullanımı
- Bu fonksiyon, taş grubuna yeni taş eklenme denemesini gerçekleştirir.
- Yeni taşlarla birlikte grup geçerli (valid group/run) olursa:
- Gerçek gruba ekleme yapılır.
- Yeni taşlar
SetOpenPairtilesile açılmış olarak işaretlenir. - Taşlar etkili numaraya göre sıralanır.
- Eğer grup geçerli değilse değişiklik yapılmaz.
Kritik Kontroller
HasOpenTail: Eklenecek taşların daha önce açılıp açılmadığını kontrol eder.IsValidGroupOrRun: Güncel grup kurallara uygun mu?sortGroupByEffectiveNumber: Jokerler ve okeylerin mantıksal sıralamasını düzenler.
func TryAddTilesToSet(set *[]*Model.Tile, tiles ...*Model.Tile) bool {
if len(tiles) == 0 || len(*set) == 0 || len(tiles) > 2 || len(*set) < 3 {
return false
}
if HasOpenTail(tiles...) {
return false
}
newSet := append([]*Model.Tile{}, *set...)
newSet = append(newSet, tiles...)
if IsValidGroupOrRun(newSet) {
*set = append(*set, tiles...)
SetOpenPairtiles(*set, *(*set)[0].GroupID)
*set = sortGroupByEffectiveNumber(*set)
return true
}
return false
}
IsValidPair Fonksiyonu
Parametreler
tiles []*Model.Tile: Kontrol edilmek istenen potansiyel çift taşlar
Amaç ve Kullanımı
- Gönderilen iki taşın geçerli bir çift (pair) olup olmadığını belirler.
- Oyun kuralları çerçevesinde “çift açmak” isteyen oyuncular için kullanılır.
- Taşlar doğru koşulları sağlıyorsa
truedöner.
Geçerlilik Kuralları
- Mutlaka 2 taş olmalıdır.
- Taşlar önceden açılmış olmamalıdır (
HasOpenTailkontrolü). - İkisi de sahte okey (joker) olamaz.
- Her taş için
CalculateTileScoreile hesaplanan değer eşit olmalıdır. - Değerler eşitse, taşlar aynı renk olmalı ya da en az biri okey olmalıdır.
func IsValidPair(tiles []*Model.Tile) bool {
if len(tiles) != 2 {
return false
}
if HasOpenTail(tiles...) {
return false
}
tile1, tile2 := tiles[0], tiles[1]
if tile1.IsJoker && tile2.IsJoker {
return false
}
score1 := CalculateTileScore(tile1, 0, tiles, false)
score2 := CalculateTileScore(tile2, 1, tiles, false)
if score1 != score2 {
return false
}
return tile1.IsOkey || tile2.IsOkey || tile1.Color == tile2.Color
}
CanAddPairToPairSets Fonksiyonu
Parametreler
remaining []*Model.Tile: Eklenmek istenen 2'li taş çiftipairSets [][]*Model.Tile: Oyuncunun önceden açmış olduğu çift setleri
Amaç ve Kullanımı
- Yeni bir taş çiftinin mevcut çift setlerine eklenip eklenemeyeceğini kontrol eder.
- Eklenen çift, oyun kurallarına uygun olmalı ve tüm çiftlerin sayısı en az 5 olmalıdır.
- Kurallar sağlanıyorsa taşlara
IsOpend = trueatanır veGroupIDbelirlenir.
Kontrol ve Koşullar
IsValidPairfonksiyonu ile çift geçerliliği kontrol edilir.HasAtLeastFivePairsForSetNewPairile tüm çiftlerin sayısı en az 5 mi bakılır.- Bu kurallar sağlanıyorsa
SetOpenPairtilesile taşlar işaretlenir.
func CanAddPairToPairSets(remaining []*Model.Tile, pairSets [][]*Model.Tile) bool {
if IsValidPair(remaining) {
var result = HasAtLeastFivePairsForSetNewPair(pairSets)
if result {
SetOpenPairtiles(remaining)
}
return result
}
return false
}
CanThrowingTileBeAddedToOpponentSets Fonksiyonu
Parametreler
newPair *Model.Tile: Atılmak istenen taşopponentSets [][]*Model.Tile: Rakibin mevcut açık setleri
Amaç ve Kullanımı
- Oyuncunun attığı bir taşın, rakibin açık setlerine uygun olup olmadığını kontrol eder.
- Taş, daha önce açılmışsa tekrar kullanılamaz.
- Her bir rakip seti için
CanAddTilesToSetfonksiyonu çağrılarak uygunluk kontrol edilir.
Koşullar ve Sonuç
- Taş
IsOpenddurumundaysa false döner (yani tekrar oynanamaz). - Rakip setlerinden en az birine eklenebiliyorsa true döner.
- Hiçbir sete eklenemiyorsa false döner.
func CanThrowingTileBeAddedToOpponentSets(newPair *Model.Tile, opponentSets [][]*Model.Tile) bool {
if newPair.IsOpend {
//Acilan tas bir daha atilamaz.
return false
}
for _, set := range opponentSets {
if CanAddTilesToSet(set, newPair) {
return true
}
}
return false
}
SplitTilesByValidGroupsOrRuns Fonksiyonu
Parametreler
tiles []*Model.Tile: Oyuncunun elindeki tüm taşlar.maxGroupSizeOptional ...int: (Opsiyonel) Maksimum grup büyüklüğü. Belirtilmezse 5 alınır.
Fonksiyonun Amacı
- Geçerli group veya sequence oluşturabilecek taş kombinasyonlarını bulur.
- Oluşabilecek en iyi (en fazla taş ve en yüksek skor içeren) grupları seçer.
- Kalan taşları ve toplam skoru da döner.
Kullanımı – Amaç
- Oyuncunun elindeki taşları geçerli grup (aynı sayı farklı renk) veya sıralı set (aynı renk artan sayı) kombinasyonlarına ayırmak için kullanılır.
- Okey taşlarını da değerlendirerek tüm geçerli olasılıkları dener.
- Backtracking algoritması ile en fazla taş içeren ve en yüksek skoru getiren kombinasyonlar seçilir.
- Kullanılamayan (açılamayan) taşlar ayrıca belirtilir.
Dönüş Değerleri
[][]*Model.Tile: En iyi seçilen geçerli taş grupları[]*Model.Tile: Kullanılamayan taşlar (geriye kalanlar)int: Gruplardan elde edilen toplam puan
func SplitTilesByValidGroupsOrRuns(tiles []*Model.Tile, maxGroupSizeOptional ...int) ([][]*Model.Tile, []*Model.Tile, int) {
n := len(tiles)
maxGroupSize := 5
if len(maxGroupSizeOptional) > 0 && maxGroupSizeOptional[0] > 0 {
maxGroupSize = maxGroupSizeOptional[0]
}
if n < maxGroupSize {
maxGroupSize = n
}
sort.Slice(tiles, func(i, j int) bool {
if tiles[i].Color == tiles[j].Color {
return tiles[i].Number < tiles[j].Number
}
return tiles[i].Color < tiles[j].Color
})
type candidate struct {
Indices []int
Group []*Model.Tile
}
var allGroups []candidate
for size := maxGroupSize; size >= 3; size-- {
indices := make([]int, size)
var generate func(start, depth int)
generate = func(start, depth int) {
if depth == size {
group := make([]*Model.Tile, size)
okeyCount := 0
for i, idx := range indices {
tile := tiles[idx]
group[i] = tile
if tile.IsOkey {
okeyCount++
}
}
if okeyCount > 2 {
return
}
nonOkeys := filterNonOkeys(group)
if isGroup(nonOkeys, okeyCount) || isSequence(nonOkeys, okeyCount) {
tmp := make([]*Model.Tile, len(group))
copy(tmp, group)
tmpIdx := make([]int, len(indices))
copy(tmpIdx, indices)
allGroups = append(allGroups, candidate{Indices: tmpIdx, Group: tmp})
}
return
}
for i := start; i <= n-(size-depth); i++ {
indices[depth] = i
generate(i+1, depth+1)
}
}
generate(0, 0)
}
var (
maxTilesUsed int
maxScore int
bestCombination [][]*Model.Tile
)
var backtrack func(start int, used map[int]bool, current [][]*Model.Tile)
backtrack = func(start int, used map[int]bool, current [][]*Model.Tile) {
usedCount := len(used)
score := 0
for _, group := range current {
score += sumGroupScore(group)
}
if usedCount > maxTilesUsed || (usedCount == maxTilesUsed && score > maxScore) {
maxTilesUsed = usedCount
maxScore = score
bestCombination = deepCopyGroups(current)
}
for i := start; i < len(allGroups); i++ {
canUse := true
for _, idx := range allGroups[i].Indices {
if used[idx] {
canUse = false
break
}
}
if !canUse {
continue
}
for _, idx := range allGroups[i].Indices {
used[idx] = true
}
backtrack(i+1, used, append(current, allGroups[i].Group))
for _, idx := range allGroups[i].Indices {
delete(used, idx)
}
}
}
backtrack(0, make(map[int]bool), [][]*Model.Tile{})
usedIndices := make(map[*Model.Tile]bool)
for _, group := range bestCombination {
for _, tile := range group {
usedIndices[tile] = true
}
}
var remaining []*Model.Tile
for _, tile := range tiles {
if !usedIndices[tile] {
remaining = append(remaining, tile)
}
}
for i, g := range bestCombination {
bestCombination[i] = sortGroupByEffectiveNumber(g)
}
return bestCombination, remaining, maxScore
}
deepCopyGroups Fonksiyonu
Parametreler
groups [][]*Model.Tile: Taş gruplarından oluşan iki boyutlu slice. Her bir grup sıralı veya grup olabilir.
Kullanımı – Amaç
- Taş gruplarının bağımsız bir kopyasını üretir. Yani orijinal veri yapısını değiştirmeden, üzerinde işlem yapılabilecek yeni bir yapı oluşturur.
- Özellikle
backtrackingalgoritmalarında alternatif kombinasyonları denerken kullanılır. - Orijinal taşları etkilemeden alternatif çözümleri kıyaslamaya olanak tanır.
Dönüş Değeri
[][]*Model.Tile: Girdi olarak verilen taş gruplarının birebir kopyalanmış yeni hali.
func deepCopyGroups(groups [][]*Model.Tile) [][]*Model.Tile {
copied := make([][]*Model.Tile, len(groups))
for i := range groups {
copied[i] = make([]*Model.Tile, len(groups[i]))
copy(copied[i], groups[i])
}
return copied
}
sumGroupScore Fonksiyonu
Parametreler
group []*Model.Tile: Puanı hesaplanacak taş grubudur. Bu grup geçerli bir "run" (sıralı) ya da "group" (aynı sayı, farklı renk) olmalıdır.
Kullanımı – Amaç
- Bir taş grubunun toplam skorunu hesaplar.
- Grubun sıralı (sequence) mi yoksa grup (group) mu olduğunu analiz eder.
- Okey veya joker taşların gerçek sayı değerlerini
CalculateTileScorefonksiyonuyla tespit eder. - Toplam skoru geri döndürmek için her taşın değerini toplar.
- Bu fonksiyon özellikle
SplitTilesByValidGroupsOrRunsgibi fonksiyonların içinde en yüksek skorlu kombinasyonları belirlemek için kullanılır.
Dönüş Değeri
int: Verilen grubun toplam puanını döndürür. Her taşın hesaplanmış puanlarının toplamıdır.
func sumGroupScore(group []*Model.Tile) int {
isSeq := isSequence(filterNonOkeys(group), countOkeys(group))
total := 0
for i, tile := range group {
total += CalculateTileScore(tile, i, group, isSeq)
}
return total
}
sumAllGroupsNumbers Fonksiyonu
Parametreler
groups [][]*Model.Tile: Skoru toplanacak tüm geçerli taş gruplarının listesi. Her iç liste, tek bir grup ya da sıralı seti temsil eder.
Kullanımı – Amaç
- Tüm taş gruplarındaki taşların değerlerinin toplamını döner.
- Her grup için sırayla
CalculateTileScorefonksiyonu çağrılarak, taşların efektif değerleri hesaplanır (özellikle okey taşları için). - Grubun sıralı mı (run) yoksa grup mu (group) olduğunu otomatik belirler ve buna göre hesap yapar.
- Özellikle oyun açılışlarında veya toplu değerlendirme gereken anlarda kullanılır.
Dönüş Değeri
int: Tüm gruplardaki taşların efektif skorlarının toplamı döndürülür.
func sumAllGroupsNumbers(groups [][]*Model.Tile) int {
total := 0
for _, group := range groups {
isSeq := isSequence(filterNonOkeys(group), countOkeys(group))
for index, tile := range group {
total += CalculateTileScore(tile, index, group, isSeq)
}
}
return total
}
getEffectiveNumber Fonksiyonu
Parametreler
tile *Model.Tile: Değeri çözümlemek istenen taş (joker ya da okey olabilir).group []*Model.Tile: Bu taşın bulunduğu grup ya da set. Taşın hangi değeri temsil ettiğini anlamak için grup analizi yapılır.
Kullanımı – Amaç
- Joker ya da okey taşının hangi sayıyı temsil ettiğini belirlemek için kullanılır.
- Eğer taş normal bir taşsa (okey değilse), kendi sayısı döndürülür.
- Grup ise (aynı sayı, farklı renk): grubun ortak sayısı döndürülür.
- Sıralı set ise (aynı renk, artan sayı): eksik olan sayı tespit edilir ve döndürülür.
- Seri tamamlanmışsa ve sıranın sonunda taş varsa (örneğin 11-12-13 yerine 10-11-13 varsa): eksik olan 12 döndürülür.
Dönüş Değeri
int: Taşın temsil ettiği efektif sayı değeri (özellikle joker/okey taşları için çözülmüş hali).
func getEffectiveNumber(tile *Model.Tile, group []*Model.Tile) int {
if tile.IsOkey {
nonOkeys := filterNonOkeys(group)
if isGroup(nonOkeys, countOkeys(group)) {
for _, t := range nonOkeys {
return t.Number
}
} else if isSequence(nonOKeys, countOkeys(group)) {
nums := []int{}
for _, t := range nonOkeys {
nums = append(nums, t.Number)
}
sort.Ints(nums)
expected := nums[0]
for _, n := range nums {
if n != expected {
return expected
}
expected++
}
if expected > 13 {
return nums[0] - 1
}
return expected
}
}
return tile.Number
}
sortGroupByEffectiveNumber Fonksiyonu
Parametreler
group []*Model.Tile: Etkili sayılarına göre sıralanacak taşlardan oluşan grup.
Kullanımı – Amaç
- Bu fonksiyon, verilen taş grubundaki tüm taşları, temsil ettikleri gerçek (etkili) sayıya göre sıralar.
- Joker veya okey taşları için
getEffectiveNumberfonksiyonu kullanılarak hangi değeri temsil ettikleri belirlenir. - Gerçek taşlar ise doğrudan kendi sayıları ile karşılaştırılır.
- Sıralama işlemi kararlı (stable sort) olarak yapılır, yani eşit değerli taşlar orijinal sırasını korur.
Dönüş Değeri
[]*Model.Tile: Etkili değerlere göre sıralanmış taş listesi.
func sortGroupByEffectiveNumber(group []*Model.Tile) []*Model.Tile {
type tileWithValue struct {
tile *Model.Tile
value int
}
var withValues []tileWithValue
for _, t := range group {
withValues = append(withValues, tileWithValue{
tile: t,
value: getEffectiveNumber(t, group),
})
}
sort.SliceStable(withValues, func(i, j int) bool {
return withValues[i].value < withValues[j].value
})
var sorted []*Model.Tile
for _, tw := range withValues {
sorted = append(sorted, tw.tile)
}
return sorted
}
SplitTilesByValidPairs Fonksiyonu
Parametreler
tiles []*Model.Tile: Değerlendirilecek tüm taşlar.
Kullanımı – Amaç
- Verilen taş listesinden, kurallara uygun olacak şekilde çift (pair) oluşturmaya çalışır.
- Aynı sayı ve aynı renkten en az 2 taş varsa bunları eşleştirir.
- Tek kalan taşlar varsa, okey taşlarıyla eşleştirmeye çalışır.
- Kullanılmış taşlar işaretlenir, tekrar çift oluşturulmaz.
Dönüş Değeri
([][]*Model.Tile, []*Model.Tile): İlk değer çiftlere ayrılmış taş grupları listesidir, ikinci değer ise eşleşemeyen (artakalan) taşlardır.
func SplitTilesByValidPairs(tiles []*Model.Tile) ([][]*Model.Tile, []*Model.Tile) {
type pairKey struct {
Color int
Number int
}
grouped := make(map[pairKey][]*Model.Tile)
var okeys []*Model.Tile
for _, tile := range tiles {
if tile.IsOkey {
okeys = append(okeys, tile)
} else {
key := pairKey{Color: tile.Color, Number: tile.Number}
grouped[key] = append(grouped[key], tile)
}
}
var pairs [][]*Model.Tile
used := make(map[*Model.Tile]bool)
for _, group := range grouped {
available := []*Model.Tile{}
for _, t := range group {
if !used[t] {
available = append(available, t)
}
}
for len(available) >= 2 {
pair := available[:2]
pairs = append(pairs, pair)
used[pair[0]] = true
used[pair[1]] = true
available = available[2:]
}
}
for _, group := range grouped {
if len(okeys) == 0 {
break
}
available := []*Model.Tile{}
for _, t := range group {
if !used[t] {
available = append(available, t)
}
}
for len(available) >= 1 && len(okeys) > 0 {
t := available[0]
okey := okeys[0]
pairs = append(pairs, []*Model.Tile{t, okey})
used[t] = true
used[okey] = true
available = available[1:]
okeys = okeys[1:]
}
}
var remaining []*Model.Tile
for _, t := range tiles {
if !used[t] {
remaining = append(remaining, t)
}
}
return pairs, remaining
}
1. Tüm Okey Taşlarını Oluşturma
tiles := Core.CreateFullTileSet()Bu satır, tüm oyun taşlarını üretir: 4 renk x 13 sayı x 2 = 104 taş + 2 sahte okey = 106 taş. Her taşın
ID, Color, Number gibi özellikleri tanımlıdır. Dönüş olarak
karıştırılmış bir taş dizisi (tile bag) elde edilir.
2. Player 1’e 22 Taş Dağıtılır
player1 = Core.ShowPlayerTiles(&tiles, "Player 1:", 22)Player 1'e havuzdan 22 taş çekilir. Fonksiyon, oyuncunun elini terminale yazdırır ve kalan taşları havuzdan eksiltir.
3. Player 2’ye 21 Taş Dağıtılır
player2 = Core.ShowPlayerTiles(&tiles, "Player 2:", 21)Player 2'ye 21 taş verilir. Aynı şekilde taşlar yazdırılır, havuz güncellenir.
5. Kalan Taş Havuzu Görüntülenir
for i, tile := range tiles {...}Gösterge sonrası, elde kalan tüm taşlar (taş havuzu) yazdırılır. Her taşın
ID, Color,
Number, IsJoker, IsOkey bilgisi gösterilir.
6. Okey Taşları Belirlenip Etiketlenir
tiles.MarkOkeyTiles(indicatorTile)player1.MarkOkeyTiles(indicatorTile)player2.MarkOkeyTiles(indicatorTile)Göstergeye göre okey olan taşlar belirlenir. `IsOkey = true` olarak güncellenir. Hem havuzda hem oyuncularda işlem yapılır.
7. Okey Etiketlemesinden Sonra Oyuncu Elleri Yazdırılır
for i, tile := range *player1 {...}for i, tile := range *player2 {...}Oyuncuların elleri tekrar yazdırılır. Bu sefer hangi taşların okey olduğu da belirtilir.
8. Player 1 Taş Çeker (Turn Başlangıcı)
takenTile = tiles.TakeOneFromBag((*[]Model.Tile)(player1))Player 1, taş havuzundan bir taş çeker. Bu işlem, oyuncunun taş sayısını 23’e çıkarır. Terminale bu taşın bilgileri yazdırılır.
ResetGame – Oyun Grubu Sayacını Sıfırlama
Kullanımı
Core.ResetGame()
Amaç
Bu fonksiyon, oyun içerisindeki
Bu fonksiyon, oyun içerisindeki
Game isimli global GameGroupState nesnesini
sıfırlar.
Özellikle açılan grup ID sayaçlarının yeniden başlatılması gereken durumlarda (yeni oyun başlangıcı gibi)
çağrılır.
Ne Yapar?
- Global
Gamenesnesine yeni birGameGroupStateatanır. - İçerisindeki
GroupIDCountersıfırlanır. - Yani, taşlara verilecek yeni grup ID'leri sıfırdan başlatılır.
Tipik Kullanım Zamanı
Yeni bir oyun başladığında veya tüm oyun durumu sıfırlanmak istendiğinde kullanılır.
Yeni bir oyun başladığında veya tüm oyun durumu sıfırlanmak istendiğinde kullanılır.
var Game GameGroupState
type GameGroupState struct {
GroupIDCounter int
}
func ResetGame() {
Game = GameGroupState{
GroupIDCounter: 0,
}
}
// Örnek çağrı:
Core.ResetGame()
4. Gösterge Taşının Belirlenmesi
indicatorTile := tiles.GetRandomIndicatorFromTiles()Oyun kurallarına göre bir gösterge taşı rastgele seçilir. Bu taşın bir üst değeri Okey taşı olur. Gösterge taş bilgisi terminalde gösterilir.
CreateFullTileSet Fonksiyonu
main.go İçinde Kullanımı
tiles := Core.CreateFullTileSet()
Amaç
Bu fonksiyon, oyunun başında gerekli olan tüm okey taşlarını (106 adet) üretmek için çağrılır.
Bu fonksiyon, oyunun başında gerekli olan tüm okey taşlarını (106 adet) üretmek için çağrılır.
Kapsam
- Her renkten (Kırmızı, Sarı, Mavi, Siyah) 1’den 13’e kadar olan taşlardan ikişer adet üretir.
- Toplamda 4 renk x 13 sayı x 2 = 104 taş oluşturulur.
- Ayrıca 2 adet sahte okey (renksiz, sayı 0,
- Böylece toplam taş sayısı 106 olur.
- Her renkten (Kırmızı, Sarı, Mavi, Siyah) 1’den 13’e kadar olan taşlardan ikişer adet üretir.
- Toplamda 4 renk x 13 sayı x 2 = 104 taş oluşturulur.
- Ayrıca 2 adet sahte okey (renksiz, sayı 0,
IsJoker = true) eklenir.- Böylece toplam taş sayısı 106 olur.
main.go'da Ne Zaman ve Neden Çağrılır?
Oyun başlatıldığında, tüm taşların sıfırdan ve karışık bir şekilde oluşturulması gerekir. Bu yüzden
Oyun başlatıldığında, tüm taşların sıfırdan ve karışık bir şekilde oluşturulması gerekir. Bu yüzden
CreateFullTileSet fonksiyonu main fonksiyonu içinde ilk adımda çağrılır.
Fonksiyonun İçsel İşleyişi
1. Taşları ID vererek oluşturur.
2. Renk ve sayı değerlerini atar.
3. Sahte okey taşlarını ayrı olarak tanımlar.
4. En sonunda tüm taşları kriptografik olarak güvenli şekilde karıştırmak için
1. Taşları ID vererek oluşturur.
2. Renk ve sayı değerlerini atar.
3. Sahte okey taşlarını ayrı olarak tanımlar.
4. En sonunda tüm taşları kriptografik olarak güvenli şekilde karıştırmak için
ShuffleTilesSecure() fonksiyonuna gönderir.
DropTileFromTiles – Player 1
main.go İçinde Kullanımı
var result = Core.DropTileFromTiles((*[]Model.Tile)(player1), dropTile)if result { fmt.Printf("...") }
Amaç
Bu satır, Player 1’in elinden belirli bir taşı çıkarmak (oyun alanına atmak) için kullanılır. Oyunda her tur sonunda bir taş atılır; bu davranışı simüle eder.
Bu satır, Player 1’in elinden belirli bir taşı çıkarmak (oyun alanına atmak) için kullanılır. Oyunda her tur sonunda bir taş atılır; bu davranışı simüle eder.
Detaylı Açıklama
-
-
-
dropTile, atılmak istenen taşı temsil eder (örneğin elin 3. taşı).-
DropTileFromTiles() fonksiyonu:
- Player 1’in elindeki taşları döngüyle kontrol eder.
- Taşın
IDeşleşmesi varsa onu listeden çıkarır. - Başarıyla çıkardıysa
truedöner, değilsefalse.
Kullanım Nedeni
Okey oyununda her oyuncu sırası geldiğinde bir taş çeker ve bir taş atar. Bu satır, "taş atma" adımını uygulamak için kullanılır. Ayrıca `fmt.Printf(...)` satırı sayesinde, atılan taşın ID’si, rengi, numarası ve joker durumu terminale yazdırılır.
Okey oyununda her oyuncu sırası geldiğinde bir taş çeker ve bir taş atar. Bu satır, "taş atma" adımını uygulamak için kullanılır. Ayrıca `fmt.Printf(...)` satırı sayesinde, atılan taşın ID’si, rengi, numarası ve joker durumu terminale yazdırılır.
TakeOneFromTable Fonksiyonu
Parametre (player)
– Taşı alacak oyuncunun elindeki taş listesi
Bu parametre, taşın ekleneceği oyuncuya ait taş listesidir. Pointer olarak geçirilir, böylece orijinal veri doğrudan güncellenir.
Bu parametre, taşın ekleneceği oyuncuya ait taş listesidir. Pointer olarak geçirilir, böylece orijinal veri doğrudan güncellenir.
Parametre (tile)
– Eline alınacak taş
Masadan veya rakipten alınan belirli taş. Bu taş doğrudan oyuncunun eline eklenir.
Masadan veya rakipten alınan belirli taş. Bu taş doğrudan oyuncunun eline eklenir.
Kullanımı – Amaç
- Oyuncunun masadan ya da başka bir kaynaktan (örneğin başka oyuncudan) bir taşı eline almasını sağlar.
- Ana fonksiyon (örnek:
main.go) içerisinde taş çekme veya alma işlemleri için çağrılır. - Örneğin,
Player 2oyuncusunun,Player 1oyuncusunun attığı bir taşı eline almasını simüle eder: Core.TakeOneFromTable((*[]Model.Tile)(player2), dropTile)- Bu satır,
dropTiletaşınıplayer2’nin eline ekler.
func TakeOneFromTable(player *[]Model.Tile, tile Model.Tile) {
*player = append(*player, tile)
}
// Örnek çağrım:
// Player 2, dropTile adındaki taşı masadan alır
Core.TakeOneFromTable((*[]Model.Tile)(player2), dropTile)
DropTileFromTiles Fonksiyonu
Parametre (playerTiles)
– Oyuncunun elindeki taş listesi
Taşı elinden bırakacak oyuncunun taş dizisi. Pointer olarak gönderilir ki taş elden kalıcı olarak silinebilsin.
Taşı elinden bırakacak oyuncunun taş dizisi. Pointer olarak gönderilir ki taş elden kalıcı olarak silinebilsin.
Parametre (dropTile)
– Atılacak taş
Elinden çıkarılmak istenen belirli taş.
Elinden çıkarılmak istenen belirli taş.
ID eşleşmesi ile oyuncunun elinden silinir.
Kullanımı – Amaç
- Bir oyuncunun elindeki taşlardan birini masaya atmasını sağlar.
- Taş,
IDeşleşmesi ile bulunarak oyuncunun taş listesinden kaldırılır. - Eğer taş başarıyla bulunup çıkarılırsa
truedöner, aksi takdirdefalse. - Örnek kullanım:
Core.DropTileFromTiles((*[]Model.Tile)(player2), (*player2)[4]) - Bu örnekte
player2oyuncusu, elindeki 5. taşı (indeks 4) atmaktadır.
func DropTileFromTiles(playerTiles *[]Model.Tile, dropTile Model.Tile) bool {
var isFound bool = false
for i, tile := range *playerTiles {
if tile.ID == dropTile.ID {
*playerTiles = append((*playerTiles)[:i], (*playerTiles)[i+1:]...)
isFound = true
break
}
}
return isFound
}
// Örnek çağrım:
// Player 2, elindeki 5. taşı atar
Core.DropTileFromTiles((*[]Model.Tile)(player2), (*player2)[4])
ShowPlayerTiles Fonksiyonu
Parametre (tiles)
– TileBag (taş havuzu)
Oyunculara verilecek taşların bulunduğu havuz. Taşlar buradan seçilir ve oyuncuya atanır.
Oyunculara verilecek taşların bulunduğu havuz. Taşlar buradan seçilir ve oyuncuya atanır.
Parametre (name)
– Oyuncu ismi (ekrana yazdırmak için)
Hangi oyuncuya ait taşların gösterildiğini belirtmek için yazı olarak kullanılır.
Hangi oyuncuya ait taşların gösterildiğini belirtmek için yazı olarak kullanılır.
Parametre (topCount)
– Çekilecek taş sayısı
Oyuncuya başlangıçta verilecek taş adedini belirtir. Belirtilen sayı kadar taş seçilir ve gösterilir.
Oyuncuya başlangıçta verilecek taş adedini belirtir. Belirtilen sayı kadar taş seçilir ve gösterilir.
Kullanımı – Amaç
- Taş havuzundan belirtilen sayıda taşı çekip, oyuncuya dağıtır.
- Konsola detaylı bilgi yazdırır: taş ID’si, rengi, numarası, okey ya da joker olup olmadığı.
- Hem görsel çıktı sağlar hem de oyuncuya ait taşları döndürür.
- Örnek kullanım:
Core.ShowPlayerTiles(player1, "Player 1:", 22) - Bu örnekte
player1oyuncusuna 22 taş verilir ve bilgileri konsola yazdırılır.
func ShowPlayerTiles(tiles *TileBag, name string, topCount int) *TileBag {
player := tiles.GetTiles(topCount)
fmt.Println(name)
fmt.Println(strings.Repeat("-", 30))
for i, tile := range *player {
colorName := GetEnumName(ColorEnum, tile.Color)
fmt.Printf("%d-) ID: %d, %s %d, Joker: %v Okey: %v\n",
i+1, tile.ID, colorName, tile.Number, tile.IsJoker, tile.IsOkey)
}
fmt.Println()
fmt.Printf("Kalan taş sayısı: %d\n", len(*tiles))
return player
}
// Örnek çağrım:
// Player 1’e 22 taş verilip, bilgileri yazdırılır.
Core.ShowPlayerTiles(player1, "Player 1:", 22)
ShowPlayerTiles – Player 2
Parametre (tiles)
– Taş havuzu (TileBag)
Oyuna başlarken veya yeni taş çekilirken kullanılan tüm taşların bulunduğu dizidir.
Oyuna başlarken veya yeni taş çekilirken kullanılan tüm taşların bulunduğu dizidir.
Parametre (name)
– Oyuncu adı (örnek: "Player 2:")
Konsola yazdırılan başlık. Oyuncunun taşlarının kimde olduğunu belirtmek için görsel çıktıda kullanılır.
Konsola yazdırılan başlık. Oyuncunun taşlarının kimde olduğunu belirtmek için görsel çıktıda kullanılır.
Parametre (topCount)
– Çekilecek taş sayısı
Taş havuzundan kaç taş çekileceğini belirtir. Bu örnekte 21 taş "Player 2" için alınır.
Taş havuzundan kaç taş çekileceğini belirtir. Bu örnekte 21 taş "Player 2" için alınır.
Kullanımı – Amaç
- Oyuncuya başlangıçta veya oyun sırasında taş vermek için kullanılır.
- Konsol üzerinde görsel bilgi sağlar: her taşın ID’si, rengi, numarası, okey veya joker durumu.
- Fonksiyon, hem taşları yazdırır hem de dağıtılan taşları döndürür.
- Örnek çağrı:
Core.ShowPlayerTiles(player2, "Player 2:", 21) - Bu kullanımda,
player2'ye 21 taş verilir ve oyuncunun taşları listelenir.
func ShowPlayerTiles(tiles *TileBag, name string, topCount int) *TileBag {
player := tiles.GetTiles(topCount)
fmt.Println(name)
fmt.Println(strings.Repeat("-", 30))
for i, tile := range *player {
colorName := GetEnumName(ColorEnum, tile.Color)
fmt.Printf("%d-) ID: %d, %s %d, Joker: %v Okey: %v\n",
i+1, tile.ID, colorName, tile.Number, tile.IsJoker, tile.IsOkey)
}
fmt.Println()
fmt.Printf("Kalan taş sayısı: %d\n", len(*tiles))
return player
}
// Kullanım örneği:
// Player 2 için 21 taş dağıtılır ve konsola yazdırılır.
Core.ShowPlayerTiles(player2, "Player 2:", 21)
ShowPlayerTiles – Tüm Taş Havuzunun Gösterimi
Parametre (tiles)
– TileBag (Taş Havuzu)
Oyunun başında oluşturulan ve tüm taşları (jokerler dahil) içeren listeyi temsil eder.
Oyunun başında oluşturulan ve tüm taşları (jokerler dahil) içeren listeyi temsil eder.
Parametre (name)
– "Bag :"
Konsol çıktısında başlık olarak gösterilir. Bu durumda taş havuzunun görüntülendiği belirtiliyor.
Konsol çıktısında başlık olarak gösterilir. Bu durumda taş havuzunun görüntülendiği belirtiliyor.
Parametre (topCount)
– len(tiles)
Taş havuzundaki tüm taşların gösterileceği anlamına gelir.
Taş havuzundaki tüm taşların gösterileceği anlamına gelir.
len(tiles) kadar taş çekilir ve
yazdırılır.
Kullanımı – Amaç
- Oyun başında taş havuzunun içeriğini kontrol etmek için kullanılır.
- Renk, sayı, okey ve joker durumlarıyla birlikte her taşın detayını gösterir.
- Genellikle
CreateFullTileSet()ile oluşturulan taş setinin doğru olup olmadığını gözlemlemek için kullanılır. - Taşlar çekildiği için havuzdan çıkar; bu yüzden sadece kontrol amaçlı kullanılmalıdır.
- Örnek çağrı:
Core.ShowPlayerTiles(&tiles, "Bag :", len(tiles))
func ShowPlayerTiles(tiles *TileBag, name string, topCount int) *TileBag {
player := tiles.GetTiles(topCount)
fmt.Println(name)
fmt.Println(strings.Repeat("-", 30))
for i, tile := range *player {
colorName := GetEnumName(ColorEnum, tile.Color)
fmt.Printf("%d-) ID: %d, %s %d, Joker: %v Okey: %v\n",
i+1, tile.ID, colorName, tile.Number, tile.IsJoker, tile.IsOkey)
}
fmt.Println()
fmt.Printf("Kalan taş sayısı: %d\n", len(*tiles))
return player
}
// Örnek kullanım:
Core.ShowPlayerTiles(&tiles, "Bag :", len(tiles))