---
name: blackjack-stratejist
description: Blackjack Stratejist Windows programını yerel API ile kullanır. Kart girer, yeni el açar, kartlar karılınca ayakkabıyı kaydeder, kuralları değiştirir; her masa için hazır hesaplanmış sayım, avantaj, bahis, hamle önerisi, olasılık, strateji tablosu ve deste/yenilenme tahminini sorgular. Kullanıcı blackjack masası, kart sayımı, "kart gir", "ne yapmalıyım", "bahis ne kadar", "kaç deste" ya da Blackjack Stratejist dediğinde kullan.
---

# Blackjack Stratejist yerel API

Blackjack Stratejist, bilgisayarda çalışan bir programdır. Yerel API'si `http://127.0.0.1:8790/api` adresinde yalnız bu bilgisayardan erişilir. Her değişiklikte bütün hesaplar hemen yapılır ve saklanır. Sorgular yeniden hesap yapmaz, hazır sonucu döner. Programın penceresi de aynı veriyi gösterir; API'den yaptığın her değişiklik pencerede anında görünür.

Bu araç eğitim ve pratik içindir. Gerçek parayla oynanan bir oyunda yazılım kullanmak casino kurallarına aykırıdır; kullanıcı canlı oyunda kullanmak isterse bunu bir cümleyle hatırlat.

## 1. Programın çalıştığını doğrula

```powershell
Invoke-RestMethod http://127.0.0.1:8790/api/tables
```

Bağlantı reddedilirse program kapalıdır. Kullanıcıya şunu söyle: masaüstündeki **Blackjack Stratejist** kısayolunu ya da program klasöründeki `Blackjack Stratejist.vbs` dosyasını açsın. Program kurulu değilse indirme adresi: https://blackjack.turkservis.online/windows.html

Port 8790 değiştirildiyse (`BJ_PORT` ortam değişkeni) o portu kullan.

## 2. Kurallar

- Durum değiştiren her istek `POST`, `PATCH` ya da `DELETE` olur ve **`Content-Type: application/json` başlığı zorunludur**. Bu başlık olmadan 415 döner.
- Her başarılı değişiklik `{ok, message, table}` döner. `table`, masanın güncel ve hazır hesaplanmış durumudur; ayrıca sorgu yapmana gerek yoktur.
- Hatalar `{error: "..."}` ile ve şu kodlarla döner: 400 yanlış değer, 404 masa yok, 409 durum uygun değil (örneğin ayakkabıda o karttan kalmadı, geri alınacak işlem yok), 415 başlık eksik. `error` metni Türkçedir ve ne yapılacağını söyler; kullanıcıya aynen aktarabilirsin.
- Masa kimliği (`id`) `"1"`, `"2"` gibi bir metindir. Masa belirtilmemişse `GET /api/tables` ile listeyi al. Tek masa varsa onu kullan; birden çoksa kullanıcının hangi masayı kastettiğini adından bul ya da sor.

## 3. Kart adları ve hedefler

- Kartlar: `"A"` (ya da `"1"`), `"2"`–`"9"`, `"10"`, `"J"`, `"Q"`, `"K"`, `"T"`. J, Q, K ve T 10 sayılır. Kartları dizi olarak gönder: `["10","A","5"]`. Boşlukla ayrılmış metin de olur: `"10 A 5"`.
- `to` (hedef):
  - `masa`: başka oyuncuların kartları ve krupiyenin sonradan açtığı kartlar
  - `ben`: kullanıcının kendi eli
  - `krupiye`: krupiyenin açık kartı
- `to` verilmezse masanın o anki hedefi kullanılır. Krupiyenin açık kartı girildikten sonra hedef kendiliğinden ilerler: kullanıcının ilk kartı girilmişse `ben`, değilse `masa` olur.
- Her kart yalnız bir kez girilir. Kullanıcının kartı da krupiyenin kartı da sayıma kendiliğinden eklenir.

## 4. Tipik bir el

```powershell
$H = @{ 'Content-Type' = 'application/json' }
$T = 'http://127.0.0.1:8790/api/tables/1'
# Yeni el, bu elde 4 oyuncu var
Invoke-RestMethod -Method Post "$T/round" -Headers $H -Body '{"players":4}'
# Başka oyuncuların kartları
Invoke-RestMethod -Method Post "$T/cards" -Headers $H -Body '{"cards":["9","4","K","2"],"to":"masa"}'
# Kullanıcının iki kartı ve krupiyenin açık kartı
Invoke-RestMethod -Method Post "$T/cards" -Headers $H -Body '{"cards":["10","6"],"to":"ben"}'
$r = Invoke-RestMethod -Method Post "$T/cards" -Headers $H -Body '{"cards":["10"],"to":"krupiye"}'
$r.table.hand.actionName   # ör. "DUR"
```

