Code edit (9 edits merged)
Please save this source code
User prompt
"var y = H / 2 - 120;" yazıyorum ama zarları aşağı kaydıramıyorum pozisyonunu. H/2'de kalıyor sürekli sanki. Neden?
Code edit (7 edits merged)
Please save this source code
User prompt
Oyunun ortasındaki zarları biraz daha büyültebilir misin? Üzerlerine tıklamakta zorlanıyorum çünkü biraz ufak kalıyorlar.
Code edit (3 edits merged)
Please save this source code
User prompt
Hala "Ana Skor: 0 | undefined | Ana Skor: 0" yazıyor. undefined değil, hedef ne ise onun puanı yazmalı orada ve o puana ulaşan ilk oyuncu oyunu kazanmalı.
User prompt
Şu anda hesabı sıfırla diyip hesabı sıfırladığımda seviye bilgisi sıfırlanmıyor. Hedef puanı göstermesi gereken yerde undefined yazıyor. Başlangıçta (ben seviye 1 iken) hedef 1000 olmalı ve benim her seviye artışım için hedef de 250 artmalı. Yani 2 seviye olunca hedef 1250, 3 seviye olunda 1500, ..., 10 seviye olunca hedef 3500 olmalı ve bu şekilde artmaya devam etmeli. Eğer oyunu kazanırsam seviyem artmalı. Eğer oyunu kaybedersem seviyem sabit kalmalı yani artmamalı. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Şu anda Hedefe (başlangıçta 1000) ulaşılmasına rağmen oyun bitmiyor devam ediyor. Şurada "// değerleri güncelle ve görünür yap var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; var oran = totalGames > 0 ? Math.round(winGames / totalGames * 100) + "%" : "% ?"; var oyunStr = totalGames > 0 ? totalGames : "?"; window.winRateTxt.setText("Zafer Oranı: " + oran + " | Maç Sayısı: " + oyunStr);" zafer oranı ve maç sayısı bilgileri var ve güncelleniyor ama seviye bilgisi yazmıyor ve galiba güncellenmiyor. Ben seviye atladıkça hedefin de +250 artması gerekiyor ve hedefin de güncellenmesi gerekiyor. Bu güncelleme sadece yazı olarak değil aynı zamanda o hedefe ulaşılınca oyunu bitirecek şekilde olmalı. Tüm bu sorunları düzelt.
User prompt
Şu anda zafer oranı, maç sayısı yazısı ana menü ve oyun sonu ekranında da gözüküyor fakat seviye kısmı gözükmüyor ana menü ve oyun sonu ekranı kısmında. Ayrıca şu anda seviye ben oyun kazandıkça güncelleniyor mu yani artıyor mu? Bu artış seviye yazısında da güncelleniyor mu? Ayrıca şu anda Hedefe (başlangıçta 1000) ulaşılmasına rağmen oyun bitmiyor devam ediyor. Tüm bu sorunları düzelt.
Code edit (1 edits merged)
Please save this source code
User prompt
"Şimdi kazanma oranı ve oynanan oyun sayısı yazan yerin yanında bir de başlangıçta "Seviye 1" yazsın. Ben her oyun kazandığımda seviyem 1 artsın. Ayrıca başlangıçta oynanan oyun sayısı yazan yerde de "?" yerine "0" yazsın. Ayrıca başlangıçta kazanma oranı yazan yerde "?" yerine "∅" yazsın. Hedef başlangıçta 1000 olsun ve ben her seviye atladığımda +250 artsın. Yani ben seviye 2 olunca hedef 1250 olacak, ben seviye 3 olunca hedef 1500 olacak şeklinde... Ayrıca skor tablosunun yanında lig görselim olacak. Bu benim mevcut ligimi temsil edecek. İlk 10 oyunumu oynayana kadar orada "derecesizLigi" asseti olacak. İlk 10 oyunumu tamamladıktan sonra: Eğer kazanma oranım %0 - %10 arasındaysa orada "demirLigi" asseti olacak. Eğer kazanma oranım %11 - %20 arasındaysa orada "bronzLigi" asseti olacak. Eğer kazanma oranım %21 - %30 arasındaysa orada "gumusLigi" asseti olacak. Eğer kazanma oranım %31 - %40 arasındaysa orada "altinLigi" asseti olacak. Eğer kazanma oranım %41 - %50 arasındaysa orada "zumrutLigi" asseti olacak. Eğer kazanma oranım %51 - %60 arasındaysa orada "platinLigi" asseti olacak. Eğer kazanma oranım %61 - %70 arasındaysa orada "elmasLigi" asseti olacak. Eğer kazanma oranım %71 - %80 arasındaysa orada "ustaLigi" asseti olacak. Eğer kazanma oranım %81 - %90 arasındaysa orada "ustadLigi" asseti olacak. Eğer kazanma oranım %91 - %100 arasındaysa orada "sampiyonlukLigi" asseti olacak." demiştim ama şu anda oyuna başlayınca Hedef kısmında undefined yazıyor, ayrıca lig assetlerimi (derecesizLigi, demirLigi, bronzLigi, ..., sampiyonlukLigi vb.) de oluşturmamışsın. Ayrıca lig görseli 200x200 olacak ve skor tablosunun sağ tarafında yer alacak. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (2 edits merged)
Please save this source code
User prompt
Şimdi kazanma oranı ve oynanan oyun sayısı yazan yerin yanında bir de başlangıçta "Seviye 1" yazsın. Ben her oyun kazandığımda seviyem 1 artsın. Ayrıca başlangıçta oynanan oyun sayısı yazan yerde de "?" yerine "0" yazsın. Ayrıca başlangıçta kazanma oranı yazan yerde "?" yerine "∅" yazsın. Hedef başlangıçta 1000 olsun ve ben her seviye atladığımda +250 artsın. Yani ben seviye 2 olunca hedef 1250 olacak, ben seviye 3 olunca hedef 1500 olacak şeklinde... Ayrıca skor tablosunun yanında lig görselim olacak. Bu benim mevcut ligimi temsil edecek. İlk 10 oyunumu oynayana kadar orada "derecesizLigi" asseti olacak. İlk 10 oyunumu tamamladıktan sonra: Eğer kazanma oranım %0 - %10 arasındaysa orada "demirLigi" asseti olacak. Eğer kazanma oranım %11 - %20 arasındaysa orada "bronzLigi" asseti olacak. Eğer kazanma oranım %21 - %30 arasındaysa orada "gumusLigi" asseti olacak. Eğer kazanma oranım %31 - %40 arasındaysa orada "altinLigi" asseti olacak. Eğer kazanma oranım %41 - %50 arasındaysa orada "zumrutLigi" asseti olacak. Eğer kazanma oranım %51 - %60 arasındaysa orada "platinLigi" asseti olacak. Eğer kazanma oranım %61 - %70 arasındaysa orada "elmasLigi" asseti olacak. Eğer kazanma oranım %71 - %80 arasındaysa orada "ustaLigi" asseti olacak. Eğer kazanma oranım %81 - %90 arasındaysa orada "ustadLigi" asseti olacak. Eğer kazanma oranım %91 - %100 arasındaysa orada "sampiyonlukLigi" asseti olacak.
Code edit (10 edits merged)
Please save this source code
User prompt
Oyuna şu anda ilk rakip (2. oyuncu) başlıyor. Şu anda oyuna ilk 2. oyuncu başlarken "rakibinSirasiSesi" sesi çalıyor fakat ben oyuna ilk olarak rakip başladığı zaman "ilkRakipBasliyorSesi" sesi çalsın 1 kere istiyorum. Buna göre kodu düzelt.
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Ama şu anda tur sırası 1. oyuncudan 2. oyuncuya geçtiği zaman 2. oyuncu hiçbir şekilde hamle yapmıyor sanki direkt anında pas geçiyor ve sıra tekrar 1. oyuncuya geliyor.
User prompt
Şu anda yapay zekanın mantıklı oynadığını sanmıyorum ve yapay zeka hamlelerini yapmak için düşünmekle çok vakit kaybediyor. Bunu engellemek için yapay zekanın uzunca düşünerek oynamasından ziyade onu belirli bir algoritmayı sürekli takip etmeye zorlamak istiyorum. Bu sayede düşünmekle zaman kaybetmeyecek, ona verdiğim algoritmaya göre DEVAM mı yoksa TAMAM mı demesi gerektiğine karar verecek ve o algoritmaya göre oynayacak hamlelerini sürekli. Aşağıda sana hangi zar durumları için TAMAM mı yoksa DEVAM mı demesi gerektiğini detaylıca açıkladım: 6 zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 1 | 6 144 | 32/243 | %13,17 | 100 | | 5 | 6 144 | 32/243 | %13,17 | 50 | | 1 1 | 3 840 | 20/243 | %8,23 | 200 | | 5 5 | 3 840 | 20/243 | %8,23 | 100 | | 1 5 | 7 680 | 40/243 | %16,46 | 150 | | 1 1 5 | 3 840 | 20/243 | %8,23 | 250 | | 1 5 5 | 3 840 | 20/243 | %8,23 | 200 | | 1 1 5 5 | 1 440 | 5/162 | %3,09 | 300 | 6 zarlı durumlar için yukarıdaki durumlar gelirse NPC bu durumlar içindeki tek bir zarı (öncelikle varsa 1'i, yoksa 5'i) seçip DEVAM butonuna basmalı ve seçilmeyen 5 zarı tekrar atarak (iflas etme ihtimali 5/108) oyuna devam etmeli. 6 zarlı durumlar için yukarıdaki durumlar haricinde diğer 6 zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarları seçip TAMAM butonuna basmalı ve skorunu almalı. 5 zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 1 | 1 280 | 40/243 | %16,46 | 100 | | 5 | 1 280 | 40/243 | %16,46 | 50 | | 1 1 | 640 | 20/243 | %8,23 | 200 | | 5 5 | 640 | 20/243 | %8,23 | 100 | | 1 5 | 1 280 | 40/243 | %16,46 | 150 | | 1 1 5 | 480 | 5/81 | %6,17 | 250 | | 1 5 5 | 480 | 5/81 | %6,17 | 200 | 5 zarlı durumlar için yukarıdaki durumlar gelirse NPC bu durumlar içindeki tek bir zarı (öncelikle varsa 1'i, yoksa 5'i) seçip DEVAM butonuna basmalı ve seçilmeyen 4 zarı tekrar atarak (iflas etme ihtimali 17/108) oyuna devam etmeli. 5 zarlı durumlar için yukarıdaki durumlar haricinde diğer 5 zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarları seçip TAMAM butonuna basmalı ve skorunu almalı. 4 zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 1 | 256 | 16/81 | %19,75 | 100 | | 5 | 256 | 16/81 | %19,75 | 50 | | 1 1 | 96 | 2/27 | %7,41 | 200 | | 5 5 | 96 | 2/27 | %7,41 | 100 | | 1 5 | 192 | 4/27 | %14,81 | 150 | 4 zarlı durumlar için yukarıdaki durumlar gelirse NPC bu durumlar içindeki tek bir zarı (öncelikle varsa 1'i, yoksa 5'i) seçip DEVAM butonuna basmalı ve seçilmeyen 3 zarı tekrar atarak (iflas etme ihtimali 5/18) oyuna devam etmeli. 4 zarlı durumlar için yukarıdaki durumlar haricinde diğer 4 zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarları seçip TAMAM butonuna basmalı ve skorunu almalı. 3 zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 1 | 48 | 2/9 | %22,22 | 100 | | 5 | 48 | 2/9 | %22,22 | 50 | | 5 5 | 12 | 1/18 | %5,56 | 100 | 3 zarlı durumlar için yukarıdaki durumlar gelirse NPC bu durumlar içindeki tek bir zarı (öncelikle varsa 1'i, yoksa 5'i) seçip DEVAM butonuna basmalı ve seçilmeyen 2 zarı tekrar atarak (iflas etme ihtimali 4/9) oyuna devam etmeli. 3 zarlı durumlar için yukarıdaki durumlar haricinde diğer 3 zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarları seçip TAMAM butonuna basmalı ve skorunu almalı. 2 zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 5 | 8 | 2/9 | %22,22 | 50 | 2 zarlı durumlar için yukarıdaki durum gelirse NPC bu durum içindeki 5 zarını seçip DEVAM butonuna basmalı ve seçilmeyen 1 (tek) zarı tekrar atarak (iflas etme ihtimali 2/3) oyuna devam etmeli. 2 zarlı durumlar için yukarıdaki durum haricinde diğer 2 zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarları seçip TAMAM butonuna basmalı ve skorunu almalı. 1 (tek) zarlı durumlar için: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | 5 | 8 | 2/9 | %22,22 | 50 | 1 (tek) zarlı durumlar için yukarıdaki durum gelirse NPC bu durum içindeki 5 zarını seçip DEVAM butonuna basmalı ve 6 zarı birden tekrardan atarak (iflas etme ihtimali 25/864) oyuna devam etmeli. 1 (tek) zarlı durumlar için yukarıdaki durum haricinde diğer 1 (tek) zarlı durumlardan birisi gelmesi halinde (İflas hariç) NPC elindeki en iyi durumu oluşturan zarı seçip TAMAM butonuna basmalı ve skorunu almalı. Zar sayısına göre tüm durumları içeren detaylı listeyi aşağıda gösterdim: 1 (tek) zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | ----- | ------------------ | -------- | ---------- | ----- | | 1 | 1 | 1/6 | %16,67 | 100 | | 5 | 1 | 1/6 | %16,67 | 50 | | İflas | 4 | 2/3 | %66,67 | 0 | 2 zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | ----- | ------------------ | -------- | ---------- | ------ | | 1 | 8 | 2/9 | %22,22 | 100 | | 5 | 8 | 2/9 | %22,22 | 50 | | 1 1 | 1 | 1/36 | %2,78 | 200 | | 5 5 | 1 | 1/36 | %2,78 | 100 | | 1 5 | 2 | 1/18 | %5,56 | 150 | | İflas | 16 | 4/9 | %44,44 | 0 | 3 zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | ----- | ------------------ | -------- | ---------- | ------ | | 1 | 48 | 2/9 | %22,22 | 100 | | 5 | 48 | 2/9 | %22,22 | 50 | | 1 1 | 12 | 1/18 | %5,56 | 200 | | 5 5 | 12 | 1/18 | %5,56 | 100 | | 1 5 | 24 | 1/9 | %11,11 | 150 | | 1 5 1 | 3 | 1/72 | %1,39 | 250 | | 1 5 5 | 3 | 1/72 | %1,39 | 200 | | 1 1 1 | 1 | 1/216 | %0,46 | 1000 | | 2 2 2 | 1 | 1/216 | %0,46 | 200 | | 3 3 3 | 1 | 1/216 | %0,46 | 300 | | 4 4 4 | 1 | 1/216 | %0,46 | 400 | | 5 5 5 | 1 | 1/216 | %0,46 | 500 | | 6 6 6 | 1 | 1/216 | %0,46 | 600 | | İflas | 60 | 5/18 | %27,78 | 0 | 4 zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | ------- | ------------------ | -------- | ---------- | ------ | | 1 | 256 | 16/81 | %19,75 | 100 | | 5 | 256 | 16/81 | %19,75 | 50 | | 1 1 | 96 | 2/27 | %7,41 | 200 | | 5 5 | 96 | 2/27 | %7,41 | 100 | | 1 5 | 192 | 4/27 | %14,81 | 150 | | 1 1 5 | 48 | 1/27 | %3,70 | 250 | | 1 1 1 5 | 4 | 1/324 | %0,31 | 1050 | | 1 5 5 | 48 | 1/27 | %3,70 | 200 | | 1 5 5 5 | 4 | 1/324 | %0,31 | 600 | | 1 1 5 5 | 6 | 1/216 | %0,46 | 300 | | 1 1 1 | 16 | 1/81 | %1,23 | 1000 | | 2 2 2 | 12 | 1/108 | %0,93 | 200 | | 3 3 3 | 12 | 1/108 | %0,93 | 300 | | 4 4 4 | 12 | 1/108 | %0,93 | 400 | | 5 5 5 | 16 | 1/81 | %1,23 | 500 | | 6 6 6 | 12 | 1/108 | %0,93 | 600 | | 1 1 1 1 | 1 | 1/1296 | %0,08 | 2000 | | 2 2 2 2 | 1 | 1/1296 | %0,08 | 400 | | 3 3 3 3 | 1 | 1/1296 | %0,08 | 600 | | 4 4 4 4 | 1 | 1/1296 | %0,08 | 800 | | 5 5 5 5 | 1 | 1/1296 | %0,08 | 1000 | | 6 6 6 6 | 1 | 1/1296 | %0,08 | 1200 | | İflas | 204 | 17/108 | %15,74 | 0 | 5 zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | ------------- | ------------------ | --------- | ---------- | ------- | | 1 | 1 280 | 40/243 | %16,46 | 100 | | 5 | 1 280 | 40/243 | %16,46 | 50 | | 1 1 | 640 | 20/243 | %8,23 | 200 | | 5 5 | 640 | 20/243 | %8,23 | 100 | | 1 5 | 1 280 | 40/243 | %16,46 | 150 | | 1 1 5 | 480 | 5/81 | %6,17 | 250 | | 1 1 1 5 | 80 | 5/486 | %1,03 | 1050 | | 1 1 1 1 5 | 5 | 5/7 776 | %0,06 | 2050 | | 1 5 5 | 480 | 5/81 | %6,17 | 200 | | 1 5 5 5 | 80 | 5/486 | %1,03 | 600 | | 1 5 5 5 5 | 5 | 5/7 776 | %0,06 | 1100 | | 1 1 5 5 | 120 | 5/324 | %1,54 | 300 | | 1 1 1 5 5 | 10 | 5/3 888 | %0,13 | 1100 | | 1 1 5 5 5 | 10 | 5/3 888 | %0,13 | 700 | | 1 1 1 | 160 | 5/243 | %2,06 | 1000 | | 2 2 2 | 90 | 5/432 | %1,16 | 200 | | 3 3 3 | 90 | 5/432 | %1,16 | 300 | | 4 4 4 | 90 | 5/432 | %1,16 | 400 | | 5 5 5 | 160 | 5/243 | %2,06 | 500 | | 6 6 6 | 90 | 5/432 | %1,16 | 600 | | 1 1 1 1 | 20 | 5/1 944 | %1,03 | 2000 | | 2 2 2 2 | 15 | 5/2 592 | %0,58 | 400 | | 3 3 3 3 | 15 | 5/2 592 | %0,58 | 600 | | 4 4 4 4 | 15 | 5/2 592 | %0,58 | 800 | | 5 5 5 5 | 20 | 5/1 944 | %1,03 | 1000 | | 6 6 6 6 | 15 | 5/2 592 | %0,58 | 1200 | | 1 1 1 1 1 | 1 | 1/7 776 | %0,01 | 4000 | | 2 2 2 2 2 | 1 | 1/7 776 | %0,01 | 800 | | 3 3 3 3 3 | 1 | 1/7 776 | %0,01 | 1200 | | 4 4 4 4 4 | 1 | 1/7 776 | %0,01 | 1600 | | 5 5 5 5 5 | 1 | 1/7 776 | %0,01 | 2000 | | 6 6 6 6 6 | 1 | 1/7 776 | %0,01 | 2400 | | 1 2 3 4 5 | 120 | 5/324 | %1,54 | 500 | | 2 3 4 5 6 | 120 | 5/324 | %1,54 | 750 | | İflas | 360 | 5/108 | %4,63 | 0 | 6 zarlı tüm durumların listesi aşağıda: | Durum | Kombinasyon Sayısı | Olasılık | Yaklaşık % | Puan | | --------------- | ------------------ | -------- | ---------- | ----- | | 1 | 6 144 | 32/243 | %13,17 | 100 | | 5 | 6 144 | 32/243 | %13,17 | 50 | | 1 1 | 3 840 | 20/243 | %8,23 | 200 | | 5 5 | 3 840 | 20/243 | %8,23 | 100 | | 1 5 | 7 680 | 40/243 | %16,46 | 150 | | 1 1 5 | 3 840 | 20/243 | %8,23 | 250 | | 1 1 1 5 | 960 | 5/243 | %2,06 | 1 050 | | 1 1 1 1 5 | 120 | 5/1 944 | %0,26 | 2 050 | | 1 1 1 1 1 5 | 6 | 1/7 776 | %0,01 | 4 050 | | 1 5 5 | 3 840 | 20/243 | %8,23 | 200 | | 1 5 5 5 | 960 | 5/243 | %2,06 | 600 | | 1 5 5 5 5 | 120 | 5/1 944 | %0,26 | 1 100 | | 1 5 5 5 5 5 | 6 | 1/7 776 | %0,01 | 2 100 | | 1 1 5 5 | 1 440 | 5/162 | %3,09 | 300 | | 1 1 1 5 5 | 240 | 5/972 | %0,51 | 1 100 | | 1 1 5 5 5 | 240 | 5/972 | %0,51 | 700 | | 1 1 1 5 5 5 | 20 | 5/11 664 | %0,04 | 1 500 | | 1 1 1 | 1 280 | 20/729 | %2,74 | 1 000 | | 2 2 2 | 540 | 5/432 | %1,16 | 200 | | 3 3 3 | 540 | 5/432 | %1,16 | 300 | | 4 4 4 | 540 | 5/432 | %1,16 | 400 | | 5 5 5 | 1 280 | 20/729 | %2,74 | 500 | | 6 6 6 | 540 | 5/432 | %1,16 | 600 | | 1 1 1 1 | 240 | 5/972 | %0,51 | 2 000 | | 2 2 2 2 | 135 | 5/1 728 | %0,29 | 400 | | 3 3 3 3 | 135 | 5/1 728 | %0,29 | 600 | | 4 4 4 4 | 135 | 5/1 728 | %0,29 | 800 | | 5 5 5 5 | 240 | 5/972 | %0,51 | 1 000 | | 6 6 6 6 | 135 | 5/1 728 | %0,29 | 1 200 | | 1 1 1 1 1 | 24 | 1/1 944 | %0,05 | 4 000 | | 2 2 2 2 2 | 18 | 1/2 592 | %0,04 | 800 | | 3 3 3 3 3 | 18 | 1/2 592 | %0,04 | 1 200 | | 4 4 4 4 4 | 18 | 1/2 592 | %0,04 | 1 600 | | 5 5 5 5 5 | 24 | 1/1 944 | %0,05 | 2 000 | | 6 6 6 6 6 | 18 | 1/2 592 | %0,04 | 2 400 | | 1 1 1 1 1 1 | 1 | 1/46 656 | %0,00 | 8 000 | | 2 2 2 2 2 2 | 1 | 1/46 656 | %0,00 | 1 600 | | 3 3 3 3 3 3 | 1 | 1/46 656 | %0,00 | 2 400 | | 4 4 4 4 4 4 | 1 | 1/46 656 | %0,00 | 3 200 | | 5 5 5 5 5 5 | 1 | 1/46 656 | %0,00 | 4 000 | | 6 6 6 6 6 6 | 1 | 1/46 656 | %0,00 | 4 800 | | 1 2 3 4 5 | 1 800 | 25/648 | %3,86 | 500 | | 2 3 4 5 6 | 1 800 | 25/648 | %3,86 | 750 | | 1 2 3 4 5 6 | 720 | 5/324 | %1,54 | 1 500 | | İflas | 1 350 | 25/864 | %2,89 | 0 | Şimdi tekrar ediyorum: Şu anda yapay zekanın mantıklı oynadığını sanmıyorum ve yapay zeka hamlelerini yapmak için düşünmekle çok vakit kaybediyor. Bunu engellemek için yapay zekanın uzunca düşünerek oynamasından ziyade onu belirli bir algoritmayı sürekli takip etmeye zorlamak istiyorum. Bu sayede düşünmekle zaman kaybetmeyecek, ona verdiğim algoritmaya göre DEVAM mı yoksa TAMAM mı demesi gerektiğine karar verecek ve o algoritmaya göre oynayacak hamlelerini sürekli. Yukarıda sana hangi zar durumları için TAMAM mı yoksa DEVAM mı demesi gerektiğini detaylıca açıkladım. Buna göre gerekli değişikliklerin yapılması gerekiyor.
User prompt
Şu anda hesabı sıfırladığım zaman zar istatistikleri (hangi zardan kaç kere geldiğini gösteren) sıfırlanmıyor, bunu düzelt. Ayrıca şu anda 2. oyuncu (NPC yani Yapay Zeka) çok zeki değil gibi geldi bana. Mesela zarlar 1 3 4 1 2 1 geldiğinde 1 1 1 yapıp BANK yapacağına 1'i tutup kalan 5 zarı tekrar atıyor ama bu mantıksız bence. Yapay zekayı daha akıllı yapmak için gerekli düzeltmeleri de yap. Beyin fırtınası yap!
User prompt
İstediğim olmadı hala! Ben şu anda mesela oyunun ortasında oyundan çıkıp oyuna tekrar girdiğim zaman kaldığım yerden devam etmiyorum, beni yeni bir oyuna başlatıyor otomatik olarak. Ben kaldığım yerden devam edebilmek istiyordum oyuna çıkıp girsem bile. Bunu neden bir türlü yapamıyorsun? Sorun ne?
User prompt
Ama ben şu anda mesela oyunun ortasında oyundan çıkıp oyuna tekrar girdiğim zaman kaldığım yerden devam etmiyorum, beni yeni bir oyuna başlatıyor otomatik olarak. Ben kaldığım yerden devam edebilmek istiyordum. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.tempGameState = {' Line Number: 1022
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// geri düş: ms cinsinden epoch
// Konfeti Parçacığı Sınıfı
var ConfettiParticle = Container.expand(function () {
var self = Container.call(this);
// Rastgele renk ve şekil seç
function randomColor() {
// Canlı, pastel ve koyu renkler karışık
var palette = [[255, 59, 59],
// kırmızı
[59, 255, 59],
// yeşil
[59, 59, 255],
// mavi
[255, 224, 102],
// sarı
[102, 224, 255],
// açık mavi
[255, 102, 224],
// pembe
[255, 255, 255],
// beyaz
[255, 165, 0],
// turuncu
[0, 230, 230],
// cam göbeği
[142, 68, 173],
// mor
[46, 204, 64],
// koyu yeşil
[243, 156, 18],
// altın sarısı
[231, 76, 60],
// canlı kırmızı
[22, 160, 133],
// teal
[52, 73, 94],
// koyu mavi
[255, 192, 203],
// pastel pembe
[173, 216, 230],
// pastel mavi
[255, 255, 153],
// pastel sarı
[204, 255, 204],
// pastel yeşil
[255, 153, 204] // pastel fuşya
];
var idx = Math.floor(Math.random() * palette.length);
var rgb = palette[idx];
// RGB to hex
return (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
}
var color = randomColor();
var shapeType = Math.random() < 0.5 ? 'box' : 'ellipse';
// Rastgele boyut
var size = 32 + Math.floor(Math.random() * 32);
// Asset oluştur
// 'confettiShape' adında bir shape asset'i kullanıyoruz (id önemli değil, motor otomatik oluşturur)
var asset = self.attachAsset('confettiShape', {
width: size,
height: size,
anchorX: .5,
anchorY: .5
});
asset.tint = color;
// Başlangıç pozisyonu: X rastgele, Y üstte
self.x = 80 + Math.random() * (2048 - 160);
self.y = -40 - Math.random() * 80;
// Rastgele hız ve açı
self.vy = 3 + Math.random() * 3; // Düşme hızı
self.vx = -2 + Math.random() * 4; // Sağa/sola savrulma
self.spin = -0.05 + Math.random() * 0.1; // Hafif dönme
// Hafifçe şeffaflık
asset.alpha = 0.85 + Math.random() * 0.15;
// Hafifçe farklı ölçek
asset.scaleX = 0.8 + Math.random() * 0.6;
asset.scaleY = 0.8 + Math.random() * 0.6;
// Dönme açısı
asset.rotation = Math.random() * Math.PI * 2;
// Son pozisyonları takip et (gerekirse)
self.lastY = self.y;
// Her frame güncelle
self.update = function () {
self.x += self.vx;
self.y += self.vy;
asset.rotation += self.spin;
// Hafifçe sağa/sola dalgalanma
self.vx += -0.1 + Math.random() * 0.2;
// Ekran dışına çıktıysa yok et
if (self.y > 2732 + 60) {
if (self.parent) {
self.parent.removeChild(self);
}
self._destroyed = true;
}
};
return self;
});
/****
* Initialize Game
****/
/***********************************************************
* 1. KISIM — VARLIKLAR, GENEL TANIMLAR, Dice SINIFI
************************************************************/
/* --- Zar sınıfı --- */
// Joker zarı için (zar6 ile aynı görsel, gerekirse farklı id ile değiştir)
// Kanvas boyutları
/* --- Oyun nesnesi --- */
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// 1-5 listelerinde _sıralı string_ kullanıyoruz (örn: "115").
/* ---------------- NPC Pattern Tabloları ---------------- */
/* === AI globals & stats ================================= */
var BUST_PASS_DELAY = 600;
var CONTINUE_PATTERNS = {
6: ["1", "5", "11", "55", "15", "115", "155", "1155"],
5: ["1", "5", "11", "55", "15", "115", "155"],
4: ["1", "5", "11", "55", "15"],
3: ["1", "5", "55"],
// “1 5” burada yok –> 3 zarla banklamak istiyorsun
2: ["5"],
// sadece tek 5
1: ["5"] // tek 5
};
var NPC_STEP_DELAY = 1000; // 1 saniye
function applyFinalDecision() {
// BANK mi DEVAM mı zaten bestMoveBank değişkeninde
if (bestMoveBank) {
var _LK$getSound;
(_LK$getSound = LK.getSound('tutVeTuruSonlandirSesi')) === null || _LK$getSound === void 0;
// 1 sn boyunca seçili zarlar ekranda kalsın
LK.setTimeout(function () {
var _bestMove$score, _bestMove;
selectedScores[NPC] = (_bestMove$score = (_bestMove = bestMove) === null || _bestMove === void 0 ? void 0 : _bestMove.score) !== null && _bestMove$score !== void 0 ? _bestMove$score : 0;
tempScores[NPC] += selectedScores[NPC];
scores[NPC] += tempScores[NPC];
tempScores[NPC] = selectedScores[NPC] = 0;
updateHUD();
endTurn();
}, NPC_STEP_DELAY);
} else {
var _bestMove$score3, _bestMove3;
var _LK$getSound2, _bestMove$score2, _bestMove2;
(_LK$getSound2 = LK.getSound('tutVeDevamEtSesi')) === null || _LK$getSound2 === void 0;
/* 1. Skoru ekle */
selectedScores[NPC] = (_bestMove$score3 = (_bestMove3 = bestMove) === null || _bestMove3 === void 0 ? void 0 : _bestMove3.score) !== null && _bestMove$score3 !== void 0 ? _bestMove$score3 : 0;
tempScores[NPC] += selectedScores[NPC];
selectedScores[NPC] = 0;
/* 2. Zarları henüz silme! – önce yeni atış gösterilsin */
updateHUD(); // seçili zarlar masada, sayılar güncel
/* 3. Kalan zarları döndür; silme işini callback’te yapacağız */
var toErase = dice.filter(function (d) {
return d.selected;
}); // referans tut
animateRoll(function () {
/* 3.a Seçili zarları ANCAK yeni değerler göründükten sonra kaldır */
dice = dice.filter(function (d) {
return !toErase.includes(d);
});
selectedDiceIdx = [];
if (dice.length === 0) {
resetDice(6, false);
} else {
dice.forEach(function (d) {
d.selected = false;
});
renumberDice();
updateDicePositions();
}
var leftVals = dice.map(function (d) {
return d.value;
});
if (!canMakeAnyScore(leftVals)) {
npcBustFlow();
} else {
LK.setTimeout(npcQuickDecision, NPC_STEP_DELAY);
}
}, false);
}
}
/* ––– YALNIZ BANKLAMADA KULLANILACAK –––
* Elinizdeki zarlar arasından PUAN GETİREN
* Tüm alt–kümeleri tarar, en yüksek skorluyu döndürür.
* Hiç puanlı seçim yoksa null döner. */
function bestScoringCombo(vals) {
var best = null,
bestScore = -1;
for (var k = 1; k <= vals.length; k++) {
getCombinations(vals, k).forEach(function (c) {
if (isValidSelection(c)) {
var s = calcScoreFarkle(c).score;
if (s > bestScore) {
bestScore = s;
best = c;
}
}
});
}
return best ? {
combo: best,
score: bestScore
} : {
combo: [],
score: 0
};
}
var lastCombos = null;
// --- 1A) Oyunun MCTS için serileştirilmiş hali ---
function _createForOfIteratorHelper4(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray4(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n4 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n4 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n4++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray4(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray4(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray4(r, a) : void 0;
}
}
function _arrayLikeToArray4(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _typeof3(o) {
"@babel/helpers - typeof";
return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof3(o);
}
function _typeof2(o) {
"@babel/helpers - typeof";
return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof2(o);
}
function _classCallCheck2(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
}
function __defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey2(o.key), o);
}
}
function _createClass2(e, r, t) {
return r && __defineProperties(e.prototype, r), t && __defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _toPropertyKey2(t) {
var i = _toPrimitive2(t, "string");
return "symbol" == _typeof2(i) ? i : i + "";
}
function _toPrimitive2(t, r) {
if ("object" != _typeof2(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof2(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
var bestMove = null,
bestMoveBank = false,
bestMoveScore = -Infinity;
var perfNow = typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now.bind(performance) : function () {
return Date.now();
}; // yüksek çözünürlüklü süre
// Konfeti renkleri (dilediğin kadar ekleyebilirsin)
// --- Konfeti Efekti için Global Değişkenler ve Sınıf ---
// Music for each screen
var CONFETTI_COLORS = [0xff3b3b, 0x3bff3b, 0x3b3bff, 0xffe066, 0x66e0ff, 0xff66e0, 0xffffff, 0xffa500, 0x00e6e6];
// Konfeti parçacıklarını tutan dizi
var confettiParticles = [];
// Konfeti efektinin interval referansı
var confettiInterval = null;
// utils.js – script’in başına ekle
function enumerateRolls(n, buf, out) {
buf = buf || [];
out = out || [];
if (buf.length === n) {
out.push(buf.slice());
return out;
}
for (var v = 1; v <= 6; v++) {
buf.push(v);
enumerateRolls(n, buf, out);
buf.pop();
}
return out;
}
// Küçük bir cache – aynı n için tekrar hesaplamasın
var _rollCache = {};
function getAllRolls(n) {
return _rollCache[n] || (_rollCache[n] = enumerateRolls(n));
}
function depthFor(n, hotDice) {
// daha sığ – CPU harcamasını %30 ↓
if (hotDice) {
return 8;
}
return n <= 2 ? 7 : n === 3 ? 6 : n === 4 ? 5 : 4;
}
/* 1-6 zar için tam simetrik permütasyon kümesi – 7776’dan ≈ 1 020 satıra iner */
var _symTable = {};
function getSymmetricRolls(n) {
if (_symTable[n]) {
return _symTable[n];
}
var uniq = Object.create(null),
arr = [];
function rec(pos, buf) {
if (pos === n) {
uniq[buf.join('')] = buf.slice();
return;
}
for (var v = 1; v <= 6; v++) {
buf[pos] = v;
rec(pos + 1, buf);
}
}
rec(0, new Array(n));
/* anahtar sırası önemli değil */
for (var k in uniq) {
arr.push(uniq[k]);
}
return _symTable[n] = arr;
}
/* --- Zar sınıfı --- */
// Joker zarı için (zar6 ile aynı görsel, gerekirse farklı id ile değiştir)
function _createForOfIteratorHelper3(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray3(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n3 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n3 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n3++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray3(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray3(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray3(r, a) : void 0;
}
}
function _arrayLikeToArray3(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _createForOfIteratorHelper2(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray2(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n2 = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n2 >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n2++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray2(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray2(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0;
}
}
function _arrayLikeToArray2(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) {
return;
}
f = !1;
} else {
for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
;
}
}
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
return;
}
} finally {
if (o) {
throw n;
}
}
}
return a;
}
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) {
return r;
}
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
function _toPrimitive(t, r) {
if ("object" != _typeof(t) || !t) {
return t;
}
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != _typeof(i)) {
return i;
}
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _possibleConstructorReturn(t, e) {
if (e && ("object" == _typeof(e) || "function" == typeof e)) {
return e;
}
if (void 0 !== e) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(t);
}
function _assertThisInitialized(e) {
if (void 0 === e) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return e;
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
return !!t;
})();
}
function _getPrototypeOf(t) {
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
return t.__proto__ || Object.getPrototypeOf(t);
}, _getPrototypeOf(t);
}
function _inherits(t, e) {
if ("function" != typeof e && null !== e) {
throw new TypeError("Super expression must either be null or a function");
}
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), Object.defineProperty(t, "prototype", {
writable: !1
}), e && _setPrototypeOf(t, e);
}
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
return t.__proto__ = e, t;
}, _setPrototypeOf(t, e);
}
var W = 2048,
H = 2732;
var Dice = /*#__PURE__*/function (_Container) {
function Dice() {
var _this;
_classCallCheck(this, Dice);
_this = _callSuper(this, Dice);
/** Zar yüzü (1-6) */
_this.value = 1;
/** Seçili mi? */
_this.selected = false;
// Zar yüzü asset'i (her değer için ayrı)
_this.face = _this.attachAsset('zar1', {
anchorX: .5,
anchorY: .5
});
_this.updateFace = function () {
// Eski asset'i kaldır
if (_this.face && _this.face.parent) {
_this.face.parent.removeChild(_this.face);
}
// Yeni asset'i ekle
var assetName = 'zar' + _this.value;
_this.face = _this.attachAsset(assetName, {
anchorX: .5,
anchorY: .5
});
};
// Başlangıçta 1 ile başlat
_this.value = 1;
_this.selected = false;
_this.updateFace();
return _this;
}
/** Değeri ayarla + yüzü güncelle */
_inherits(Dice, _Container);
return _createClass(Dice, [{
key: "setValue",
value: function setValue(v) {
this.value = v;
this.updateFace();
}
}]);
}(Container);
// --- Global durum --- */
var PLAYER = 0,
NPC = 1;
var scores = [0, 0],
turnScore = 0,
current = PLAYER,
gameOver = false;
var dice = []; // Aktif zarlar
var selectedDiceIdx = []; // Seçili zar indeksleri
var diceGroup = null,
selectedDiceGroup = null;
// --- Oyun Devamı için Geçici Kayıt/Restore ---
// Kaydedilecek anahtarlar: scores, tempScores, selectedScores, turnScore, turnNumber, current, diceVals, selectedDiceIdx, gameOver
function saveGameState() {
// Sadece oyun devam ediyorsa kaydet
if (gameOver) {
if (typeof storage !== "undefined" && storage) {
storage.tempGameState = null;
}
return;
}
var diceVals = dice.map(function (d) {
return d.value;
});
var diceSelected = dice.map(function (d) {
return !!d.selected;
});
if (typeof storage !== "undefined" && storage) {
try {
storage.tempGameState = {
scores: scores.slice(),
tempScores: tempScores.slice(),
selectedScores: selectedScores.slice(),
turnScore: turnScore,
turnNumber: turnNumber,
current: current,
diceVals: diceVals,
diceSelected: diceSelected,
selectedDiceIdx: selectedDiceIdx.slice(),
gameOver: gameOver
};
} catch (e) {
// Defensive: ignore storage errors
}
}
}
function restoreGameState() {
var state = storage.tempGameState;
if (!state || state.gameOver) {
return false;
}
// Restore all main variables
scores = state.scores.slice();
tempScores = state.tempScores.slice();
selectedScores = state.selectedScores.slice();
turnScore = state.turnScore;
turnNumber = state.turnNumber;
current = state.current;
gameOver = state.gameOver;
// Zarları oluştur ve değerleri ata
resetDice(state.diceVals.length, false);
for (var i = 0; i < dice.length; i++) {
dice[i].setValue(state.diceVals[i]);
dice[i].selected = !!state.diceSelected[i];
}
selectedDiceIdx = state.selectedDiceIdx.slice();
updateDicePositions();
updateHUD();
return true;
}
// Oyun sırasında önemli değişikliklerde kaydet
function saveGameStateIfNeeded() {
// Oyun ekranındayken ve oyun bitmemişse kaydet
if (!gameOver && typeof mainMenuContainer === "undefined" || !mainMenuContainer) {
saveGameState();
}
}
// Oyun başında otomatik olarak restore etmeye çalış
(function tryRestoreOnLoad() {
// Sadece bir kez hook'la, tekrar tekrar sarmalama!
if (storage && storage.tempGameState && storage.tempGameState.gameOver !== true) {
// Yükleme ekranı kalkınca restore et
var origStartGame = startGame;
startGame = function startGame() {
// Sadece bir kez restore etmeye çalış
if (typeof storage !== "undefined" && storage && storage.tempGameState && storage.tempGameState.gameOver !== true) {
if (restoreGameState()) {
// Oyun arkaplanını güncelle (restoreGameState'de resetDice çağrıldı, burada tekrar ekle)
if (game._oyunBg) {
game._oyunBg.destroy();
game._oyunBg = null;
}
var oyunBg = LK.getAsset('oyunEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
game.addChildAt(oyunBg, 0);
game._oyunBg = oyunBg;
updateHUD();
var ilkSenBasliyorsunSesi = LK.getSound && LK.getSound('ilkSenBasliyorsunSesi');
if (ilkSenBasliyorsunSesi && ilkSenBasliyorsunSesi.play) {
ilkSenBasliyorsunSesi.play();
}
// Zar animasyonu oynatma (isteğe bağlı, restore sonrası)
animateRoll();
return;
}
}
origStartGame();
};
}
})();
// Oyun bittiğinde veya ana menüye dönüldüğünde kaydı temizle
function clearGameState() {
storage.tempGameState = null;
}
/* --- Diziyi yeniden numaralandır + doğru tıklama --- */
function renumberDice() {
for (var i = 0; i < dice.length; i++) {
var d = dice[i];
d.idx = i; // güncel indis
d.down = function () {
toggleSelect(this.idx);
}; // <— closure sorunu yok
}
}
/***********************************************************
* 2. KISIM — SKOR HESABI ve KOMBİNASYON YARDIMCILARI
************************************************************/
/* Farkle puan tablosu */
function calcScoreFarkle(vals) {
var cnt = Array(7).fill(0);
vals.forEach(function (v) {
return cnt[v]++;
});
var score = 0,
used = [];
/* Full straight 1-6 */
if (vals.length === 6 && [1, 2, 3, 4, 5, 6].every(function (v) {
return cnt[v] === 1;
})) {
return {
score: 1500,
used: [0, 1, 2, 3, 4, 5]
};
}
/* Partial straight 1-5 */
if (vals.length === 5 && [1, 2, 3, 4, 5].every(function (v) {
return cnt[v];
})) {
return {
score: 500,
used: [0, 1, 2, 3, 4]
};
}
/* Partial straight 2-6 */
if (vals.length === 5 && [2, 3, 4, 5, 6].every(function (v) {
return cnt[v];
})) {
return {
score: 750,
used: [0, 1, 2, 3, 4]
};
}
/* 3-6 aynı zar kümeleri */
for (var v = 1; v <= 6; v++) {
if (cnt[v] >= 3) {
var base = v === 1 ? 1000 : v * 100;
var factor = [1, 2, 4, 8][cnt[v] - 3];
score += base * factor;
var need = cnt[v];
vals.forEach(function (val, i) {
if (val === v && need) {
used.push(i);
need--;
}
});
cnt[v] = 0; // tekil sayılmasın
}
}
/* Tekil 1 & 5 */
vals.forEach(function (v, i) {
if (used.includes(i)) {
return;
}
if (v === 1) {
score += 100;
used.push(i);
}
if (v === 5) {
score += 50;
used.push(i);
}
});
return {
score: score,
used: used
};
}
/*****************************************************************
* Eksiksiz olasılık tablosu – oyun açılışında bir kez hesaplanır
*****************************************************************/
var exactFarkleTable = {}; // diceLeft → {bust, expected}
(function buildExactTable() {
for (var diceLeft = 1; diceLeft <= 6; diceLeft++) {
var total = 0; // 6^n
var bustCount = 0;
var scoreSum = 0; // yalnızca skor alınan durumlarda toplanır
var faces = Array(diceLeft).fill(0);
// kartesyen ürün: 6^diceLeft kombinasyonu tek tek dolaş
(function dfs(pos) {
if (pos === diceLeft) {
total++;
var r = calcScoreFarkle(faces);
if (r.score === 0) {
bustCount++;
} else {
scoreSum += r.score;
} // en yüksek skora göre
return;
}
for (var f = 1; f <= 6; f++) {
faces[pos] = f;
dfs(pos + 1);
}
})(0);
var bustProb = bustCount / total;
var expectedWhenScore = scoreSum / Math.max(1, total - bustCount); // skorlu durumda ort.
exactFarkleTable[diceLeft] = {
bust: bustProb,
expected: expectedWhenScore
};
}
})();
/* Seçim geçerli mi? */
function isValidSelection(selVals) {
var r = calcScoreFarkle(selVals);
return r.score > 0 && r.used.length === selVals.length;
}
/* Belirli uzunlukta kombinasyonları döndür */
function getCombinations(arr, k) {
var out = [];
(function helper(start, path) {
if (path.length === k) {
out.push(path.slice());
return;
}
for (var i = start; i < arr.length; i++) {
path.push(arr[i]);
helper(i + 1, path);
path.pop();
}
})(0, []);
return out;
}
/* Kalan zarlarla **hiç** skor yapılabilir mi? */
function canMakeAnyScore(vals) {
if (!vals.length) {
return false;
}
for (var i = 1; i <= vals.length; i++) {
var combs = getCombinations(vals, i);
var _iterator = _createForOfIteratorHelper(combs),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var c = _step.value;
if (isValidSelection(c)) {
return true;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
return false;
}
/***********************************************************
* 3. KISIM — GUI, HUD ve ZAR YÖNETİMİ
************************************************************/
/* --- Butonlar --- */
// TUT ve DEVAM ET butonu
var rollBtn = new Container();
rollBtn.attachAsset('tutVeDevamEtButonuGorseli', {
anchorX: .5,
anchorY: .5
});
var rollTxt = new Text2('DEVAM', {
size: 80,
fill: '#fff'
});
rollTxt.anchor.set(.5, .5);
rollTxt.y = 40;
rollBtn.addChild(rollTxt);
LK.gui.bottom.addChild(rollBtn);
rollBtn.x = -500;
rollBtn.y = -160;
// TUT ve TURU SONLANDIR butonu
var bankBtn = new Container();
bankBtn.attachAsset('tutVeTuruSonlandirButonuGorseli', {
anchorX: .5,
anchorY: .5
});
var bankTxt = new Text2('TAMAM', {
size: 80,
fill: '#fff'
});
bankTxt.anchor.set(.5, .5);
bankTxt.y = 40;
bankBtn.addChild(bankTxt);
LK.gui.bottom.addChild(bankBtn);
bankBtn.x = 0;
bankBtn.y = -160;
// PAS GEÇ butonu
var passBtn = new Container();
passBtn.attachAsset('pasGecButonuGorseli', {
anchorX: .5,
anchorY: .5
});
var passTxt = new Text2('PAS', {
size: 80,
fill: '#fff'
});
passTxt.anchor.set(.5, .5);
passTxt.y = 40;
passBtn.addChild(passTxt);
LK.gui.bottom.addChild(passBtn);
// PAS GEÇ butonunu TUT ve TURU SONLANDIR butonunun sağına yerleştir
passBtn.x = 500;
passBtn.y = -160;
/* --- Reset & Pozisyon --- */
function resetDice() {
var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 6;
var randomize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (diceGroup) {
diceGroup.destroy();
}
if (selectedDiceGroup) {
selectedDiceGroup.destroy();
}
dice = [];
selectedDiceIdx = [];
diceGroup = new Container();
selectedDiceGroup = new Container();
game.addChild(diceGroup);
game.addChild(selectedDiceGroup);
var diceSpacing = 280;
var startX = W / 2 - (n - 1) * diceSpacing / 2;
var y = H / 2;
for (var i = 0; i < n; i++) {
var d = new Dice();
d.x = startX + i * diceSpacing;
d.y = y;
if (randomize) {
d.setValue(1 + (Math.random() * 6 | 0));
}
diceGroup.addChild(d);
dice.push(d);
}
renumberDice();
updateDicePositions();
updateHUD();
}
/* Seç/Aç seçimi */
function toggleSelect(idx) {
if (gameOver || current !== PLAYER) {
return;
}
var d = dice[idx];
if (d.selected) {
d.selected = false;
selectedDiceIdx = selectedDiceIdx.filter(function (i) {
return i !== idx;
});
// Play zarBirakmaSesi when deselecting
var birakmaSesi = LK.getSound && LK.getSound('zarBirakmaSesi');
if (birakmaSesi && birakmaSesi.play) {
birakmaSesi.play();
}
} else {
d.selected = true;
if (!selectedDiceIdx.includes(idx)) {
selectedDiceIdx.push(idx);
}
// Play zarSecmeSesi when selecting
var secmeSesi = LK.getSound && LK.getSound('zarSecmeSesi');
if (secmeSesi && secmeSesi.play) {
secmeSesi.play();
}
}
updateDicePositions();
updateHUD();
saveGameState(); // Her seçimde kaydet
}
/* Konumları güncelle */
function updateDicePositions() {
if (!diceGroup || !selectedDiceGroup) {
return;
}
diceGroup.removeChildren();
selectedDiceGroup.removeChildren();
// YENİ: her iki oyuncu için d.selected bayrağını kullan
var sel = [],
unsel = [];
for (var i = 0; i < dice.length; i++) {
var d = dice[i];
if (!d) {
continue;
} // güvenlik
if (d.selected) {
sel.push(i);
selectedDiceGroup.addChild(d);
} else {
unsel.push(i);
diceGroup.addChild(d);
}
}
/* Seçili zarlar aşağıda (hem PLAYER hem de NPC için) */
// 2. oyuncu (NPC) için de seçili zarlar aşağıda dizilecek
var diceSpacing = 280;
var selStart = W / 2 - (sel.length - 1) * diceSpacing / 2;
var selY = H / 2 + 280;
sel.forEach(function (idx, i) {
var d = dice[idx];
d.x = selStart + i * diceSpacing;
d.y = selY;
d.face.alpha = .6;
});
/* Diğer zarlar ortada */
var unStart = W / 2 - (unsel.length - 1) * diceSpacing / 2,
y = H / 2;
unsel.forEach(function (idx, i) {
var d = dice[idx];
d.x = unStart + i * diceSpacing;
d.y = y;
d.face.alpha = 1;
});
}
/**** ZAR DÖNDÜRME ANİMASYONU ****/
function animateRoll(onFinish) {
var playSfx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
if (game._rolling) {
return;
} // Çifte animasyonu engelle
game._rolling = true;
if (playSfx) {
var s = LK.getSound && LK.getSound('tutVeDevamEtSesi');
s === null || s === void 0 || s.play();
}
rollBtn.interactive = bankBtn.interactive = passBtn.interactive = false;
dice.forEach(function (d) {
return d.down = function () {};
}); // Zarlar seçilemesin
var rollDuration = 2000,
step = 60;
var elapsed = 0;
(function tick() {
dice.forEach(function (d) {
if (!d.selected) {
d.setValue(1 + Math.random() * 6 | 0);
}
});
updateDicePositions();
if ((elapsed += step) < rollDuration) {
LK.setTimeout(tick, step);
} else {
game._rolling = false;
rollBtn.interactive = bankBtn.interactive = passBtn.interactive = true;
renumberDice(); // Zarlar yeniden seçilebilir
// --- Zar istatistiklerini güncelle (sadece oyuncu için) ---
if (current === PLAYER) {
var playerDiceVals = dice.filter(function (d) {
return !d.selected;
}).map(function (d) {
return d.value;
});
updateZarStatsForPlayerDice(playerDiceVals);
refreshZarStatsTxt();
}
onFinish === null || onFinish === void 0 || onFinish(); // Animasyon tamam callback
}
})();
}
/***********************************************************
* 4. KISIM — OYUN DÖNGÜSÜ, NPC, HUD, BAŞLAT
************************************************************/
/* --- HUD --- */
// Skor tablosu için Text2 objeleri
var scoreTableRows = [null, null, null, null];
var turnTxt;
var TARGET_SCORE = 8000; // Hedef puan
var BANK_BIAS = TARGET_SCORE * 2; /* vuruş anında daha agresif banklama */
var _INFTY = 1e12; // alpha-beta için pratik sonsuz
// Geçici ve seçilen skorlar için yeni değişkenler
var tempScores = [0, 0]; // Geçici skorlar (her oyuncu için)
var selectedScores = [0, 0]; // Seçilen skorlar (her oyuncu için)
var turnNumber = 1; // Tur sayısı
function updateHUD() {
// --- Buton aktifliği ---
var selVals = selectedDiceIdx.map(function (i) {
return dice[i].value;
});
var valid = isValidSelection(selVals);
rollBtn.alpha = bankBtn.alpha = valid ? 1 : 0.4;
rollBtn.interactive = bankBtn.interactive = valid && current === PLAYER && !gameOver;
// --- Skor tablosu ilk kez oluşturuluyorsa ekle ---
if (!scoreTableRows[0]) {
// Lig: 10 oyun öncesi derecesiz, sonrası oran aralığına göre
var getLeagueAsset = function getLeagueAsset(totalGames, winGames) {
if (totalGames < 10) {
return "derecesizLigi";
}
var rate = totalGames > 0 ? Math.round(winGames / totalGames * 100) : 0;
if (rate <= 10) {
return "demirLigi";
}
if (rate <= 20) {
return "bronzLigi";
}
if (rate <= 30) {
return "gumusLigi";
}
if (rate <= 40) {
return "altinLigi";
}
if (rate <= 50) {
return "zumrutLigi";
}
if (rate <= 60) {
return "platinLigi";
}
if (rate <= 70) {
return "elmasLigi";
}
if (rate <= 80) {
return "ustaLigi";
}
if (rate <= 90) {
return "ustadLigi";
}
return "sampiyonlukLigi";
};
// --- Zar kombinasyonları ve puan tablosu ---
// Zar assetlerini göstermek için fonksiyon
var createDiceRow = function createDiceRow(diceArr, text, size, gap) {
var row = new Container();
var x = 0;
for (var i = 0; i < diceArr.length; i++) {
var asset = LK.getAsset(diceArr[i], {
anchorX: 0.5,
anchorY: 0.5,
width: size,
height: size
});
asset.x = x;
asset.y = 0;
row.addChild(asset);
x += size + (gap || 10);
}
if (text) {
var txt = new Text2(text, {
size: size * 0.6,
fill: '#fff'
});
txt.anchor.set(0, 0.5);
txt.x = x - 25;
txt.y = 0;
row.addChild(txt);
}
return row;
}; // Tabloyu oluştur
// --- Kazanma oranı, seviye, hedef ve lig göstergesi ---
// storage'dan toplam oyun ve kazanılan oyun sayısını al
var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0;
var winGames = typeof storage.winGames === "number" ? storage.winGames : 0;
// Seviye: Her kazanılan oyun için 1 artar, başlangıç 1
if (typeof storage.level !== "number" || storage.level < 1) {
storage.level = 1;
}
var level = storage.level;
// Hedef: Başlangıç 1000, her seviye +250
var dynamicTarget = 1000 + (level - 1) * 250;
var leagueAssetId = getLeagueAsset(totalGames, winGames);
// Lig görseli ekle/güncelle
if (!window.leagueBadge) {
window.leagueBadge = LK.getAsset(leagueAssetId, {
anchorX: 0.5,
anchorY: 0
});
LK.gui.top.addChild(window.leagueBadge);
// Skor tablosunun sağında, ortalanmış şekilde konumlandır
window.leagueBadge.x = 580;
window.leagueBadge.y = 75;
} else {
// Sadece asset değişirse güncelle
if (window.leagueBadge._assetId !== leagueAssetId) {
var parent = window.leagueBadge.parent;
var idx = parent ? parent.getChildIndex(window.leagueBadge) : -1;
window.leagueBadge.destroy();
window.leagueBadge = LK.getAsset(leagueAssetId, {
anchorX: 0.5,
anchorY: 0,
width: 200,
height: 200
});
if (parent && idx >= 0) {
parent.addChildAt(window.leagueBadge, idx);
}
window.leagueBadge.x = 600;
window.leagueBadge.y = 80;
}
}
window.leagueBadge._assetId = leagueAssetId;
// --- Kazanma oranı ve oyun sayısı yazısı ---
// Başlangıçta oran yoksa "∅", oyun sayısı yoksa "0"
if (!window.winRateTxt) {
window.winRateTxt = new Text2("", {
size: 48,
fill: '#ffe066',
fontWeight: 'bold'
});
window.winRateTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(window.winRateTxt);
}
var winRateStr = totalGames > 0 ? "%" + Math.round(winGames / totalGames * 100) : "∅";
var oyunSayisiStr = totalGames > 0 ? totalGames : "0";
window.winRateTxt.setText("Zafer Oranı: " + winRateStr + " | Maç Sayısı: " + oyunSayisiStr + " | Seviye: " + level);
window.winRateTxt.x = 0;
window.winRateTxt.y = 20;
// 1. satır: başlıklar
var playerNameDisplay = typeof playerName === "string" && playerName.length > 0 ? playerName : "1. Oyuncu";
scoreTableRows[0] = new Text2(playerNameDisplay + " | Hedef | Yapay Zeka", {
size: 54,
fill: '#fff',
fontWeight: 'bold'
});
scoreTableRows[0].anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTableRows[0]);
// Skor tablosunu ekranın tam ortasına yerleştir
// Tüm satırları ve sıra göstergesini tam ekranın ortasına hizala
var centerX = 0;
scoreTableRows[0].x = centerX;
scoreTableRows[0].y = 80;
// 2. satır: ana skorlar ve hedef
scoreTableRows[1] = new Text2("", {
size: 54,
fill: '#fff'
});
scoreTableRows[1].anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTableRows[1]);
scoreTableRows[1].x = centerX;
scoreTableRows[1].y = scoreTableRows[0].y + 60;
// 3. satır: geçici skorlar ve tur
scoreTableRows[2] = new Text2("", {
size: 48,
fill: '#ffe066'
});
scoreTableRows[2].anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTableRows[2]);
scoreTableRows[2].x = centerX;
scoreTableRows[2].y = scoreTableRows[1].y + 54;
// 4. satır: seçilen skorlar
scoreTableRows[3] = new Text2("", {
size: 44,
fill: '#b3e6ff'
});
scoreTableRows[3].anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTableRows[3]);
scoreTableRows[3].x = centerX;
scoreTableRows[3].y = scoreTableRows[2].y + 48;
// Sıra göstergesi
turnTxt = new Text2('', {
size: 54,
fill: '#ffe066',
fontWeight: 'bold'
});
turnTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(turnTxt);
turnTxt.x = centerX;
turnTxt.y = scoreTableRows[3].y + 60;
var scoreTableContainer = new Container();
scoreTableContainer.x = 0;
scoreTableContainer.y = turnTxt.y + 90;
var rowY = 0;
var rowGap = 70;
var diceSize = 60;
var bigGap = 80;
// 1. satır
var row1a = createDiceRow(['zar1'], "= 100", diceSize);
var row1b = createDiceRow(['zar1', 'zar1', 'zar1'], "= 1000", diceSize);
row1a.x = -400;
row1b.x = 200;
row1a.y = row1b.y = rowY + 10;
scoreTableContainer.addChild(row1a);
scoreTableContainer.addChild(row1b);
rowY += rowGap;
// 2. satır
var row2a = createDiceRow(['zar5'], "= 50", diceSize);
var row2b = createDiceRow(['zar2', 'zar2', 'zar2'], "= 200", diceSize);
row2a.x = -400;
row2b.x = 200;
row2a.y = row2b.y = rowY + 10;
scoreTableContainer.addChild(row2a);
scoreTableContainer.addChild(row2b);
rowY += rowGap;
// 3. satır
var row3a = createDiceRow(['zar1', 'zar2', 'zar3', 'zar4', 'zar5'], "= 500", diceSize);
var row3b = createDiceRow(['zar3', 'zar3', 'zar3'], "= 300", diceSize);
row3a.x = -400;
row3b.x = 200;
row3a.y = row3b.y = rowY + 10;
;
scoreTableContainer.addChild(row3a);
scoreTableContainer.addChild(row3b);
rowY += rowGap;
// 4. satır
var row4a = createDiceRow(['zar2', 'zar3', 'zar4', 'zar5', 'zar6'], "= 750", diceSize);
var row4b = createDiceRow(['zar4', 'zar4', 'zar4'], "= 400", diceSize);
row4a.x = -400;
row4b.x = 200;
row4a.y = row4b.y = rowY + 10;
;
scoreTableContainer.addChild(row4a);
scoreTableContainer.addChild(row4b);
rowY += rowGap;
// 5. satır
var row5a = createDiceRow(['zar1', 'zar2', 'zar3', 'zar4', 'zar5', 'zar6'], "= 1500", diceSize);
var row5b = createDiceRow(['zar5', 'zar5', 'zar5'], "= 500", diceSize);
row5a.x = -400;
row5b.x = 200;
row5a.y = row5b.y = rowY + 10;
;
scoreTableContainer.addChild(row5a);
scoreTableContainer.addChild(row5b);
rowY += rowGap;
// 6. satır
var row6a = createDiceRow(['zarJoker'], "= Joker", diceSize);
var row6b = createDiceRow(['zar6', 'zar6', 'zar6'], "= 600", diceSize);
row6a.x = -400;
row6b.x = 200;
row6a.y = row6b.y = rowY + 10;
;
scoreTableContainer.addChild(row6a);
scoreTableContainer.addChild(row6b);
rowY += rowGap;
// Ortala
scoreTableContainer.x = 0;
scoreTableContainer.y = turnTxt.y + 90;
scoreTableContainer.pivot.x = 0;
scoreTableContainer.pivot.y = 0;
scoreTableContainer.anchorX = 0.5;
scoreTableContainer.anchorY = 0;
scoreTableContainer.x = 0;
// GUI'ye ekle (top bölgesine, skor tablosunun altına)
LK.gui.top.addChild(scoreTableContainer);
scoreTableContainer.x = 0;
scoreTableContainer.y = turnTxt.y + 90;
// Altına gri açıklama yazısı ekle
if (!window._farkleScoreInfoTxt) {
var infoTxt = new Text2("3'ten sonraki her ilave zar değerini iki katına çıkarır.", {
size: 38,
fill: '#b0b0b0'
});
infoTxt.anchor.set(0.5, 0);
infoTxt.x = 0;
infoTxt.y = scoreTableContainer.y + scoreTableContainer.height;
LK.gui.top.addChild(infoTxt);
window._farkleScoreInfoTxt = infoTxt;
} else {
// Her update'te pozisyonunu güncelle
window._farkleScoreInfoTxt.x = 0;
window._farkleScoreInfoTxt.y = scoreTableContainer.y + scoreTableContainer.height + 20;
}
// Tablonun referansını sakla (gerekirse erişmek için)
window._farkleScoreTable = scoreTableContainer;
}
// --- Skor tablosunu güncelle ---
// Her zaman güncel dynamicTarget'ı göster
scoreTableRows[1].setText("Ana Skor: " + scores[PLAYER] + " | " + dynamicTarget + " | " + "Ana Skor: " + scores[NPC]);
scoreTableRows[2].setText("Geçici Skor: " + tempScores[PLAYER] + " | Tur: " + turnNumber + " | Geçici Skor: " + tempScores[NPC]);
// Seçilen Skor'u canlı olarak güncelle (her iki oyuncu için)
var liveSelectedScorePlayer = 0;
var liveSelectedScoreNPC = 0;
if (current === PLAYER && selectedDiceIdx.length > 0) {
var selValsLive = selectedDiceIdx.map(function (i) {
return dice[i].value;
});
if (isValidSelection(selValsLive)) {
liveSelectedScorePlayer = calcScoreFarkle(selValsLive).score;
}
}
if (current === NPC && dice.length > 0) {
// NPC'nin seçili zarlarını bul
var selValsLiveNPC = [];
for (var i = 0; i < dice.length; i++) {
if (dice[i].selected) {
selValsLiveNPC.push(dice[i].value);
}
}
if (selValsLiveNPC.length > 0 && isValidSelection(selValsLiveNPC)) {
liveSelectedScoreNPC = calcScoreFarkle(selValsLiveNPC).score;
}
}
scoreTableRows[3].setText("Seçilen Skor: " + (current === PLAYER ? liveSelectedScorePlayer : selectedScores[PLAYER]) + " | Seçilen | Seçilen Skor: " + (current === NPC ? liveSelectedScoreNPC : selectedScores[NPC]));
turnTxt.setText(current === PLAYER ? 'Sıra: 1. Oyuncuda' : 'Sıra: 2. Oyuncuda');
}
// --- Zar istatistikleri: her oyuncuya gelen zarların adedi ---
// storage'da saklanacak anahtarlar: zarStats = { zar1: 0, zar2: 0, ... }
var diceStatKeys = ['zar2', 'zar3', 'zar4', 'zar5', 'zar6', 'zar1', 'zarJoker'];
var defaultZarStats = {
zar1: 0,
zar2: 0,
zar3: 0,
zar4: 0,
zar5: 0,
zar6: 0,
zarJoker: 0
};
if (_typeof3(storage.zarStats) !== "object" || !storage.zarStats) {
storage.zarStats = Object.assign({}, defaultZarStats);
}
var zarStats = storage.zarStats;
// --- Zar istatistiklerini güncelleyen fonksiyon ---
// Bu fonksiyon, oyuncuya yeni zarlar geldiğinde çağrılmalı
function updateZarStatsForPlayerDice(diceArr) {
var changed = false;
for (var i = 0; i < diceArr.length; i++) {
var v = diceArr[i];
var key = "zar" + v;
if (key === "zar0" || key === "zarundefined" || key === "zarNaN") {
continue;
}
if (zarStats.hasOwnProperty(key)) {
zarStats[key]++;
changed = true;
}
}
// Joker zarları da say (ör: value==7 veya value==0 ise zarJoker)
for (var i = 0; i < diceArr.length; i++) {
if (diceArr[i] === 0 || diceArr[i] === 7) {
zarStats["zarJoker"]++;
changed = true;
}
}
if (changed) {
storage.zarStats = zarStats;
}
}
// --- Zar istatistiklerini gösteren görsel satır (dice assetleri + sayı) ---
// Sadece bir kez oluşturulacak, sonra güncellenecek
if (!window.zarStatsRow) {
// Ana container
var statsRow = new Container();
// Sıralama: zar2, zar3, zar4, zar5, zar6, zar1, zarJoker
var diceKeys = diceStatKeys;
var diceSize = 100;
var gap = 20;
var totalWidth = diceKeys.length * diceSize + (diceKeys.length - 1) * gap;
var startX = -totalWidth / 2 + diceSize / 2;
statsRow.diceAssets = [];
statsRow.countTexts = [];
for (var i = 0; i < diceKeys.length; i++) {
var key = diceKeys[i];
// Zar görseli
var asset = LK.getAsset(key, {
anchorX: 0.5,
anchorY: 1,
width: diceSize,
height: diceSize
});
asset.x = startX + i * (diceSize + gap);
asset.y = 0;
statsRow.addChild(asset);
statsRow.diceAssets.push(asset);
// Altına sayı
var count = zarStats[key] || 0;
var countTxt = new Text2(count + "", {
size: 36,
fill: 0xFFE066,
fontWeight: "bold"
});
countTxt.anchor.set(0.5, 0);
countTxt.x = asset.x;
countTxt.y = 8;
statsRow.addChild(countTxt);
statsRow.countTexts.push(countTxt);
}
// 'tutVeTuruSonlandirButonuGorseli' assetinin biraz üstünde olacak şekilde konumlandır
statsRow.x = bankBtn.x;
statsRow.y = bankBtn.y - 200;
LK.gui.bottom.addChild(statsRow);
window.zarStatsRow = statsRow;
}
// --- Zar istatistiklerini güncelleyen fonksiyon (görsel) ---
function refreshZarStatsTxt() {
// Sıralama: zar2, zar3, zar4, zar5, zar6, zar1, zarJoker
if (!window.zarStatsRow) {
return;
}
for (var i = 0; i < diceStatKeys.length; i++) {
var key = diceStatKeys[i];
var val = zarStats[key] || 0;
if (window.zarStatsRow.countTexts[i]) {
window.zarStatsRow.countTexts[i].setText(val + "");
}
}
}
// --- Oyun başında ve her zar atışında güncelle
refreshZarStatsTxt();
/**** --- Tur Aksiyonları --- */
function rollAll() {
if (gameOver || current !== PLAYER) {
return;
}
dice.forEach(function (d) {
if (!d.selected) {
d.setValue(1 + Math.floor(Math.random() * 6));
}
});
// --- Zar istatistiklerini güncelle (sadece oyuncu için) ---
if (current === PLAYER) {
var playerDiceVals = dice.filter(function (d) {
return !d.selected;
}).map(function (d) {
return d.value;
});
updateZarStatsForPlayerDice(playerDiceVals);
refreshZarStatsTxt();
}
updateDicePositions();
updateHUD();
saveGameState(); // Zar atınca kaydet
var unselVals = dice.filter(function (d) {
return !d.selected;
}).map(function (d) {
return d.value;
});
// Eğer oyuncu zar attıktan sonra hiçbir şekilde kombinasyon yapılamıyorsa otomatik olarak turu rakibe geçir
if (!canMakeAnyScore(unselVals)) {
// Kırmızı ekranı daha uzun göster (ör: 1200ms)
LK.effects.flashScreen(0xff0000, 1200);
// "İflas!" yazısı ekle
var iflasTxt = new Text2('İflas!', {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
iflasTxt.x = W / 2;
iflasTxt.y = H / 2;
iflasTxt.alpha = 1;
game.addChild(iflasTxt);
// İflas sesi (ben)
var iflasBenSesi = LK.getSound && LK.getSound('iflasBenSesi');
if (iflasBenSesi && iflasBenSesi.play) {
iflasBenSesi.play();
}
// 1 saniye boyunca göster, sonra yavaşça kaybolsun
LK.setTimeout(function () {
tween(iflasTxt, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
if (iflasTxt && iflasTxt.parent) {
iflasTxt.parent.removeChild(iflasTxt);
}
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
updateHUD();
LK.setTimeout(endTurn, BUST_PASS_DELAY);
}
});
}, 1000);
}
}
function keepAndContinue() {
if (gameOver || current !== PLAYER) {
return;
}
var selVals = selectedDiceIdx.map(function (i) {
return dice[i].value;
});
if (!isValidSelection(selVals)) {
return;
}
// Seçilen skor hesapla ve ekle
var selScore = calcScoreFarkle(selVals).score;
selectedScores[current] = selScore;
tempScores[current] += selectedScores[current];
selectedScores[current] = 0; // Seçilen skor sıfırlanır
// turnScore artık kullanılmıyor, backward compatibility için güncelle
turnScore = tempScores[current];
// Seçili zarları kaldır
dice = dice.filter(function (d, i) {
return !selectedDiceIdx.includes(i);
}).map(function (d) {
return d;
});
selectedDiceIdx = [];
if (dice.length === 0) {
// Zarları hemen oluştur, ama roll animasyonu ile göster
resetDice(6, false); // randomize = false, böylece değerler 1 olarak başlar ve animasyonla atanır
// Zar animasyonunu başlat, animasyon sonunda istatistikleri güncelle
animateRoll(function () {
// --- Zar istatistiklerini güncelle (hot dice: yeni 6 zar geldi) ---
if (current === PLAYER) {
var playerDiceVals = [];
for (var i = 0; i < dice.length; i++) {
playerDiceVals.push(dice[i].value);
}
updateZarStatsForPlayerDice(playerDiceVals);
refreshZarStatsTxt();
}
});
} else {
dice.forEach(function (d) {
d.selected = false; // sadece seçimi temizle
});
renumberDice();
updateDicePositions();
}
updateHUD();
saveGameState(); // Devam et seçeneğinde kaydet
var unselVals = dice.map(function (d) {
return d.value;
});
// Eğer kalan zarlarla hiçbir şekilde kombinasyon yapılamıyorsa otomatik olarak turu rakibe geçir
if (!canMakeAnyScore(unselVals)) {
LK.effects.flashScreen(0xff0000, 1200);
var iflasTxt = new Text2('İflas!', {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
iflasTxt.x = W / 2;
iflasTxt.y = H / 2;
iflasTxt.alpha = 1;
game.addChild(iflasTxt);
// İflas sesi (ben)
var iflasBenSesi = LK.getSound && LK.getSound('iflasBenSesi');
if (iflasBenSesi && iflasBenSesi.play) {
iflasBenSesi.play();
}
LK.setTimeout(function () {
tween(iflasTxt, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
if (iflasTxt && iflasTxt.parent) {
iflasTxt.parent.removeChild(iflasTxt);
}
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
updateHUD();
LK.setTimeout(endTurn, BUST_PASS_DELAY);
}
});
}, 1000);
}
}
function keepAndEndTurn() {
if (gameOver || current !== PLAYER) {
return;
}
var selVals = selectedDiceIdx.map(function (i) {
return dice[i].value;
});
if (!isValidSelection(selVals)) {
return;
}
// Seçilen skor hesapla ve ekle
var selScore = calcScoreFarkle(selVals).score;
selectedScores[current] = selScore;
// Ana skora ekle: geçici skor + seçilen skor
scores[current] += tempScores[current] + selectedScores[current];
// Sıfırla
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
updateHUD();
saveGameState(); // Tur sonlandırınca kaydet
// --- Zar istatistiklerini güncelle (tur sonunda kalan zarlar) ---
if (current === PLAYER) {
var playerDiceVals = [];
for (var i = 0; i < dice.length; i++) {
playerDiceVals.push(dice[i].value);
}
updateZarStatsForPlayerDice(playerDiceVals);
refreshZarStatsTxt();
}
endTurn();
}
function endTurn() {
// Kazanan kontrolü
// Hedefi dinamik olarak hesapla (her seviye için 1000 + (level-1)*250)
var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1;
var dynamicTarget = 1000 + (level - 1) * 250;
if (scores[current] >= dynamicTarget) {
showWinner();
return;
}
// Sırayı değiştir
var prevCurrent = current;
current = current === PLAYER ? NPC : PLAYER;
// Sıra değişiminde uygun sesi çal
if (prevCurrent === PLAYER && current === NPC) {
var rakibinSirasiSesi = LK.getSound && LK.getSound('rakibinSirasiSesi');
if (rakibinSirasiSesi && rakibinSirasiSesi.play) {
rakibinSirasiSesi.play();
}
} else if (prevCurrent === NPC && current === PLAYER) {
var siraSendeSesi = LK.getSound && LK.getSound('siraSendeSesi');
if (siraSendeSesi && siraSendeSesi.play) {
siraSendeSesi.play();
}
}
// Yeni oyuncunun geçici ve seçilen skorlarını sıfırla
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
// Tur sayısını sadece 1. oyuncuya geçerken artır
if (current === PLAYER) {
turnNumber++;
}
resetDice(6, current === PLAYER);
updateHUD();
saveGameState(); // Sıra değişince kaydet
// --- HATA DÜZELTME: Zarlar otomatik atıldığında hiçbir kombinasyon yapılamıyorsa otomatik iflas ve sıra geçişi ---
// Sadece yeni tur başında, zarlar atıldıktan hemen sonra kontrol et
var unselVals = dice.map(function (d) {
return d.value;
});
if (!canMakeAnyScore(unselVals)) {
// Ekranı kırmızıya flash et
LK.effects.flashScreen(0xff0000, 1200);
// "İflas!" yazısı ekle
var iflasTxt = new Text2('İflas!', {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
iflasTxt.x = W / 2;
iflasTxt.y = H / 2;
iflasTxt.alpha = 1;
game.addChild(iflasTxt);
// Sesi çal (oyuncuya göre)
var iflasSesi = null;
if (current === PLAYER) {
iflasSesi = LK.getSound && LK.getSound('iflasBenSesi');
} else {
iflasSesi = LK.getSound && LK.getSound('iflasRakipSesi');
}
if (iflasSesi && iflasSesi.play) {
iflasSesi.play();
}
LK.setTimeout(function () {
tween(iflasTxt, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
if (iflasTxt && iflasTxt.parent) {
iflasTxt.parent.removeChild(iflasTxt);
}
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
updateHUD();
// Sırayı tekrar değiştir (sonsuz döngüye girmemesi için current bir kez daha değişecek)
// Not: endTurn fonksiyonu tekrar çağrılırsa, bir sonraki oyuncuya geçer
LK.setTimeout(endTurn, BUST_PASS_DELAY);
}
});
}, 1000);
return; // Diğer kodları çalıştırma
}
if (current === NPC) {
npcTurn(); // aynen kalsın
} else {
// animasyon bittikten sonra iflas kontrolü yap
animateRoll(function () {
var vals = dice.map(function (d) {
return d.value;
});
if (!canMakeAnyScore(vals)) {
// aynı blok
npcBustFlow ? npcBustFlow() // NPC için ayrı fonksiyonun varsa
: playerBustFlow(); // ya da direkt mevcut iflas bloğun
}
});
}
}
/* --- NPC Basit AI --- */
// ► Kurallı AI’da kullanılacak geçici alan
var bestMove = null;
var bestMoveBank = false;
function npcTurn() {
// Oyunun bittiğini veya sıranın NPC’de olmadığını kontrol et
if (gameOver || current !== NPC) {
return;
}
/* Önce tüm zarları seçimsiz hâle getir ve güncelle */
var _iterator3 = _createForOfIteratorHelper2(dice),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var d = _step3.value;
d.selected = false;
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
updateDicePositions();
animateRoll(function () {
/* Zarlar durduktan sonra 1 sn bekle */
LK.setTimeout(function () {
// — reset —
bestMove = null;
bestMoveBank = false;
bestMoveScore = -Infinity;
LK.setTimeout(npcQuickDecision, NPC_STEP_DELAY); // <- 1 sn sonra
}, NPC_STEP_DELAY); // NPC_STEP_DELAY = 1000
});
}
/**
* Zar sayısına göre tablolaştırılmış kurallarla
* - hangi zarı seçeceğine
* - banklayıp banklamayacağına
* karar verir ve applyFinalDecision’ı tetikler.
*/
function npcQuickDecision() {
/* 0) Seçim bayraklarını sıfırla ─ animasyon hatalarını önler */
dice.forEach(function (d) {
return d.selected = false;
});
updateDicePositions();
// 0.a) Zar değerlerini oku
var vals = dice.map(function (d) {
return d.value;
});
var n = vals.length;
/* === 0.a) HOT-DICE kontrolü (öncelik) === */
var fullScore = calcScoreFarkle(vals);
var hotDice = fullScore.score > 0 && fullScore.used.length === vals.length;
if (hotDice) {
/* Zarları ŞİMDİ seçme — sadece kararı kaydet */
bestMove = {
combo: vals.slice(),
score: fullScore.score
};
bestMoveBank = false; // DEVAM
/* return yok! En alttaki “seçme bloğuna” akmaya devam edeceğiz */
}
/* Tek-zar‐devam ve banklama mantığına yalnızca hot-dice DEĞİLSE bak */
if (!hotDice) {
// ==== 1) Tek–zar DEVAM listesi ====
var sig = vals.slice().sort(function (a, b) {
return a - b;
}).filter(function (v) {
return v === 1 || v === 5;
}).join('');
var singleContinue = (CONTINUE_PATTERNS[n] || []).includes(sig);
/* ---------- YENİ EK ---------- */
var BANK_THRESHOLD = 400; // dilediğin rakam
var counts = Array(7).fill(0);
vals.forEach(function (v) {
return counts[v]++;
});
var hasTripleOrBetter = counts.some(function (c) {
return c >= 3;
}); // 2-2-2 gibi
// Elin puanı düşükse banklamak istemiyoruz
var best = bestScoringCombo(vals); // {combo, score}
var worthBanking = hasTripleOrBetter || best.score >= BANK_THRESHOLD;
// Liste kuralı devrede ama banklamaya değer bir durum varsa
if (singleContinue && worthBanking) {
singleContinue = false; // → else bloğuna gitsin
}
/* ---------- /YENİ EK ---------- */
if (singleContinue) {
// sadece 1 ya da 5'ten **birini** tut ve DEVAM et
var pickDie = vals.includes(1) ? 1 : 5;
bestMove = {
combo: [pickDie],
score: calcScoreFarkle([pickDie]).score
};
bestMoveBank = false; // DEVAM
} else {
// En iyi kombinasyon + BANK
bestMove = best; // az önce zaten hesapladık
bestMoveBank = true; // TAMAM
}
// 2) Kararı uygula
if (singleContinue) {
// Listede varsa sadece **TEK** zar tutulur
var pickDie = vals.includes(1) ? 1 : 5; // 1 öncelikli
var idx = vals.indexOf(pickDie);
bestMove = {
combo: [pickDie],
score: calcScoreFarkle([pickDie]).score
};
bestMoveBank = false; // DEVAM
} else {
// En iyi kombinasyon + BANK
best = bestScoringCombo(vals);
worthBanking = best.score >= 400; // eşiği istediğin gibi ayarla
if (singleContinue && worthBanking) {
singleContinue = false; // yüksek puan varsa bankla
}
// hiç puan getiren kombinasyon yoksa iflas
if (!best || best.score === 0 || !best.combo.length) {
npcBustFlow();
return;
}
bestMove = best;
bestMoveBank = true; // TAMAM
}
}
/* Eşik kuralı: temp + seçilen ≥ 1000 ise kesin bankla */
if (tempScores[NPC] + bestMove.score >= 1000) {
bestMoveBank = true; // zorunlu bank
}
// 3) Görsel güncellemeler + kararın uygulanması
updateDicePositions();
updateHUD();
/*********** TEKER TEKER SEÇME BLOĞU ***********/
// Hangi zarlar seçilecek? → npcSelectOrder
var npcSelectOrder = [];
var valsCopy = vals.slice(); // birazdan -1 ile işaretleyeceğiz
bestMove.combo.forEach(function (v) {
var i = valsCopy.indexOf(v);
if (i !== -1) {
npcSelectOrder.push(i);
valsCopy[i] = -1; // aynı zarı 2. kez bulma
}
});
var step = 0;
function selectNext() {
if (step < npcSelectOrder.length) {
var idx = npcSelectOrder[step++];
/* ses efekti */
var sfx = LK.getSound('zarSecmeSesi');
sfx && sfx.play();
dice[idx].selected = true;
updateDicePositions();
updateHUD();
/* 1 sn sonra bir sonraki zara geç */
LK.setTimeout(selectNext, NPC_STEP_DELAY);
} else {
/* Son zarı da seçtik → 1 sn sonra butona bas */
LK.setTimeout(function () {
// 1) Buton sesini GECİKME-siz çal
var btnSound = bestMoveBank ? 'tutVeTuruSonlandirSesi' // → TAMAM
: 'tutVeDevamEtSesi'; // → DEVAM
var s = LK.getSound(btnSound);
s && s.play();
LK.setTimeout(applyFinalDecision, 0);
}, 0); // ilk setTimeout’u 0 ms yap – ses anında gelsin
}
}
/* İlk seçimi başlat */
LK.setTimeout(selectNext, NPC_STEP_DELAY);
}
/**** NPC animasyon sonrası hamle ****/
function decideAndAct() {
// Hiç geçerli hamle yoksa veya hesaplama yetişmediyse => sıra geçsin
if (!bestMove || !bestMove.combo || !bestMove.combo.length) {
tempScores[NPC] = selectedScores[NPC] = 0; // güvenli sıfırlama
updateHUD();
endTurn();
return;
}
/* ------------------------------
* HOT-DICE ≠ OYUNU BİTİREN SKOR
* ------------------------------ */
var willWin = scores[NPC] // şu ana kadar banklı skor
+ tempScores[NPC] // tur içi birikmiş skor
+ bestMove.score // seçtiği kombinasyon skoru
>= TARGET_SCORE; // → hedefi geçiyor mu?
if (bestMove.combo.length === dice.length // hot-dice
&& !willWin) {
// ama bitirmiyorsa
bestMoveBank = false; // ► mutlaka devam et
}
// 8) Zarları adım adım seçip (görsel animasyon)
/* Eğer banklanacaksa, önce en yüksek skorlu komboyu seç */
if (bestMoveBank) {
if (lastCombos && lastCombos.length) {
bestMove = lastCombos.reduce(function (max, c) {
return c.score > max.score ? c : max;
}, bestMove);
}
}
/* npcSelectOrder dizisini hazırla */
var npcSelectOrder = [];
var used = [];
// Defensive: check bestMove and bestMove.combo before iterating
if (bestMove && bestMove.combo && Array.isArray(bestMove.combo)) {
for (var i = 0; i < dice.length; i++) {
var v = dice[i].value;
for (var j = 0; j < bestMove.combo.length; j++) {
if (!used[j] && bestMove.combo[j] === v) {
npcSelectOrder.push(i);
used[j] = true;
break;
}
}
}
}
var idxSel = 0;
function npcSelectNextDie() {
if (idxSel < npcSelectOrder.length) {
var _LK$getSound4;
var idx = npcSelectOrder[idxSel++];
var snd = dice[idx].selected ? 'zarBirakmaSesi' : 'zarSecmeSesi';
dice[idx].selected = true; // güvenli: hep seç
(_LK$getSound4 = LK.getSound(snd)) === null || _LK$getSound4 === void 0 || _LK$getSound4.play();
updateDicePositions();
updateHUD();
LK.setTimeout(npcSelectNextDie, NPC_STEP_DELAY);
return;
}
// Tüm zarlar seçildi → bank / devam kararı
/* Son zarı da seçtik → KISA bir nefes ver, sonra butona bas */
LK.setTimeout(function () {
/* 1) Buton sesi HEMEN çalsın */
var btnSound = bestMoveBank ? 'tutVeTuruSonlandirSesi' // TAMAM
: 'tutVeDevamEtSesi'; // DEVAM
var s = LK.getSound(btnSound);
s && s.play();
/* 2) Kararı uygula */
applyFinalDecision();
}, 300); // 300 ms’lik kısa gecikme — göz kırpma süresi
}
npcSelectNextDie();
}
/* --- Kazanan ekranı --- */
function showWinner() {
gameOver = true;
// Kazanma oranı güncellemesi
var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0;
var winGames = typeof storage.winGames === "number" ? storage.winGames : 0;
totalGames += 1;
if (current === PLAYER) {
winGames += 1;
// Seviye artır
if (typeof storage.level !== "number" || storage.level < 1) {
storage.level = 1;
}
storage.level += 1;
}
storage.totalGames = totalGames;
storage.winGames = winGames;
// Hedefi güncelle (her seviye +250)
if (typeof storage.level !== "number" || storage.level < 1) {
storage.level = 1;
}
var level = storage.level;
var dynamicTarget = 1000 + (level - 1) * 250;
// Lig görselini güncelle
function getLeagueAsset(totalGames, winGames) {
if (totalGames < 10) {
return "derecesizLigi";
}
var rate = totalGames > 0 ? Math.round(winGames / totalGames * 100) : 0;
if (rate <= 10) {
return "demirLigi";
}
if (rate <= 20) {
return "bronzLigi";
}
if (rate <= 30) {
return "gumusLigi";
}
if (rate <= 40) {
return "altinLigi";
}
if (rate <= 50) {
return "zumrutLigi";
}
if (rate <= 60) {
return "platinLigi";
}
if (rate <= 70) {
return "elmasLigi";
}
if (rate <= 80) {
return "ustaLigi";
}
if (rate <= 90) {
return "ustadLigi";
}
return "sampiyonlukLigi";
}
var leagueAssetId = getLeagueAsset(totalGames, winGames);
if (window.leagueBadge) {
if (window.leagueBadge._assetId !== leagueAssetId) {
var parent = window.leagueBadge.parent;
var idx = parent ? parent.getChildIndex(window.leagueBadge) : -1;
window.leagueBadge.destroy();
window.leagueBadge = LK.getAsset(leagueAssetId, {
anchorX: 0.5,
anchorY: 0,
width: 90,
height: 90
});
if (parent && idx >= 0) {
parent.addChildAt(window.leagueBadge, idx);
}
window.leagueBadge.x = 440;
window.leagueBadge.y = 20;
}
}
if (window.leagueBadge) {
window.leagueBadge._assetId = leagueAssetId;
}
// HUD'daki oranı, oyun sayısı, seviye ve hedefi hemen güncelle
if (window.winRateTxt) {
var winRateStr = totalGames > 0 ? "%" + Math.round(winGames / totalGames * 100) : "∅";
var oyunSayisiStr = totalGames > 0 ? totalGames : "0";
window.winRateTxt.setText("Zafer Oranı: " + winRateStr + " | Maç Sayısı: " + oyunSayisiStr + " | Seviye: " + level);
}
if (scoreTableRows && scoreTableRows[1]) {
scoreTableRows[1].setText("Ana Skor: " + scores[PLAYER] + " | " + dynamicTarget + " | " + "Ana Skor: " + scores[NPC]);
}
var winnerText = current === PLAYER ? 'Kazandın!' : 'Kaybettin...';
clearGameState();
showGameOverScreen(winnerText);
}
/* --- Buton Olayları --- */
rollBtn.down = function () {
if (gameOver || current !== PLAYER) {
return;
}
// Tüm zarlar seçili (hot-dice) ise önce puanı uygula
var hotDice = selectedDiceIdx.length === dice.length;
if (hotDice) {
// Skoru ekle, yeni 6 zarı hazırla
keepAndContinue(); // burada resetDice(6) zaten çağrılıyor
// Şimdi yeni zarları döndür
animateRoll(null, false); // callback gerekmez, çünkü puan uygulandı
} else {
var _LK$getSound3;
(_LK$getSound3 = LK.getSound('tutVeDevamEtSesi')) === null || _LK$getSound3 === void 0 || _LK$getSound3.play();
animateRoll(keepAndContinue, false);
}
};
bankBtn.down = function () {
if (current === PLAYER) {
var tutTuruSonlandirSesi = LK.getSound && LK.getSound('tutVeTuruSonlandirSesi');
if (tutTuruSonlandirSesi && tutTuruSonlandirSesi.play) {
tutTuruSonlandirSesi.play();
}
keepAndEndTurn();
}
};
// PAS GEÇ butonu olayı
passBtn.down = function () {
if (current === PLAYER && !gameOver) {
var pasButonuSesi = LK.getSound && LK.getSound('pasButonuSesi');
if (pasButonuSesi && pasButonuSesi.play) {
pasButonuSesi.play();
}
// Sıramı pas geç, turu rakibe geçir
tempScores[current] = 0;
selectedScores[current] = 0;
turnScore = 0;
updateHUD();
saveGameState(); // Pas geçince kaydet
endTurn();
}
};
/* --- Başlat --- */
function startGame() {
// Try to restore game state if available and not game over
if (typeof storage !== "undefined" && storage && storage.tempGameState && storage.tempGameState.gameOver !== true) {
if (restoreGameState()) {
// Oyun arkaplanını güncelle (restoreGameState'de resetDice çağrıldı, burada tekrar ekle)
if (game._oyunBg) {
game._oyunBg.destroy();
game._oyunBg = null;
}
var oyunBg = LK.getAsset('oyunEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
game.addChildAt(oyunBg, 0);
game._oyunBg = oyunBg;
updateHUD();
var ilkSenBasliyorsunSesi = LK.getSound && LK.getSound('ilkSenBasliyorsunSesi');
if (ilkSenBasliyorsunSesi && ilkSenBasliyorsunSesi.play) {
ilkSenBasliyorsunSesi.play();
}
// Zar animasyonu oynatma (isteğe bağlı, restore sonrası)
animateRoll();
return;
}
}
// Normal yeni oyun başlat
scores = [0, 0];
tempScores = [0, 0];
selectedScores = [0, 0];
turnScore = 0;
turnNumber = 1;
current = NPC;
gameOver = false;
// Set oyunEkraniArkaplani as background
if (game._oyunBg) {
game._oyunBg.destroy();
game._oyunBg = null;
}
var oyunBg = LK.getAsset('oyunEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
game.addChildAt(oyunBg, 0);
game._oyunBg = oyunBg;
// Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor
resetDice(6);
updateHUD();
// İlk oyun başlangıcında rakip başlıyorsa özel sesi çal
var ilkRakipBasliyorSesi = LK.getSound && LK.getSound('ilkRakipBasliyorSesi');
if (ilkRakipBasliyorSesi && ilkRakipBasliyorSesi.play) {
ilkRakipBasliyorSesi.play();
} else {
var rakipSesi = LK.getSound && LK.getSound('rakibinSirasiSesi');
rakipSesi && rakipSesi.play();
}
npcTurn();
}
// --- Ana Menü ve Oyun Sonu Ekranları ---
var mainMenuContainer = null;
var gameOverContainer = null;
// Oyuncu adı global değişkeni
var playerName = storage.playerName || null;
// Oyuncu adı giriş penceresi için referanslar
var playerNameDialog = null;
// Hesabı Sıfırla onay penceresi
function showResetAccountDialog() {
// Önce varsa eski dialog'u kaldır
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
playerNameDialog = new Container();
playerNameDialog.width = 900;
playerNameDialog.height = 600;
playerNameDialog.x = W / 2 - 450;
playerNameDialog.y = H / 2 - 300;
// Arkaplan kutusu
var bg = LK.getAsset('loadingBgRed', {
anchorX: 0,
anchorY: 0,
color: 0x222222
});
playerNameDialog.addChild(bg);
// Başlık
var info = new Text2("Bu işlemden emin misin?", {
size: 54,
fill: 0xFFE066
});
info.anchor.set(0.5, 0);
info.x = 450;
info.y = 60;
playerNameDialog.addChild(info);
// Input kutusu
var resetInput = new Text2("", {
size: 80,
fill: "#fff",
background: "#444",
padding: 24
});
resetInput.anchor.set(0.5, 0);
resetInput.x = 450;
resetInput.y = info.y + 70;
resetInput.interactive = true;
resetInput.text = "";
playerNameDialog.addChild(resetInput);
// Sanal klavye (yalnızca harfler, DEL, GERİ, TAMAM)
var isCaps = true;
var maxLen = 8;
var keyboardRows = [["E", "V", "E", "T"], ["DEL", "GERI", "TAMAM"]];
var keyW = 170,
keyH = 170,
keyGap = 20;
var kbStartX = (900 - (4 * keyW + 3 * keyGap)) / 2;
var kbStartY = 320;
for (var row = 0; row < keyboardRows.length; row++) {
for (var col = 0; col < keyboardRows[row].length; col++) {
(function (row, col) {
var k = keyboardRows[row][col];
var isWideKey = k === "GERI" || k === "TAMAM";
var thisKeyW = isWideKey ? 360 : keyW;
var thisKeyH = keyH;
var keyBtn = new Container();
keyBtn.attachAsset('klavyeTusuGorseli', {
anchorX: 0.5,
anchorY: 0.5,
width: thisKeyW,
height: thisKeyH
});
var labelText = "";
if (k === "DEL") {
labelText = "Sil";
} else if (k === "GERI") {
labelText = "Geri";
} else if (k === "TAMAM") {
labelText = "Tamam";
} else {
labelText = k;
}
var keyTxt = new Text2(labelText, {
size: 40,
fill: "#fff"
});
keyBtn.label = keyTxt;
keyTxt.anchor.set(0.5, 0.5);
keyBtn.addChild(keyTxt);
// Konumlandırma
var sumW = 0;
if (row === 1) {
for (var c = 0; c < col; c++) {
sumW += keyboardRows[row][c] === "GERI" || keyboardRows[row][c] === "TAMAM" ? 360 + keyGap : keyW + keyGap;
}
keyBtn.x = kbStartX + sumW + thisKeyW / 2;
} else {
keyBtn.x = kbStartX + col * (keyW + keyGap) + thisKeyW / 2;
}
keyBtn.y = kbStartY + row * (keyH + keyGap) + thisKeyH / 2;
keyBtn.interactive = true;
keyBtn.down = function () {
var klavyeTusunaBasmaSesi = LK.getSound && LK.getSound('klavyeTusunaBasmaSesi');
if (klavyeTusunaBasmaSesi && klavyeTusunaBasmaSesi.play) {
klavyeTusunaBasmaSesi.play();
}
// DEL tuşu
if (k === "DEL") {
resetInput.text = resetInput.text.slice(0, -1);
resetInput.setText(resetInput.text);
return;
}
// GERİ tuşu
if (k === "GERI") {
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
return;
}
// TAMAM tuşu
if (k === "TAMAM") {
var val = resetInput.text.trim();
if (val.toLocaleUpperCase('tr-TR') === "EVET") {
// Tüm verileri sıfırla
storage.playerName = null;
storage.totalGames = 0;
storage.winGames = 0;
storage.zarStats = Object.assign({}, defaultZarStats);
zarStats = storage.zarStats; // global zarStats referansını da güncelle
refreshZarStatsTxt(); // görseli de hemen güncelle
storage.tempGameState = null;
if (window.zarStatsTxt) {
window.zarStatsTxt.setText("zar2 = 0 zar3 = 0 zar4 = 0 zar5 = 0 zar6 = 0 zar1 = 0 zarJoker = 0");
}
// Diğer olası veriler de burada sıfırlanabilir
// Dialog'u kapat
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
// Ana menüyü güncelle (isim sorulacak)
showMainMenu();
}
return;
}
// Harf tuşları
if (resetInput.text.length < maxLen && k.length === 1) {
var harf = isCaps ? k.toLocaleUpperCase('tr-TR') : k.toLocaleLowerCase('tr-TR');
resetInput.text += harf;
resetInput.setText(resetInput.text);
}
};
keyBtn._isKeyBtn = true;
keyBtn._row = row;
keyBtn._col = col;
playerNameDialog.addChild(keyBtn);
})(row, col);
}
}
// Ekrana ekle
game.addChild(playerNameDialog);
}
// Oyuncu adı giriş penceresini göster
function showPlayerNameDialog(onComplete) {
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
playerNameDialog = new Container();
playerNameDialog.width = 900;
playerNameDialog.height = 600;
playerNameDialog.x = W / 2 - 450;
playerNameDialog.y = H / 2 - 300;
// Arkaplan kutusu
var bg = LK.getAsset('loadingBgRed', {
anchorX: 0,
anchorY: 0,
color: 0x222222
});
playerNameDialog.addChild(bg);
// Başlık
var title = new Text2("Oyuncu Adı", {
size: 80,
fill: "#fff"
});
title.anchor.set(0.5, 0);
title.x = 450;
title.y = 40;
playerNameDialog.addChild(title);
// Oyuncu adı başlığının hemen altına, 15px aşağıda gösterilecek şekilde input kutusu ve yazı
var playerNameInput = new Text2("", {
size: 80,
fill: "#fff",
background: "#444",
padding: 24
});
playerNameInput.anchor.set(0.5, 0);
// Oyuncu Adı başlığının y'si 40, yüksekliği 80. 15px aşağıda olacak şekilde:
playerNameInput.x = 450;
playerNameInput.y = 40 + 80 + 15; // title.y + title.height + 15
playerNameInput.interactive = true;
playerNameInput.text = "";
playerNameDialog.addChild(playerNameInput);
// --- Sanal klavye: çoklu karakter, boşluk, caps lock desteği ve özel arkaplanlar ---
var isCaps = true;
var maxLen = 24;
// Klavye tuşları ve ek fonksiyon tuşları aynı sırada olacak şekilde
var keyboardRows = [["A", "B", "C", "Ç", "D", "E", "F", "G", "Ğ"], ["H", "I", "İ", "J", "K", "L", "M", "N", "O"], ["Ö", "P", "R", "S", "Ş", "T", "U", "Ü", "V"], ["Y", "Z", "SPACE", "DEL", "CAPS", "GERI", "TAMAM"]];
// Klavye arkaplanı
var keyboardBg = LK.getAsset('klavyeArkaplani', {
anchorX: 0,
anchorY: 0,
x: -415,
y: 300
});
playerNameDialog.addChild(keyboardBg);
// Tuş boyutları ve konumlar
var keyW = 170,
keyH = 170,
keyGap = 20;
var keysPerRow = keyboardRows[0].length; // 9
var kbStartX = (900 - (keysPerRow * keyW + (keysPerRow - 1) * keyGap)) / 2;
var kbStartY = 320;
// Tuşları sırayla çiz
for (var row = 0; row < keyboardRows.length; row++) {
for (var col = 0; col < keyboardRows[row].length; col++) {
(function (row, col) {
var k = keyboardRows[row][col];
// GERI ve TAMAM tuşları için özel boyut
var isWideKey = k === "GERI" || k === "TAMAM";
var thisKeyW = isWideKey ? 360 : keyW;
var thisKeyH = keyH;
var keyBtn = new Container();
// Tüm tuşlar aynı görselde, sadece label farklı
keyBtn.attachAsset('klavyeTusuGorseli', {
anchorX: 0.5,
anchorY: 0.5,
width: thisKeyW,
height: thisKeyH
});
// Label
var labelText = "";
if (k === "SPACE") {
labelText = "Boşluk";
} else if (k === "DEL") {
labelText = "Sil";
} else if (k === "CAPS") {
labelText = isCaps ? "Caps: A" : "Caps: a";
} else if (k === "GERI") {
labelText = "Geri";
} else if (k === "TAMAM") {
labelText = "Tamam";
} else {
labelText = isCaps ? k : k.toLowerCase();
}
var keyTxt = new Text2(labelText, {
size: 40,
fill: "#fff"
});
keyBtn.label = keyTxt; // <-- etiket referansı
keyTxt.anchor.set(0.5, 0.5);
keyBtn.addChild(keyTxt);
// Konumlandırma
// GERI ve TAMAM tuşları için x pozisyonunu ayarlamak gerekiyor
var xOffset = 0;
if (isWideKey) {
// GERI ve TAMAM tuşları son satırda, 3. ve 4. sütun
// 4. satırda: ["Y", "Z", "SPACE", "DEL", "CAPS", "GERI", "TAMAM"]
// GERI: col==5, TAMAM: col==6
// 5. ve 6. tuşun başı, önceki tuşların toplam genişliği + gap'leri kadar sağda olmalı
// 0-4 arası normal, 5 ve 6 geniş
// 0-4: keyW, 5-6: 260
// GERI'nin x'i: kbStartX + (5 * (keyW + keyGap)) + 260/2 + (col-5)*((260-keyW)/2)
// TAMAM'ın x'i: kbStartX + (5 * (keyW + keyGap)) + (1 * (260 + keyGap)) + 260/2
// Hesaplamayı daha basit yapalım:
// Her tuşun başı: kbStartX + sum(width+gap) + width/2
// 0-4: keyW, 5-6: 260
var sumW = 0;
for (var c = 0; c < col; c++) {
if (keyboardRows[row][c] === "GERI" || keyboardRows[row][c] === "TAMAM") {
sumW += 360 + keyGap;
} else {
sumW += keyW + keyGap;
}
}
keyBtn.x = kbStartX + sumW + thisKeyW / 2;
} else {
keyBtn.x = kbStartX + col * (keyW + keyGap) + thisKeyW / 2;
}
keyBtn.y = kbStartY + row * (keyH + keyGap) + thisKeyH / 2;
keyBtn.interactive = true;
keyBtn.down = function () {
var klavyeTusunaBasmaSesi = LK.getSound && LK.getSound('klavyeTusunaBasmaSesi');
if (klavyeTusunaBasmaSesi && klavyeTusunaBasmaSesi.play) {
klavyeTusunaBasmaSesi.play();
}
// DEL tuşu
if (k === "DEL") {
playerNameInput.text = playerNameInput.text.slice(0, -1);
playerNameInput.setText(playerNameInput.text);
return;
}
// SPACE tuşu
if (k === "SPACE") {
if (playerNameInput.text.length < maxLen) {
playerNameInput.text = playerNameInput.text + " ";
playerNameInput.setText(playerNameInput.text);
}
return;
}
// CAPS tuşu
if (k === "CAPS") {
isCaps = !isCaps;
playerNameDialog.children.forEach(function (btn) {
if (!btn._isKeyBtn || !btn.label) {
return;
}
var code = keyboardRows[btn._row][btn._col];
if (code === "CAPS") {
btn.label.setText(isCaps ? "Caps: A" : "Caps: a");
} else if (code.length === 1) {
// Harf tuşu
btn.label.setText(isCaps ? code.toLocaleUpperCase("tr-TR") : code.toLocaleLowerCase("tr-TR"));
}
});
return;
}
// GERİ tuşu
if (k === "GERI") {
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
return;
}
// TAMAM tuşu
if (k === "TAMAM") {
var name = playerNameInput.text.trim();
if (name.length < 2) {
return;
}
playerName = name;
storage.playerName = name;
if (playerNameDialog) {
playerNameDialog.destroy();
playerNameDialog = null;
}
if (typeof onComplete === "function") {
onComplete();
}
return;
}
// Harf tuşları
if (playerNameInput.text.length < maxLen && k.length === 1) {
var harf = isCaps ? k.toLocaleUpperCase('tr-TR') // büyük harf modu
: k.toLocaleLowerCase('tr-TR'); // küçük harf modu
playerNameInput.text += harf;
playerNameInput.setText(playerNameInput.text);
}
};
// Tuşun tipini sakla (caps güncellemesi için)
keyBtn._isKeyBtn = true;
keyBtn._row = row;
keyBtn._col = col;
playerNameDialog.addChild(keyBtn);
})(row, col);
}
}
// Ekrana ekle
game.addChild(playerNameDialog);
}
// Ana Menü Ekranını Göster
function showMainMenu() {
// Temizle
if (mainMenuContainer) {
mainMenuContainer.destroy();
mainMenuContainer = null;
}
if (gameOverContainer) {
gameOverContainer.destroy();
gameOverContainer = null;
}
// Oyun alanını temizle
if (diceGroup) {
diceGroup.destroy();
diceGroup = null;
}
if (selectedDiceGroup) {
selectedDiceGroup.destroy();
selectedDiceGroup = null;
}
dice = [];
selectedDiceIdx = [];
// Skor tablosunu gizle
for (var i = 0; i < scoreTableRows.length; i++) {
if (scoreTableRows[i]) {
scoreTableRows[i].visible = false;
}
}
if (turnTxt) {
turnTxt.visible = false;
}
// Ana menüde puan tablosu ve açıklama görünmesin
if (window._farkleScoreTable) {
window._farkleScoreTable.visible = false;
}
if (window._farkleScoreInfoTxt) {
window._farkleScoreInfoTxt.visible = false;
}
// Zar istatistik satırını gizle (sadece oyun ekranında görünür)
if (window.zarStatsRow) {
window.zarStatsRow.visible = false;
}
// --- Kazanma Oranı etiketi ---
if (!window.winRateTxt) {
// daha önce hiç oluşturulmamışsa burada yarat
window.winRateTxt = new Text2("", {
size: 48,
fill: '#ffe066',
fontWeight: 'bold'
});
window.winRateTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(window.winRateTxt);
}
// değerleri güncelle ve görünür yap
var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0;
var winGames = typeof storage.winGames === "number" ? storage.winGames : 0;
var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1;
var oran = totalGames > 0 ? Math.round(winGames / totalGames * 100) + "%" : "∅";
var oyunStr = totalGames > 0 ? totalGames : "0";
window.winRateTxt.setText("Zafer Oranı: " + oran + " | Maç Sayısı: " + oyunStr + " | Seviye: " + level);
window.winRateTxt.x = 0;
window.winRateTxt.y = 20;
window.winRateTxt.visible = true;
// Butonları pasifleştir
rollBtn.visible = false;
bankBtn.visible = false;
if (typeof passBtn !== "undefined") {
passBtn.visible = false;
}
// Remove oyun ekranı arkaplanı if exists
if (game._oyunBg) {
game._oyunBg.destroy();
game._oyunBg = null;
}
// Ana Menü Container
mainMenuContainer = new Container();
mainMenuContainer.width = W;
mainMenuContainer.height = H;
// Arkaplan (anaMenuEkraniArkaplani)
var bg = LK.getAsset('anaMenuEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
mainMenuContainer.addChild(bg);
// Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor
// "Oyunu Başlat" Butonu
var startBtn = new Container();
startBtn.attachAsset('oyunuBaslatButonuGorseli', {
anchorX: 0.5,
anchorY: 0.5
});
var startTxt = new Text2('Oyunu Başlat', {
size: 124,
fill: '#fff'
});
startTxt.anchor.set(0.5, 0.5);
startTxt.y = 40;
startBtn.addChild(startTxt);
startBtn.x = W / 2;
startBtn.y = H / 2 - 230;
startBtn.interactive = true;
startBtn.down = function () {
var oyunuBaslatButonuSesi = LK.getSound && LK.getSound('oyunuBaslatButonuSesi');
if (oyunuBaslatButonuSesi && oyunuBaslatButonuSesi.play) {
oyunuBaslatButonuSesi.play();
}
// Oyuncu adı yoksa önce sor, varsa direkt başlat
if (!storage.playerName) {
showPlayerNameDialog(function () {
hideMainMenu();
startGame();
});
} else {
playerName = storage.playerName;
hideMainMenu();
startGame();
}
};
mainMenuContainer.addChild(startBtn);
// --- HESABI SIFIRLA BUTONU ---
// Buton görseli ve metni
var sifirlaBtn = new Container();
sifirlaBtn.attachAsset('tamamButonuGorseli', {
anchorX: 0.5,
anchorY: 0.5
});
var sifirlaTxt = new Text2('Hesabı Sıfırla', {
size: 124,
fill: '#fff'
});
sifirlaTxt.anchor.set(0.5, 0.5);
sifirlaTxt.y = 40;
sifirlaBtn.addChild(sifirlaTxt);
// Konum: Başlat butonunun hemen altında, arada 80px boşluk
sifirlaBtn.x = W / 2;
sifirlaBtn.y = H / 2 + 230;
sifirlaBtn.interactive = true;
sifirlaBtn.down = function () {
var hesabiSifirlaButonuSesi = LK.getSound && LK.getSound('hesabiSifirlaButonuSesi');
if (hesabiSifirlaButonuSesi && hesabiSifirlaButonuSesi.play) {
hesabiSifirlaButonuSesi.play();
}
// Sıfırlama onay penceresini göster
showResetAccountDialog();
};
mainMenuContainer.addChild(sifirlaBtn);
game.addChild(mainMenuContainer);
// --- Instagram ve Erken Erişim Yazıları (sadece ana menüde) ---
if (!window.instaText) {
// Instagram: ugurcanyardim_
var instaText = new Text2("Instagram: ugurcanyardim_", {
size: 64,
fill: 0xFF0000,
// kırmızı
fontWeight: "bold"
});
instaText.anchor.set(0.5, 0);
window.instaText = instaText;
// Beta text
var betaText = new Text2("Erken Erişim", {
size: 64,
fill: 0xFFE066,
// sarı
fontWeight: "bold"
});
betaText.anchor.set(0, 0); // left-top
window.betaText = betaText;
}
// Pozisyonları langBtn'a göre ayarla
// langBtn yoksa, referans noktası olarak startBtn kullan
var refBtn = typeof langBtn !== "undefined" && langBtn ? langBtn : startBtn;
window.instaText.x = refBtn.x - 586;
window.instaText.y = refBtn.y + 1500;
window.betaText.x = window.instaText.x + 1194;
window.betaText.y = window.instaText.y;
// Sadece ana menüde göster
window.instaText.visible = true;
window.betaText.visible = true;
mainMenuContainer.addChild(window.instaText);
mainMenuContainer.addChild(window.betaText);
clearGameState();
// --- Konfeti efektini ve parçacıklarını temizle (ana menüye dönünce) ---
if (confettiInterval) {
LK.clearInterval(confettiInterval);
confettiInterval = null;
}
for (var i = 0; i < confettiParticles.length; i++) {
if (confettiParticles[i] && confettiParticles[i].parent) {
confettiParticles[i].parent.removeChild(confettiParticles[i]);
}
}
confettiParticles = [];
// Olası update fonksiyonunu da temizle
if (gameOverContainer && gameOverContainer.update) {
gameOverContainer.update = null;
}
}
// Ana Menü Ekranını Gizle
function hideMainMenu() {
if (mainMenuContainer) {
mainMenuContainer.destroy();
mainMenuContainer = null;
}
// Skor tablosunu göster
for (var i = 0; i < scoreTableRows.length; i++) {
if (scoreTableRows[i]) {
scoreTableRows[i].visible = true;
}
}
if (turnTxt) {
turnTxt.visible = true;
}
// Oyun ekranına dönünce puan tablosunu ve açıklamayı tekrar göster
if (window._farkleScoreTable) {
window._farkleScoreTable.visible = true;
}
if (window._farkleScoreInfoTxt) {
window._farkleScoreInfoTxt.visible = true;
}
// Butonları göster
rollBtn.visible = true;
bankBtn.visible = true;
if (typeof passBtn !== "undefined") {
passBtn.visible = true;
}
// Zar istatistik satırını göster (sadece oyun ekranında)
if (window.zarStatsRow) {
window.zarStatsRow.visible = true;
}
}
// Oyun Sonu Ekranını Göster
function showGameOverScreen(winnerText) {
// Temizle
if (gameOverContainer) {
gameOverContainer.destroy();
gameOverContainer = null;
}
if (mainMenuContainer) {
mainMenuContainer.destroy();
mainMenuContainer = null;
}
// Oyun alanını temizle
if (diceGroup) {
diceGroup.destroy();
diceGroup = null;
}
if (selectedDiceGroup) {
selectedDiceGroup.destroy();
selectedDiceGroup = null;
}
dice = [];
selectedDiceIdx = [];
// Skor tablosunu gizle
for (var i = 0; i < scoreTableRows.length; i++) {
if (scoreTableRows[i]) {
scoreTableRows[i].visible = false;
}
}
if (turnTxt) {
turnTxt.visible = false;
}
// Oyun sonu ekranında puan tablosu görünmesin, sadece oyun ekranında görünsün
if (window._farkleScoreTable) {
window._farkleScoreTable.visible = false;
}
if (window._farkleScoreInfoTxt) {
window._farkleScoreInfoTxt.visible = false;
}
// Zar istatistik satırını gizle (sadece oyun ekranında görünür)
if (window.zarStatsRow) {
window.zarStatsRow.visible = false;
}
// Kazanma oranı ve oyun sayısı yazısı oyun sonu ekranında da görünür olsun
if (window.winRateTxt) {
window.winRateTxt.visible = true;
window.winRateTxt.x = 0;
window.winRateTxt.y = 20;
}
// Butonları pasifleştir
rollBtn.visible = false;
bankBtn.visible = false;
if (typeof passBtn !== "undefined") {
passBtn.visible = false;
}
// Remove oyun ekranı arkaplanı if exists
if (game._oyunBg) {
game._oyunBg.destroy();
game._oyunBg = null;
}
clearGameState();
// Oyun Sonu Container
gameOverContainer = new Container();
gameOverContainer.width = W;
gameOverContainer.height = H;
// Arkaplan (oyunSonuEkraniArkaplani)
var bg = LK.getAsset('oyunSonuEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
gameOverContainer.addChild(bg);
// Oyun sonunda kazanan/kaybeden SFX çal
if (typeof current !== "undefined") {
if (current === PLAYER) {
var senKazandinSesi = LK.getSound && LK.getSound('senKazandinSesi');
if (senKazandinSesi && senKazandinSesi.play) {
senKazandinSesi.play();
}
} else if (current === NPC) {
var kaybettinSesi = LK.getSound && LK.getSound('kaybettinSesi');
if (kaybettinSesi && kaybettinSesi.play) {
kaybettinSesi.play();
}
}
}
// Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor
// Kazanan/Kaybeden Metni
var resultTxt = new Text2(winnerText || 'Oyun Bitti', {
size: 140,
fill: '#fff'
});
resultTxt.anchor.set(0.5, 0.5);
resultTxt.x = W / 2;
resultTxt.y = H / 2 - 200;
gameOverContainer.addChild(resultTxt);
// "Ana Menüye Dön" Butonu
var menuBtn = new Container();
menuBtn.attachAsset('anaMenuyeDonButonuGorseli', {
anchorX: 0.5,
anchorY: 0.5
});
var menuTxt = new Text2('Ana Menüye Dön', {
size: 60,
fill: '#fff'
});
menuTxt.anchor.set(0.5, 0.5);
menuTxt.y = 25;
menuBtn.addChild(menuTxt);
menuBtn.x = W / 2;
menuBtn.y = H / 2;
menuBtn.interactive = true;
menuBtn.down = function () {
var anaMenuyeDonButonuSesi = LK.getSound && LK.getSound('anaMenuyeDonButonuSesi');
if (anaMenuyeDonButonuSesi && anaMenuyeDonButonuSesi.play) {
anaMenuyeDonButonuSesi.play();
}
hideGameOverScreen();
showMainMenu();
};
gameOverContainer.addChild(menuBtn);
game.addChild(gameOverContainer);
// --- Konfeti Efekti: Sadece oyuncu kazandıysa başlat ---
if (typeof current !== "undefined" && current === PLAYER) {
// Önce varsa eski konfeti efektini temizle
if (confettiInterval) {
LK.clearInterval(confettiInterval);
confettiInterval = null;
}
// Tüm eski konfeti parçacıklarını temizle
for (var i = 0; i < confettiParticles.length; i++) {
if (confettiParticles[i] && confettiParticles[i].parent) {
confettiParticles[i].parent.removeChild(confettiParticles[i]);
}
}
confettiParticles = [];
// Konfeti efektini başlat: her 80ms'de yeni parçacık ekle
confettiInterval = LK.setInterval(function () {
// Her seferinde 2-4 yeni konfeti ekle
var count = 2 + Math.floor(Math.random() * 3);
for (var j = 0; j < count; j++) {
var confetti = new ConfettiParticle();
gameOverContainer.addChild(confetti);
confettiParticles.push(confetti);
}
}, 80);
// Konfeti parçacıklarını güncellemek için gameOverContainer.update fonksiyonu
gameOverContainer.update = function () {
// Tüm konfeti parçacıklarını güncelle
for (var i = confettiParticles.length - 1; i >= 0; i--) {
var c = confettiParticles[i];
if (c && !c._destroyed && typeof c.update === "function") {
c.update();
}
// Yok edilenleri diziden çıkar
if (c._destroyed) {
confettiParticles.splice(i, 1);
}
}
};
} else {
// Kazanmadıysan konfeti efektini başlatma, varsa temizle
if (confettiInterval) {
LK.clearInterval(confettiInterval);
confettiInterval = null;
}
for (var i = 0; i < confettiParticles.length; i++) {
if (confettiParticles[i] && confettiParticles[i].parent) {
confettiParticles[i].parent.removeChild(confettiParticles[i]);
}
}
confettiParticles = [];
if (gameOverContainer.update) {
gameOverContainer.update = null;
}
}
}
// Oyun Sonu Ekranını Gizle
function hideGameOverScreen() {
if (gameOverContainer) {
gameOverContainer.destroy();
gameOverContainer = null;
}
// Skor tablosunu göster
for (var i = 0; i < scoreTableRows.length; i++) {
if (scoreTableRows[i]) {
scoreTableRows[i].visible = true;
}
}
if (turnTxt) {
turnTxt.visible = true;
}
// Oyun ekranına dönünce puan tablosunu tekrar göster
if (window._farkleScoreTable) {
window._farkleScoreTable.visible = true;
}
if (window._farkleScoreInfoTxt) {
window._farkleScoreInfoTxt.visible = true;
}
// Butonları göster
rollBtn.visible = true;
bankBtn.visible = true;
if (typeof passBtn !== "undefined") {
passBtn.visible = true;
}
// Zar istatistik satırını göster (sadece oyun ekranında)
if (window.zarStatsRow) {
window.zarStatsRow.visible = true;
}
}
// --- Kazanan ekranı override ---
// Yükleme ekranı için sınıf ve gösterme fonksiyonu
var loadingContainer = null;
var loadingTimeout = null;
// Tween plugin import
// Yükleme ekranını göster
function showLoadingScreen() {
// First, create the main menu in the background so resources can load
showMainMenu();
// Hide winRateTxt during loading screen
if (window.winRateTxt) {
window.winRateTxt.visible = false;
}
// Müzik yükleme ekranında başlamasın, sadece loading kalkınca başlatacağız
// (Burada playMusic çağrısı kaldırıldı)
// Temizle
if (loadingContainer) {
loadingContainer.destroy();
loadingContainer = null;
}
loadingContainer = new Container();
loadingContainer.width = W;
loadingContainer.height = H;
// Yükleme ekranı arkaplanı
var bg = LK.getAsset('yuklemeEkraniArkaplani', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: W,
height: H
});
loadingContainer.addChild(bg);
// Novatek logosu (ortada üstte)
var logo = LK.getAsset('novatekLogosu', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1050
});
loadingContainer.addChild(logo);
// "Loading..." yazısı
var loadingTxt = new Text2('Yükleniyor...', {
size: 90,
fill: '#fff'
});
loadingTxt.anchor.set(0.5, 0.5);
loadingTxt.x = 1024;
loadingTxt.y = 1366;
loadingContainer.addChild(loadingTxt);
// Alt açıklama yazısı
var infoTxt = new Text2("En iyi oyun deneyimi için lütfen oyunun grafik ve ses kaynakları tamamen yüklenene kadar bekleyin. Unutmayın ki insanların %99'u büyük kazanamadan hemen önce oyunu bırakıyor! %1'e girebilecek misiniz?", {
size: 36,
fill: '#fff',
wordWrap: true,
wordWrapWidth: 1800,
align: 'center'
});
infoTxt.anchor.set(0.5, 0);
infoTxt.x = 1024;
infoTxt.y = 1460;
loadingContainer.addChild(infoTxt);
// Dönen yükleme çubuğu
var spinner = LK.getAsset('yuklemeCubugu', {
anchorX: 0.5,
anchorY: 0.5,
x: W / 2,
y: infoTxt.y + infoTxt.height + 120
});
loadingContainer.addChild(spinner);
// Spinner animasyonu (dönme)
spinner.rotation = 0;
var _spinTween = function spinTween() {
tween(spinner, {
rotation: spinner.rotation + Math.PI * 2
}, {
duration: 1200,
easing: tween.linear,
onFinish: _spinTween
});
};
_spinTween();
// Add loading screen on top of main menu
game.addChild(loadingContainer);
// 10 saniye sonra loading ekranını kaldır (ana menü zaten gösteriliyor)
loadingTimeout = LK.setTimeout(function () {
if (loadingContainer) {
loadingContainer.destroy();
loadingContainer = null;
}
// Show winRateTxt after loading screen is removed
if (window.winRateTxt) {
window.winRateTxt.visible = true;
}
// Ana menü zaten gösteriliyor, sadece loading overlay'ini kaldırıyoruz
// Müzik burada başlatılır, sadece bir kez ve döngüde
LK.playMusic('oyunEkraniMuzigi', {
loop: true
});
}, 10000);
}
// Oyun başında yükleme ekranını göster
showLoadingScreen();
/* --- Responsive HUD --- */
if (!window._frvr_gui_resize_hooked) {
window._frvr_gui_resize_hooked = true;
LK.on('resize', function () {
var centerX = W / 2; // 2048/2 = 1024, ekranın tam ortası
for (var i = 0; i < scoreTableRows.length; i++) {
if (scoreTableRows[i]) {
scoreTableRows[i].x = centerX;
}
}
if (turnTxt) {
turnTxt.x = centerX;
}
});
}
// --- Fix: Define npcBustFlow for NPC bust handling ---
function npcBustFlow() {
// Show red flash and 'İflas!' text for NPC bust
LK.effects.flashScreen(0xff0000, 1200);
var iflasTxt = new Text2('İflas!', {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
iflasTxt.x = W / 2;
iflasTxt.y = H / 2;
iflasTxt.alpha = 1;
game.addChild(iflasTxt);
// Play NPC bust sound
var iflasRakipSesi = LK.getSound && LK.getSound('iflasRakipSesi');
if (iflasRakipSesi && iflasRakipSesi.play) {
iflasRakipSesi.play();
}
LK.setTimeout(function () {
tween(iflasTxt, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
if (iflasTxt && iflasTxt.parent) {
iflasTxt.parent.removeChild(iflasTxt);
}
tempScores[NPC] = selectedScores[NPC] = turnScore = 0;
updateHUD();
LK.setTimeout(endTurn, BUST_PASS_DELAY);
}
});
}, 1000);
} ===================================================================
--- original.js
+++ change.js
@@ -1383,9 +1383,9 @@
anchorY: 0
});
LK.gui.top.addChild(window.leagueBadge);
// Skor tablosunun sağında, ortalanmış şekilde konumlandır
- window.leagueBadge.x = 560;
+ window.leagueBadge.x = 580;
window.leagueBadge.y = 75;
} else {
// Sadece asset değişirse güncelle
if (window.leagueBadge._assetId !== leagueAssetId) {
@@ -2309,9 +2309,9 @@
});
if (parent && idx >= 0) {
parent.addChildAt(window.leagueBadge, idx);
}
- window.leagueBadge.x = 420;
+ window.leagueBadge.x = 440;
window.leagueBadge.y = 20;
}
}
if (window.leagueBadge) {
@@ -2866,9 +2866,9 @@
// değerleri güncelle ve görünür yap
var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0;
var winGames = typeof storage.winGames === "number" ? storage.winGames : 0;
var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1;
- var oran = totalGames > 0 ? Math.round(winGames / totalGames * 100) + "%" : "% ?";
+ var oran = totalGames > 0 ? Math.round(winGames / totalGames * 100) + "%" : "∅";
var oyunStr = totalGames > 0 ? totalGames : "0";
window.winRateTxt.setText("Zafer Oranı: " + oran + " | Maç Sayısı: " + oyunStr + " | Seviye: " + level);
window.winRateTxt.x = 0;
window.winRateTxt.y = 20;
Yeşil casino masa arkaplanı. Dikdörtgen.
Casino oyunum için buton olarak kullanmalık dikdörtgen (köşeleri yumuşatılmış, edge). Yazısız.. In-Game asset. 2d. High contrast. No shadows
Bu sefer zar 1 yerine zar 2 olsun. Delik kırmızı değil siyah olsun.
Zar 2 değil 3 olsun.
Zar 4 olsun. Deliklerinin içi dolu siyah olsun.
Zar 2 değil, zar 5 olsun.
Zar 6 olsun. İçindeki deliklerin içi dolu siyah olsun.
Zar 6 değil, zar joker olsun. Yani zarın üstünde joker sembolü olsun.
Zar 4 değil, zar 1 olsun. İçi siyah değil kırmızı olsun.
Casino tarzında yatay dikdörtgen (köşeleri yumuşatılmış, edge). İçi sarı, dışında kırmızı şerit var. Sol üst köşesinde bir çift zar var. Yazısız.. In-Game asset. 2d. High contrast. No shadows. Casino
oyunEkraniMuzigi
Music
zarBirakmaSesi
Sound effect
zarSecmeSesi
Sound effect
tutVeDevamEtSesi
Sound effect
tutVeTuruSonlandirSesi
Sound effect
ilkSenBasliyorsunSesi
Sound effect
rakibinSirasiSesi
Sound effect
siraSendeSesi
Sound effect
iflasBenSesi
Sound effect
iflasRakipSesi
Sound effect
senKazandinSesi
Sound effect
kaybettinSesi
Sound effect
pasButonuSesi
Sound effect
klavyeTusunaBasmaSesi
Sound effect
oyunuBaslatButonuSesi
Sound effect
anaMenuyeDonButonuSesi
Sound effect
hesabiSifirlaButonuSesi
Sound effect
yuklemeEkraniSesi
Sound effect
ilkRakipBasliyorSesi
Sound effect