Tic-Tac-Latin!
Ini adalah kisah nyata, jadi nama telah diubah.
Guru latin saya, Tn. Latin, menciptakan varian tac toe miliknya sendiri (bukan lelucon). Sebut saja tic-tac-latin. Permainan ini sederhana, pada dasarnya tic toe dimainkan pada empat dengan empat kotak.
Deklarasi aturan formal
Garis adalah baris, kolom atau diagonal. Ada dua simbol, 'X' dan 'O', tetapi satu atau keduanya dapat diganti untuk simbol yang berbeda.
Anda mencetak satu poin ketika Anda memiliki tiga simbol dan satu karakter lainnya.
Skor pengaturan ini:
---HAI -HAI-- XXXO XOOX O -XX - O - - X - --- O
Ini tidak memberi skor:
---- XXXX ---- OOOO ---- XXX- ---- OOO-
Permainan dimenangkan setiap kali satu pemain memiliki lebih banyak poin daripada yang lain. Gim ini hanya seri jika papan diisi.
Tantangan
Selesaikan game ini. Tugas Anda adalah menyediakan cara untuk menjamin kemenangan atau dasi, mana yang merupakan hasil optimal.
Solusi Anda dapat memilih untuk memulai pertama atau kedua (dan karena itu dapat memilih simbolnya). Ini tidak wajib untuk mengimplementasikan permainan interaktif di mana input pengguna bergerak dan tampilan yang sesuai berubah. Ini juga bisa berupa fungsi atau program yang mengambil input sebagai kondisi permainan, dan mengeluarkan papan baru atau deskripsi langkah mereka . Pilihan mana pun harus dijalankan dalam waktu sekitar sepuluh detik per gerakan yang dilakukan.
Memainkan pemain Anda melawan setiap urutan gerakan harus memberikan hasil yang optimal. Ini berarti Anda dapat menganggap posisi input adalah posisi yang dapat dijangkau dari bermain dengan pemain Anda. Kiriman harus bersifat deterministik, dan tidak perlu memberikan bukti optimalitas, tetapi jika kiriman tersebut retak (dengan dipukuli) kiriman Anda akan dianggap tidak valid (Anda dapat membiarkannya, tetapi menambahkan (retak) pada informasi utama).
Ini adalah tugas yang tidak sepele, jadi setiap pengajuan yang valid sangat mengesankan dan layak untuk centang yang diterima, tapi saya akan menjadikan kode golf kriteria utama yang menang.
Pemenang dipilih dengan turun daftar ini sampai satu pemenang dipilih.
- Implementasi terselesaikan terpendek yang selalu menang
- Implementasi terpendek
Jawaban:
Perl, 147 byte (tidak bersaing, membutuhkan lebih dari 10 detik per gerakan)
Termasuk +4 untuk
-0p
Program diputar
X
. Ini akan memainkan game yang sempurna.Masukkan papan pada STDIN, misalnya:
Ouptut akan menjadi papan yang sama dengan semua
X
digantikan olehO
dan sebaliknya. Bintik-bintik kosong akan diisi dengan angka yang mengindikasikan hasil jika X akan bermain di sana, yang1
artinya hasilnya adalah menang,2
seri, dan3
kalah. Game yang telah selesai hanya mengembalikan posisi yang sama dengan warna yang dibalik.Dalam contoh ini, hasilnya adalah:
Jadi posisinya adalah kemenangan karena
X
dia bermain di 3 tempat di bagian atas dan kiri. Semua gerakan lainnya kalah.Output membingungkan ini sebenarnya nyaman jika Anda ingin tahu bagaimana permainan berlanjut setelah pindah. Karena program selalu dimainkan,
X
Anda harus menukarX
danO
melihat pergerakannyaO
. Di sini misalnya cukup jelas bahwaX
menang dengan bermain di kiri atas, tetapi bagaimana jikaX
bermain di posisi ketiga sepanjang atas? Cukup salin output, letakkanO
di tempat langkah yang Anda pilih dan ganti semua angka lainnya-
lagi, jadi di sini:Yang menghasilkan:
Tentunya setiap gerakan
O
harus kalah, jadi bagaimana dia bisa kalah jika dia bermain di kiri atas? Sekali lagi lakukan ini dengan meletakkanO
di kiri atas dan mengganti digit dengan-
:Memberi:
Jadi X hanya memiliki satu cara untuk meraih kemenangannya:
Memberi
Situasi untuk
O
tetap tanpa harapan. Sangat mudah untuk melihat sekarang bahwa setiap gerakan memungkinkanX
untuk segera menang. Mari kita setidaknya mencoba untuk mendapatkan 3 O berturut-turut:Memberi:
X
memainkan satu-satunya langkah yang menang (perhatikan bahwa ini dilakukan diXXXO
sepanjang kolom ketiga:Di sini hasilnya adalah:
karena permainannya sudah selesai. Anda dapat melihat kemenangan di kolom ketiga.
Program aktual
tictaclatin.pl
:Diterapkan ke papan kosong ini mengevaluasi posisi 9506699 yang memakan waktu 30Gb dan 41 menit di komputer saya. Hasilnya adalah:
Jadi setiap langkah awal menarik. Jadi game ini seri.
Penggunaan memori ekstrim sebagian besar disebabkan oleh penggunaan rekursi
do$0
. Menggunakan versi 154 byte ini menggunakan fungsi sederhana membutuhkan 3Gb dan 11 menit:yang lebih tertahankan (tapi masih terlalu banyak, sesuatu pasti masih bocor memori).
Menggabungkan sejumlah speedup mengarah ke versi 160 byte ini (posisi 5028168, 4 menit dan 800M untuk papan kosong):
Yang terakhir digunakan
0
untuk menang (jangan bingung denganO
),1
untuk seri dan2
untuk kekalahan. Hasil yang satu ini juga lebih membingungkan. Ia mengisi langkah kemenangan untuk X jika menang tanpa swap warna, tetapi jika game input sudah dimenangkan masih melakukan swap warna dan tidak mengisi langkah apa pun.Semua versi tentu saja menjadi lebih cepat dan menggunakan lebih sedikit memori saat papan terisi. Versi yang lebih cepat akan menghasilkan gerakan dalam waktu kurang dari 10 detik segera setelah 2 atau 3 gerakan dilakukan.
Pada prinsipnya, versi 146 byte ini juga harus berfungsi:
tetapi pada mesin saya itu memicu bug perl dan dump inti.
Semua versi pada prinsipnya akan tetap berfungsi jika caching posisi 6 byte yang dilakukan
$$_||=
dihapus tetapi menggunakan begitu banyak waktu dan memori sehingga hanya berfungsi untuk papan yang hampir penuh. Namun secara teori setidaknya saya punya solusi 140 byte.Jika Anda menempatkan
$\=
(biaya: 3 byte) tepat sebelum$@<=>0
papan output maka masing-masing akan diikuti oleh status seluruh papan:1
untukX
menang,0
untuk menarik dan-1
untuk kerugian.Ini adalah driver interaktif berdasarkan versi tercepat yang disebutkan di atas. Pengemudi tidak memiliki logika untuk kapan permainan selesai sehingga Anda harus menghentikan diri sendiri. Kode golf tahu. Jika langkah yang disarankan kembali tanpa
-
diganti oleh apa pun, permainan telah berakhir.sumber
$move
dinyatakan pada baris 11. Saya tidak tahu apakah ada heuristik manusia. Program ini hanya tidak Minimax pada pohon permainan, tidak memiliki apa pun pengetahuan strategis.JavaScript (ES6) 392 byte
Pemakaian
"Bot" akan dimainkan kedua.
Gambar kotak 4x4 yang diberi nomor seperti ini:
Mari kita jalankan ini di konsol browser: Taruh
f=
sebelum kodeJadi, jika saya ingin mulai
1
, saya akan larif([1])([])
dan itu akan memberi saya14
.Langkah yang bagus ... Bagaimana jika saya bermain
2
sesudahnya?f([2,1])([14])
. Itu akan kembali13
.Biar mencoba menyerah. Bermain
3
.f([3,2,1])([14,13])
. Oh0
! Saya ketahuan!Bermain
0
?f([0,2,1])([14,13])
.15
Ok mari kita terus bermain ...Catatan
Mainkan secara interaktif. Mulai dengan
f([your-step])([])
.Tambahkan langkah Anda selanjutnya. (Lihat demo di atas)
Bantu "bot" memasukkan langkah-langkahnya. Itu tidak akan memberi Anda hasil yang baik jika Anda memberikannya pengaturan acak. (Suka
f([1,2,4])([14,12])
akan memberi14
- Hei bot ingin bermain di13
langkah kedua!Ringkasan singkat
Selama Anda tidak menyerah, bot akan memainkan gerakan cermin.
Terima kasih @EHTproduk karena memberi tahu saya bahwa saya salah membaca aturan permainan dan kiat bermain golf: P.
Sekarang ini juga akan mendeteksi jika mendapat skakmat. Jika ya, blokir!
Prioritasnya: Block> Mirror> (fallback) mencari cara untuk mereproduksi cermin
sumber
3,2,1
bagi Anda dan0
bot itu kemenangan bagi Anda?[0,1,2,3].map(i=>{k(n=>n%4==i);k(n=>Math.floor(n/4)==i);})
bisa golf untuk[0,1,2,3].map(i=>k(n=>n%4==i)+k(n=>(n/4|0)==i))
.