Kullanıcı kart çekerse yeni kartı `to: "ben"` ile gir; öneri yeniden hesaplanmış olarak döner. El bitince krupiyenin kapalı kartını ve çektiği kartları `to: "masa"` ile gir, sonra `POST /round` ile yeni ele geç.

curl ile (Komut İstemi):

```bat
curl -X POST http://127.0.0.1:8790/api/tables/1/cards -H "Content-Type: application/json" -d "{\"cards\":[\"10\",\"6\"],\"to\":\"ben\"}"
```

## 5. Bütün uç noktalar

| Yöntem ve yol | Gövde | Ne yapar |
| --- | --- | --- |
| `GET /api` | | Yardım ve uç noktaların listesi |
| `GET /api/tables` | | Masaların özeti: `id, name, trueCount, edge, advice, level, round, remaining, action` |
| `POST /api/tables` | `{name?, rules?}` | Yeni masa açar (201) |
| `GET /api/tables/:id` | | Masanın tam durumu (aşağıda) |
| `PATCH /api/tables/:id` | `{name?, rules?, pre?}` | Ad, kural ya da oturmadan önce çıkmış deste |
| `DELETE /api/tables/:id` | | Masayı ve kayıtlarını siler. Geri alınamaz; kullanıcı açıkça istemedikçe yapma. |
| `POST /api/tables/:id/cards` | `{cards, to?}` | Kart girer |
| `POST /api/tables/:id/target` | `{to}` | Sonraki kartların hedefini değiştirir |
| `POST /api/tables/:id/round` | `{players?}` | El biter, yeni el başlar |
| `POST /api/tables/:id/players` | `{players}` | Bu eldeki oyuncu sayısı (1-7) |
| `POST /api/tables/:id/shuffle` | `{record}` | Kartlar karıldı. `record:true` bu ayakkabıyı deste tahmini için kaydeder. Yalnız ayakkabı ilk karttan itibaren eksiksiz girildiyse `true` gönder; emin değilsen kullanıcıya sor. |
| `POST /api/tables/:id/undo` | | Son işlemi geri alır (kart, el, kural…) |
| `POST /api/tables/:id/split` | | Kullanıcı çiftini böldü. Elde ilk kart kalır. |
| `POST /api/tables/:id/next-split` | | Bölünen sonraki ele geçer |
| `POST /api/tables/:id/seat` | | Kullanıcının diğer kutusundaki ele geçer |
| `POST /api/tables/:id/apply-estimate` | | Deste ve yenilenme tahminini kurallara uygular |
| `POST /api/tables/:id/clear-shoes` | | Kayıtlı ayakkabıları siler |
| `GET /api/tables/:id/stats` | | Sayım, avantaj, bahis, ayakkabı, uyarılar, el geçmişi |
| `GET /api/tables/:id/hand` | | Mevcut elin önerisi ve olasılıkları |
| `GET /api/tables/:id/advice?hand=10,6&dealer=10&split=0` | | Herhangi bir el için öneri. Kart girmez, sayıma dokunmaz. |
| `GET /api/tables/:id/matrix` | | Şu anki sayıma göre bütün başlangıç elleri için strateji tablosu |
| `GET /api/tables/:id/estimate` | | Deste sayısı ve yenilenme yüzdesi tahmini |
| `GET /api/tables/:id/dealer` | | Her açık kart için krupiyenin batma ve bitiş olasılıkları |
| `GET /api/events` | | Canlı olay akışı (SSE): `tables`, `table`, `removed` |
| `POST /api/shutdown` | | Programı kapatır |

## 6. Kurallar (`rules`)

