为我的骑士动作而努力


16

六角象棋描述了在棋盘上玩的一系列象棋变体,其中棋盘格是六边形而不是传统的正方形。有许多这样的变体。在这一挑战中,我们将重点介绍最常见的格林斯基(Gliński)的变体。

棋盘由三种颜色组成(因此相同的颜色不会共享边缘),六边形的边缘面向玩家。板具有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
这个坐标系是魔鬼的工作。
Martin Ender

2
@MartinEnder指出如果您在Hexagony中这样做,则:)
Erik the Outgolfer '17

我觉得我可以通过将两个轴重新定义为水平轴和60度对角线,将其转换为另一个向量空间,然后使用常规移动,然后使用线性代数将其转换回去,但是我认为这很复杂:P我同意坐标系是我在此站点上看到的最邪恶的东西。:P
HyperNeutrino

Answers:


11

JavaScript(ES6),184个字节

用currying语法将文件F作为字符,将等级R作为整数(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]ÿ[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 + YX-Y来完成的

X / Y

如果以下所有比较均正确,则坐标有效:

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

我们还应该验证X[0 .. 10]中。未明确完成此操作,因为s[X]不确定的,如果它不是,这最终导致在被过滤掉了一个falsy值。

步骤#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%%

调整坐标系,尽管以不同于@Arnauld答案的方式。该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))

我以为我可以将Batch解决方案移植到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])。当[xyz]⊂[0 1 .. 10]时,得到的[xy]位置是有效的,其中z = x-y + 5。


有趣。因此,您将输入转换为该坐标系,执行计算,然后转换回去?整齐。
AdmBorkBork '17

@AdmBorkBork差不多,是的
aditsu

1

Dyalog 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 用于输入和输出

在x轴沿y 的系统中建立j对应坐标的列表aA6-L1F1-F11

虚构的第三坐标是前两个坐标的差

如果将输入单元格转换为坐标0 0 0,则骑士可以移动到坐标乘积为6或-6的那些单元格


0

Python 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.