quine-ish tic-tac-toe


19

Seçtiğiniz dilde, bir insan oyuncuya karşı 3 * 3 tahtada mükemmel bir tic-tac-toe oyunu oynayan bir program yazın. Ancak, her hamlenin önceki yinelemeden üretilen farklı bir program olması gerekir .

İnsan girdisini nasıl ve hangi şekilde değerlendirdiğiniz size bağlıdır, ancak standart girdiden okunmalıdır. Benzer şekilde, hangi oyuncunun başladığını nasıl belirleyeceğinizi seçmekte özgürsünüz (örneğin, önce soruyorsunuz veya insanın bilgisayarın başladığını veya diğer fikirleri işaret etmek için geçersiz bir hareket girmesine izin veriyorsunuz).

Hareketleri doğrulamak gerekli değildir, oldukça oynayan bir insan rakibi olduğunu varsayabilirsiniz.

Temel olarak, yönetim kurulu durumuna karşılık gelen bir programınız var. Durum tanınabilir bir şekilde yazdırılır, ancak en azından aşağıdaki ayrıntı düzeyi beklenir:

X..
00X
x..

İnsan oyuncu hamlelerine girdikten sonra, programınızın bir sonraki tekrarını aynı dilde (standart çıktıya veya bir dosyaya) kaynak dosya olarak oluşturması ve sonlandırması gerekir. Bu kaynak dosyanın dışında hiçbir yerde bilgi depolamanıza izin verilmez. (programınızın oluşturulan programı oluşturup çalıştırması gerekmez, kullanıcı tarafından yapılabilir - ancak yasak değildir). Oluşturulan program oluşturulduğunda ve çalıştırıldığında, benzer şekilde davranacak, durumu gösterecek, kullanıcı girişini bekleyecek vb.

Oyunun sonunda, sonucu (kazanıp kazanmadığınız veya beraberlik olsun) kesin olarak tanımlanabilir herhangi bir şekilde yazdırmanız gerekir.

Mükemmel oyunla demek istediğim, program kaybetmemelidir ve bir kazanma zorlama olasılığı varsa kazanmalıdır.

En kısa kod kazanır , kazanan ilk geçerli girişten en az 10 gün sonra seçilir.

Programınız bir sonraki yinelemenin inşasını ve lansmanını halledebilirse puanda% 10 indirim elde edersiniz. (Biliyorum, büyük olasılıkla buna değmez) Elbette, programın kendisi bir sonraki yinelemenin kullanıcıdan gelen hareketleri kabul ettiği zaman sonlandırılmalıdır.

Bazı tuhaf nadir numaralar kullanırsanız, lütfen kodunuzla ilgili kısa bir açıklama gönderin.


2
Güzel bir meydan okuma, ama bence vazgeçeceğim.
John Dvorak

"Her hareket farklı bir program olmalı". "Her oyun orijinal programın yeni, farklı bir örneği tarafından başlatılmalı ve yönetilmelidir" demek istiyor musunuz?
DavidC

1
@DavidCarraher: Hayır. Her hareket, sadece her oyun değil. Pano örneğinin altındaki açıklamaya bakın. Bilgisayarın bir hamle yapması gerektiğinde (böylece kartın durumu değişir), programınız oluşturulduğunda ve çalıştırıldığında bir sonraki durum haline gelecek bir kaynak dosyası oluşturmak zorundadır. Ardından orijinal programdan çıkılır. Yeni oluşturulan program, bir hamle yaparken benzer şekilde davranır: oluşturulduğunda ve çalıştırıldığında bir sonraki durum haline gelecek bir kaynak dosyası oluşturur. Oluşturulan kaynak dosya dışında hiçbir bilgi depolama alanına izin verilmediğinden, yinelemeler arasındaki farkları gösteren bir kine gibidir.
vsz

Yanıtlar:


13

Perl, 933 karakter

$m=<<'';$_='         ';
sub h{/^(?:...)*(\d)\1\1/|/^.?.?(\d)..\1..\1/|/(\d)...\1...\1/|/^..(\d).\1.\1/&&$1}
sub r{substr($_,$p-1,1)=pop}sub p{my$w=pop;my@b=(0,h==$w||h&&-1);if(!$b[1]&&/ /){$b[1]=-9;
while(/ /g){local($_,$p)=($_,pos);r$w;$r=-(p($w^1))[1];@b=($p,$r)if$r>$b[1]}}@b}
if(($w=h||!/ /)||!@ARGV){$w--&&print+(nobody,X,O)[$w]," wins\n";s/(...)/$1\n/g;
tr/ 23/.XO/;print}else{$w=3;$w^=1for/\d/g;($p=pop)?r($w^1)&&!h&&(($p)=p$w)&&r$w:s/ /2/;
print"\$m=<<'';\$_='$_';\n$m\n$m"}

sub h{/^(?:...)*(\d)\1\1/|/^.?.?(\d)..\1..\1/|/(\d)...\1...\1/|/^..(\d).\1.\1/&&$1}
sub r{substr($_,$p-1,1)=pop}sub p{my$w=pop;my@b=(0,h==$w||h&&-1);if(!$b[1]&&/ /){$b[1]=-9;
while(/ /g){local($_,$p)=($_,pos);r$w;$r=-(p($w^1))[1];@b=($p,$r)if$r>$b[1]}}@b}
if(($w=h||!/ /)||!@ARGV){$w--&&print+(nobody,X,O)[$w]," wins\n";s/(...)/$1\n/g;
tr/ 23/.XO/;print}else{$w=3;$w^=1for/\d/g;($p=pop)?r($w^1)&&!h&&(($p)=p$w)&&r$w:s/ /2/;
print"\$m=<<'';\$_='$_';\n$m\n$m"}

Lütfen komut dosyasının ortasındaki boş satırın orada olması gerektiğini unutmayın. (Uzun satırların sonunda okunabilirlik dışında satır sonlarına gerek yoktur ve karakter sayısına dahil edilmez.)

Kullanım: Program bağımsız değişkenler olmadan çalıştırıldığında, geçerli oyun durumunu gösterir. Başlangıçta kart boş olduğundan çıktı:

...
...
...

Bu kareyi hamle olarak talep etmek için programı 1 ile 9 arasında bir argümanla çalıştırın. Program kendi hareketini yapacak ve daha sonra yeni durum ile bir yedek komut dosyası verecektir. Böylece, örneğin:

$ perl ./qttt 5 > ./qttt-2
$ perl ./qttt-2
O..
.X.
...

Yalnızca ilk dönüşte 0, bilgisayarın ilk hamleyi yapması gerektiğini belirtmek için bir hamle verebilirsiniz . İlk oyuncunun her zaman olacağını unutmayın X.

Oyun bittiğinde, ekran çıktısı bu etki için bir not içerecektir:

$ perl ./qttt-4 6 > ./qttt-5
$ perl ./qttt-5
O wins
OXX
OOX
X.O

Program, oyun ağacında standart bir minimax araması yaparak çalışır. (Tic-tac-toe, her koşuda tam bir oyun ağacının üretilebileceği kadar küçük bir oyundur.) Bunun istisnası, bilgisayar ilk hareket ettiğinde - bu durumda sol üst köşeye ilk hareket zor kodlanmış.

Bu programın uygun bir kine biçiminde çalıştığını unutmayın. Komut dosyası hiçbir zaman çıktısını üretmek için kendi kaynak dosyasına erişmez.


1
Bu güzel! Burada uzun bir süre kocaman bir dokümana baktığımı fark etmedim, sonra iki kere aldım.
Jesse Smith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.