Працюю над моїми лицарськими рухами


16

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

Дошка складається з трьох кольорів (так, щоб той самий колір не розділяв краю), а краї шестикутників спрямовані до гравців. На дошці є 11 файлів, позначених буквами aнаскрізь l(літера jне використовується), та 11 рангів (які вигинаються на 60 ° у файлі f). Ранги 1через 6кожну містять 11 комірок, ранг 7- 9 комірок, ранг 8- 7 тощо. Ранг 11містить точно одну клітинку: f11 . (Якщо це допомагає, подумайте про кожен ранг як про дуже широку форму "V".)

Ось приклад малюнка дошки з лицарем на центральній комірці. Осередки, позначені крапкою, - це законний хід цього конкретного лицаря. Лицар переходить подібним чином до «звичайних» шахів, два вниз і один на один. У шестикутній шаховій формі - це ортогональний хід (через край), потім діагональний рух у тому ж напрямку (найближчий рух до того ж кольору). Наприклад, з лицарем внизу, ортогональний рух "вгору" до світло-коричневого кольору супроводжується діагональним переміщенням "вгору і вправо" або "вгору і вліво" до найближчого світло-коричневого.

Глінський варіант лицаря

З загальнодоступного домену через https://commons.wikimedia.org/wiki/File:Glinski_Chess_Knight.svg

Цей лицар розміщується на f6 і, таким чином, легальні кроки

c4, c5, d3, d7, e3, e8, g3, g8, h3, h7, i4, i5

Вхідні дані

Єдиний вхід, що дає вихідну клітинку нашого лицаря. Це може бути як один рядок "b6", так і два рядки "b", "6"тощо у будь-якому зручному форматі . Вхідні літери можуть бути великими або малими літерами - ваш вибір.

Вихідні дані

Список дійсних кроків, які може зробити лицар у цьому місці. Це може бути масив рядків, одна рядок з однозначним і послідовним роздільником, окремі рядки за новими рядками тощо, що б це було найзручніше. Вихідні дані не обов'язково мають бути відсортованими, і вони можуть бути або великими, або малими літерами - ваш вибір.

Правила

  • Припустимо, що жодного іншого шматка немає на дошці і не заважає рухатися. Ми зосереджені лише на лицарі.
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Якщо можливо, додайте посилання на онлайн-тестувальне середовище, щоб інші люди могли спробувати ваш код!
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

Приклади

b6
a3, c4, d5, d9, e7, e8

f6
c4, c5, d3, d7, e3, e8, g3, g8, h3, h7, i4, i5

f11
d8, e8, g8, h8

i1
f2, f3, g4, h4, l2, k3

12
Ця система координат - робота диявола.
Мартін Ендер

2
@MartinEnder Окуляри, якщо ви зробите це в шестикутниках :)
Ерік Атгольфер

Я відчуваю, що я міг би перетворити це на інший векторний простір, перезначивши дві осі на горизонтальну та діагональну до 60 градусів, а потім просто скористайтеся регулярними рухами, а потім перекладіть її назад за допомогою лінійної алгебри, але я думаю, що це надмірно ускладнює речі: P І також Я погоджуюся, що система координат - це найвигідніша річ, яку я бачив тут, на цьому сайті. : P
HyperNeutrino

Відповіді:


11

JavaScript (ES6), 184 байти

Приймає файл Fяк символ і ранг Rяк ціле число в синтаксисі currying (F)(R). Повертає масив рядків.

F=>R=>[...'100124566542'].map((X,i)=>(X-=3-(x=(s='abcdefghikl').search(F)))-7<(Y=('9641001469'[i]||10)-(A=Math.abs)(x-5)+17-2*R)&X+Y>3&X+16>Y&X+Y<27&&s[X]+(22-Y-A(X-5))/2).filter(n=>n)

Як?

Крок №1: конвертуйте файл / рейтинг у декартові координати

Перетворимо гексагональні координати шахів у декартові координати (x, y) з x в [0 .. 10] і y в [0 .. 20] :

      00 01 02 03 04 05 06 07 08 09 10
   +----------------------------------
00 |                f11                     F = file (letter)
01 |             e10   g10                  R = rank in [1 .. 11]
02 |          d09   f10   h09               
03 |       c08   e09   g09   i08            F | a b c d e f g h i k l
04 |    b07   d08   f09   h08   k07         --+-----------------------
05 | a06   c07   e08   g08   i07   l06      x | 0 1 2 3 4 5 6 7 8 9 10
06 |    b06   d07   f08   h07   k06         
07 | a05   c06   e07   g07   i06   l05      y = 22 - |x - 5| - 2R
08 |    b05   d06   f07   h06   k05   
09 | a04   c05   e06   g06   i05   l04
10 |    b04   d05   f06   h05   k04   
11 | a03   c04   e05   g05   i04   l03
12 |    b03   d04   f05   h04   k03   
13 | a02   c03   e04   g04   i03   l02
14 |    b02   d03   f04   h03   k02   
15 | a01   c02   e03   g03   i02   l01
16 |    b01   d02   f03   h02   k01   
17 |       c01   e02   g02   i01      
18 |          d01   f02   h01         
19 |             e01   g01            
20 |                f01               

