Пограйте в ідеальну гру Мурере


14

Фон

Му Торере - це гра, яка є однією лише з двох відомих, яку марійці Нової Зеландії грали до європейського впливу. Це робить його дуже унікальною грою тим, що вона має "об'єктивний критерій виграшу" та правила гри, які відрізняються від більшості інших існуючих ігор.

Ігровий процес:

Дошка - восьмикутник. Між кожною сусідньою вершиною є з'єднання, і є центральний вузол, який з'єднаний з усіма вершинами. У будь-який момент часу вісім із дев’яти вузлів зайняті камінням. На початку - чотири білих та чотирьох чорних каменів, які посідають одну половину восьмикутника, центральний вузол порожній. Чорний рухається першим.

Кожен поворот гравця може переміщати один із своїх каменів по одному з 16 країв від одного вузла до порожнього вузла. Камінь можна переміщати лише від зовнішнього вузла до центрального вузла, якщо камінь знаходиться поруч з каменем противника.

Гравець програє, коли не в змозі зробити законний хід, який відбувається, коли немає краю, що з'єднує камінь із порожнім вузлом.

Діаграма та пояснення правил

Ось веб-сайт, який пояснює правила (із діаграмою) та пропонує певний аналіз.

Змагання

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

Ідеальна гра?

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

Деталі

Після кожного ходу (і на початку гри) ваша програма повинна надрукувати ігрову дошку. Однак ви вирішите відображати плату, вона повинна показувати всі вузли та бути повністю з’єднаними (усі 16 ліній з'єднання повинні бути прокреслені без перекреслених ліній). На старті дошка повинна мати правильне вихідне положення. Один із способів досягти цього - зробити ігрове поле квадратним.

w-w-w
|\|/|
b-o-w
|/|\|
b-b-b

Два кольори - чорний і білий, або темний / світлий. На дошці повинно бути вказано, які вузли зайняті частинами гравця, наприклад, позначення їх "b" або "w", а який вузол є вакантним. Учасникам рекомендується (але не вимагається) зробити ігрову дошку більш графічною, а не простою текстою.

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

1-2-3
|\|/|
4-5-6
|/|\|
7-8-9

Людина - це перший рух. Його вхід буде єдиним номером. Це буде номер вузла, де знаходиться перенесений камінь. Якщо я хотів би перенести камінь із вузла 4 у порожній вузол 5, я наберу a 4. 5 мається на увазі, оскільки це єдиний порожній вузол.

Припустимо, що людина завжди зробить законний крок.

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

Ваша програма повинна припинитись після її виграшу.

Примітки

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


2
Великий виклик. Тільки "Якщо людина вводить незаконний хід, то ваша програма повинна зачекати і дозволити йому ввести інший хід". мені здається трохи не-гольф-іш: чи не можемо ми просто залишити поведінку невизначеною у випадку незаконних внесків?
перестали повертати проти годинника,

1
Я кинув цю вимогу в останню хвилину, і, мабуть, було б добре, якби ми її усунули. Це просто ускладнює людину, яка вже приречена не перемагати. :)
PhiNotPi

1
Це не що важко завжди ввести юридичне рух ... До речі, після досить докладного аналізу я думаю , що немає необхідності шукати більш 1,5 ходів вперед. Чи є такий підхід найкоротшим - інше питання.
Пітер Тейлор

3
Пов’язаний веб-сайт більше недоступний, було б краще змінити його на посилання на архівну версію.
Tally

Відповіді:


6

Рубі, 390 чол

o=->s,c{f=s=~/o/;[*0..8].select{|t|s[t]==c&&(t<1||(t+6)%8+1==f||t%8+1==f||f<1&&(s[(t+6)%8+1]!=c||s[t%8+1]!=c))}.map{|t|k=s*1;k[f]=c;k[t]=?o;k}}
v=->s,c,h{f=o[s,c];f==[]?0:h<1?1:2-f.map{|t|v[t,c>?b??b:?w,h-1]}.min}
q=->g{puts"1-2-3\n|\\|/|\n8-0-4\n|/|\\|\n7-6-5\n".tr"0-8",g;$>.flush}
q[g="obbbbwwww"]
(g.tr!?o,?b;g[gets.to_i]=?o;q[g];q[g=o[g,?w].sort_by{|q|v[q,?w,5]}[-1]])while v[g,?b,5]>0

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

1 - 2 - 3
| \ | / |
8 - 0 - 4
| / | \ |
7 - 6 - 5

5

баш та друзі ( 463 447 символів)

t(){ tr 0-8a-i $b$b
}
p(){ t<<E
0-1-2
|\|/|
3-4-5
|/|\|
6-7-8

E
}
g(){ b=`tr $x$e $e$x<<<012345678|t`
p
e=$x
}
b=bbbbowwww
e=4
m=0
p
while [ $m != 5 ]&&read x;do
g
m=0
for y in {0..8};do
s=0
S=05011234
grep -E "w.*($y$e|$e$y)"<<<${b:$y:1}30125876340142548746>/dev/null&&for p in wow.\*/ww wow.\*/w bbo.\*/b obb.\*/b www wbw .
do
((s++))
tr $y$e $e$y<<<3012587630/4e|t|grep $p>/dev/null&&break
done
s=${S:$s:1}
[ $s -gt $m ]&&m=$s x=$y
done
g
done

Людина грає як b, комп'ютер як w. Позиція дошки пронумерована, як у документі тут у верхній частині. Виявляється, евристика грати досконалою грою напрочуд проста.

З іншого боку, втратити цікавий шлях досить важко. http://ideone.com/sXJPy демонструє найкоротше можливе самогубство проти цього бота. Зауважте, що додаткові 0 в кінці - це перевірити, чи правильно він виривається з циклу.


NB: Я міг би врятувати одного персонажа, зробивши його read xобов'язковим, але це зробило б тестування дуже неприємним. Я також міг би зберегти персонажа, видаливши порожній рядок після дошки, але ...
Пітер Тейлор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.