квіне-іш тик-так-носок


19

Напишіть програму на обраній вами мові, яка грає ідеальну гру в тик-так-носок на дошці 3 * 3 проти гравця людини. Однак кожен крок повинен бути різною програмою , породженою попередньою ітерацією.

Як і в якій формі ви оцінюєте людський внесок, залежить від вас, але його слід читати зі стандартного вводу. Так само ви можете вибирати метод, яким ви будете визначати, який гравець починається (наприклад, ви запитуєте спочатку, або ви дозволяєте людині ввести недійсний хід, щоб сигналізувати про те, що запускається комп'ютер, або інші ідеї).

Валідні рухи не потрібні, ви можете припустити досить граючого суперника людини.

В основному, у вас є програма, яка відповідає стану плати. Стан друкується будь-яким розпізнаваним способом, але очікується принаймні наступний рівень деталізації:

X..
00X
x..

Після того, як гравець людини розпочав свої кроки, ваша програма повинна генерувати наступну ітерацію себе як вихідний файл на тій же мові (або до стандартного виводу, або до файлу) та завершити роботу. Вам заборонено зберігати інформацію ніде, крім цього вихідного файлу. (для створення вашої програми не потрібно створювати та запускати створену програму, це може зробити користувач - проте, це не заборонено). Коли створена програма буде побудована і запущена, вона буде вести себе аналогічно, відображатиме стан, чекатиме введення користувача тощо.

Наприкінці гри ви повинні надрукувати результат (виграв ви, чи це нічия) будь-яким однозначно впізнаваним способом.

Під ідеальною грою я маю на увазі, що програма не повинна програвати, і якщо є можливість виграти виграш, вона повинна виграти.

Найкоротший код виграє , переможця вибирають не менше 10 днів після першого дійсного вступу.

Ви отримуєте 10% зниження балу, якщо ваша програма може обробляти будівництво та запускати наступну ітерацію. (Я знаю, це, мабуть, не варто) Звичайно, сама програма повинна бути припинена до моменту, коли наступна ітерація прийме кроки від користувача.

Якщо ви використовуєте якісь дивні незвичайні хитрощі, будь ласка, опублікуйте коротке пояснення зі своїм кодом.


2
Хороший виклик, але я думаю, що я відмовлюсь від участі.
Джон Дворак

"Кожен хід повинен бути різною програмою". Ви маєте на увазі, "кожну гру потрібно ініціювати та керувати новим, чітким екземпляром оригінальної програми"?
DavidC

1
@DavidCarraher: Ні. Кожен хід, не лише кожна гра. Перевірте опис під прикладом дошки. Коли комп’ютер повинен зробити крок (щоб стан плати змінився), ваша програма повинна генерувати вихідний файл, який при побудові та запуску стане наступним станом. Потім вихідна програма закривається. Нещодавно створена програма при здійсненні руху буде поводитися аналогічно: вона створює вихідний файл, який при побудові та запуску стане наступним станом тощо. Оскільки зберігання інформації не дозволено, за винятком генерованого вихідного файлу, воно схоже на квинти з відмінностями між ітераціями.
vsz

Відповіді:


13

Perl, 933 символів

$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"}

Зверніть увагу, що порожній рядок посередині сценарію насправді зобов’язаний бути там. (Розриви рядків у кінці довгих рядків не потрібні, крім розбірливості, і не включаються до числа символів.)

Використання: Коли програма запускається без аргументів, вона відображає поточний стан гри. Оскільки на початку плата порожня, вихід буде:

...
...
...

Запустіть програму з аргументом між 1 і 9, щоб стверджувати, що цей квадрат є вашим ходом. Програма зробить свій власний хід, а потім виведе сценарій заміни з новим станом. Так, наприклад:

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

Лише на першому повороті ви можете зробити рух, 0щоб вказати, що комп'ютер повинен зробити перший крок. Зауважте, що перший гравець завжди буде X.

Коли гра закінчена, на дисплеї відображення відображатиметься примітка до цього ефекту:

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

Програма працює, виконуючи стандартний пошук в мінімаксі дерева ігор. (Tic-tac-toe - це досить маленька гра, що повне дерево ігор може генеруватися на кожному запуску.) Виняток з цього - коли комп'ютер рухається першим - у цьому випадку початковий крок у верхній лівий кут важкий - закодований.

Зауважте, що ця програма працює за принципом належної quine - ні в якому разі сценарій не отримує доступу до власного вихідного файлу для того, щоб отримати свій вихід.


1
Це прекрасно! Я не усвідомлював, що довгий час дивився на величезного тут-доктора, а потім зробив подвійний результат.
Джессі Сміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.