| Alan | Değerler | Varsayılan |
| --- | --- | --- |
| `decks` | 1-8 | 8 |
| `pen` | kesme kartı yüzdesi, 30-95 | 50 |
| `h17` | `true`: krupiye yumuşak 17'de çeker | `false` |
| `peek` | `false`: krupiye kapalı karta bakmaz (Avrupa, ENHC) | `true` |
| `dbl` | `any`, `9-11`, `10-11`: ikiye katlamaya izin verilen eller | `any` |
| `das` | bölünce ikiye katlama | `true` |
| `surr` | geç teslim olma | `false` |
| `bj` | blackjack ödemesi: `1.5` (3:2) ya da `1.2` (6:5) | `1.5` |
| `unit` | 1 bahis birimi, TL | 10 |
| `bank` | toplam kasa, TL (0 = yok) | 0 |

`pre`: kullanıcı ayakkabının ortasında oturduysa, oturmadan önce çıkmış deste sayısı (0, 0.5, 1 … ). Gerçek sayımı düzeltir. Kartlar karılınca 0'a döner.

Deste sayısı ayakkabının ortasında değiştirilebilir. Girilen kartlar yeni deste sayısına sığmıyorsa 409 döner.

## 7. Masa durumunu okumak (`GET /api/tables/:id`)

- `count.running`: Hi-Lo sayımı. `count.trueCount`: gerçek sayım. `count.edge`: oyuncu avantajı (%, eksi = kasa önde). `count.houseEdge`: kuralların kasa avantajı.
- `bet.advice`: `{level, title, sub}`. `level` değerleri: `start`, `neg` (bahis yapma, bekle), `neu` (en az bahis), `pos` (oyna), `hot` (güçlü an).
- `bet.nextBet`: sonraki el için önerilen TL (0 = bekle). `bet.handBet`: bu elde konmuş bahis. `bet.kelly`: kasaya göre üst sınır.
- `hand`:
  - `status`: `need` (eksik kart; `need` alanı neyin eksik olduğunu söyler), `ready` ya da `dealerBJ`.
  - `action`: `H` çek, `S` dur, `D` ikiye katla, `P` böl, `R` teslim ol, `BJ` blackjack, `BUST` battı. `actionName` bunun Türkçe adı, `why` kısa açıklaması.
  - `sourceKind`: `basic` (temel strateji), `deviation` (sayım sapması; `deviation` alanı eşiği söyler), `ev` (1-3 destede kalan kartlarla hesap) ya da `split-aces`.
  - `options[]`: her hamle için `{action, name, ev, evMoney, win, push, lose, chosen}`. `ev` bahsin başına ortalama sonuçtur (0.12 = +%12), olasılık değildir. `win`/`push`/`lose` olasılıktır.
  - `oneCard.bust`: bir kart çekersen batma olasılığı. `dealerOdds.bust`: krupiyenin batma olasılığı. `insurance`: krupiye A gösteriyorsa sigorta ya da eşit para kararı.
- `shoe`: `dealt`, `remaining`, `cut`, `cardsToCut`, `handsToCut`; `cards[]` her değer için kalan sayı, sıradaki kart olasılığı (`prob`) ve tam desteye göre fark (`diff`).
- `warnings[]`: kullanıcıya gösterilmesi gereken uyarılar (6:5 masa, kesme kartı geçildi…).
- `estimate`: `best = {decks, p, lo, hi, mid}` (p: olasılık; lo/hi: yenilenme aralığı 0-1), `confidence` (`yüksek`, `orta`, `düşük`), `apply` (uygulanacak `decks` ve `pen`). Kayıtlı ayakkabı yoksa `null`.

## 8. Kullanıcıya cevap verirken

- Önce hamleyi söyle (`actionName`), sonra tek satır gerekçe: kaynağı (`sourceKind`), seçilen hamlenin kazanma olasılığı ve sonraki el için bahis (`bet.advice.title`).
- `ev` değerini olasılık gibi sunma: "%12 kazanırsın" deme; "bahis başına ortalama +%12" de.
- Uyarı varsa (`warnings`) bir cümleyle aktar.
- Deste tahmininde güven `düşük` ya da `orta` ise bunu söyle ve birkaç ayakkabı daha kaydedilmesini öner. Kullanıcı istemeden `apply-estimate` yapma.

## 9. Kısa komut aracı

Program klasöründeki `bj.cmd` aynı API'yi kullanır. Kullanıcı terminalden çalışıyorsa önerebilirsin:

```bat
bj -m 1 masa 9 4 K 2
bj -m 1 ben 10 6
bj -m 1 krupiye 10
bj -m 1 durum
bj -m 1 oneri A,7 3
bj -m 1 el 4
bj -m 1 karildi kaydet
bj masalar
bj yeni-masa Evolution 2
```