Крок №2: застосуйте вектори переміщення

Нижче наведено перелік векторів руху в декартовій системі:

(-2, +4), (-1, -5), (+3, +1),
(-3, +1), (+1, -5), (+2, +4),
(-3, -1), (+2, -4), (+1, +5),
(-2, -4), (+3, -1), (-1, +5)

Ми застосовуємо кожну з них до вихідних координат (x, y) і отримуємо список координат цілі (X, Y) .

Крок №3: протестуйте цільові координати

Тепер нам потрібно перевірити, які цільові координати насправді розташовані всередині дошки. Це робиться шляхом тестування X + Y і X - Y :

X / Y

Координати є дійсними, якщо всі наступні порівняння вірні:

  • X + Y> 3
  • X + Y <27
  • X - Y <7
  • X - Y> -17

Ми також повинні перевірити, що X знаходиться в [0 .. 10] . Це не робиться явно, тому що s[X]це не визначено, якщо це не так, що в кінцевому підсумку призводить до хибного значення, яке відфільтровується.

Крок №4: перетворіть назад на шестикутні координати шахів

Нарешті, дійсні цільові координати перетворюються назад у шестикутні координати шахів, використовуючи зворотну формулу, описану на кроці №1.

Тестові справи


А, це дійсно розумний спосіб обійти шестикутну систему координат. Приємно!
AdmBorkBork

4

Пакетна. 403 байти

@echo off
set j=a b c d e f g h i k l
set f=0
for %%f in (%j%)do set/af+=1&if %%f==%1 goto l
:l
set j=j%j: =%
set/a"r=6-f,r*=r>>31,r+=%2
for %%s in ("-3 -2" "-3 -1" "-2 1" "2 -1" "3 1" "3 2")do call:c %%~s
exit/b
:c
call:l %2 %1
:l
set/ag=f+%1,s=r+%2,t=g-s
if %g% geq 1 if %g% leq 11 if %s% geq 1 if %s% leq 11 if %t% geq -5 if %t% leq 5 set/a"t=6-g,s-=t*=t>>31"&call echo %%j:~%g%,1%%%%s%%

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


3

JavaScript (ES6), 184 байти

(s,t,j=' abcdefghikl',f=j.search(s),r=f<6?t:t+f-6)=>[...'120405..162645'].map((c,i)=>[(i>>1)-3+f,c-3+r]).filter(([f,r])=>f>0&f<12&r>0&r<12&f-r<6&r-f<6).map(([f,r])=>j[f]+(f<6?r:r+6-f))

Я думав , що я порт мого Пакетне рішення ES6 , щоб подивитися , як він по порівнянні ... Я не очікував , що це буде що близько ...


3

CJam, 77

1Z2W2Z]_Wf*+2/_Wf%+[r('a-_9>-_6-We>@~+]f.+{_~m5++B,-!},{~1$6-We>-\_8>+'a+\S}/

Спробуйте в Інтернеті

Огляд:

Я використовую систему координат, яка має вигляд a..f та 1..6 з лівого боку, розширена без згинання, літери замінені цифрами та змінена на 0 (b3 → [1 2], g1 → [6 1], k3 → [9 6]). Відносні рухи в цій системі - [1 3], [2 -1], [2 3] та їх відбиття (негативні та замінені, наприклад [1 3] → [-1 -3], [3 1], [- 3 -1]). Отримане положення [xy] є дійсним iff [xyz] ⊂ [0 1 .. 10], де z = x-y + 5.


Цікаво. Отже, ви перекладаєте вхід до цієї системи координат, виконуєте обчислення, а потім переводите назад? Акуратний.
AdmBorkBork

@AdmBorkBork досить багато, так
aditsu

1

Діалог APL, 72 байти

(6=|×/t,-/t←↑j[a⍳⊂⍞]-j←⊃,/i,¨¨↓∘i¨i-6)/a←⊃,/(11⍴⎕a~'J'),∘⍕¨¨⍳¨5+i⌊⌽i←⍳11

спробуйте

будує список aусіх дійсних комірок:'A1' 'A2' ... 'L6'

a використовується як для вводу, так і для виходу

будує список jвідповідних координат до aсистеми, де вісь x вздовж A6-L1і y вздовжF1-F11

уявна третя координата - це різниця перших двох

якщо вхідна комірка переведена на координати 0 0 0, лицар може переміститися до тих осередків, добуток коордів яких становить 6 або -6


0

Пітон 3,6, 149

H='abcdefghikl'
lambda f,r:[H[i]+str(j)for i,j in[(H.find(f)+p%4*s,int(r)+p//4)for p in[9,6,-1,-5,-11,-10]for s in(1,-1)]if 0<i<11if 0<j<12-abs(6-i)]

Анонімна функція, яка викликається двома рядками для файлу та рангу; повертає список рядків.

Безголівки:

def h(f,r):
    H='abcdefghikl'

    A = []
    for p in[9,6,-1,-5,-11,-10]:
        for s in(1,-1):
            i = H.find(f) + p%4*s
            j = int(r) + p//4
            A.append(i, j)

    B = []
    for i,j in A:
        if 0 < i < 11 and 0 < j < 12 - abs(6 - i):
            B.append(H[i] + str(j))

    return B
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.