4x4 Hex의 완벽한 게임을 즐기십시오


10

배경

진수는 A의 경기 두 선수 추상 전략 게임이다 K×K육각형 타일의 마름모. 마름모의 반대편 두면은 흰색으로, 다른 두 개는 검은 색으로, 두 명의 플레이어 (흑백)는 교대로 비어있는 타일 위에 자신의 색의 토큰을 놓습니다. 색상의 반대편 사이에 경로를 구성하는 플레이어가 먼저 승리합니다. 게임은 무승부로 끝날 수 없으며, 첫 번째 플레이어는 보드 크기에 관계없이 승리 전략을 가지고있는 것으로 알려져 있습니다 (자세한 내용은 Wikipedia 페이지 참조).

작업

이 과제에서는 보드 크기를에 고정하고 보드를 K = 4다음 표로 나타냅니다. 굵은 선은 인접한 타일을 나타냅니다.

4x4 그리드.

당신의 임무는 첫 번째 플레이어를위한 승리 전략을 만들어내는 것입니다. 이것은 상대 플레이어가 합법적으로 움직일 때마다 승리가되어야한다는 것을 의미합니다. 귀하의 입력은 게임 위치 (보드에 토큰 배열)이며, 출력은 아래에 지정된 형식으로 합법적 인 이동입니다. 우승 전략을 직접 찾으려면이 스포일러를 읽지 마십시오.

백인이 먼저 가정 할 때 가능한 승리 전략의 개요. 먼저 5를 선택하십시오. 그 후, 5에서 맨 아래 행까지의 경로가 있거나 검은 색이 어느 시점에서 0 또는 1을 선택하는 경우 0 또는 1이 비어있는 것을 선택하여 응답하십시오. 검은 색이 9 또는 13을 선택하는 경우 10을 선택한 다음 14 또는 15 중 비어있는 것을 선택하십시오. 검은 색이 9, 13 또는 14를 선택하지 않으면 9를 선택하고 다음 중 13 또는 14가 비어있는 것을 선택하십시오. 검정색이 14를 선택하면 15를 선택하여 응답하십시오. 다음으로 비어있는 경우 10을 선택하십시오. 검은 색이 10을 선택하면 11로 응답하고, 검은 색으로 6을 선택하면 7로 응답하고 다음 2 또는 3 중 비어있는 것을 응답하십시오. 검은 색이 6을 선택하지 않으면 선택하면 5에서 아래쪽 행까지의 경로가됩니다.

입력과 출력

입력은 16 자 문자열로 WBE, 흰색, 검은 색 및 빈을 나타냅니다. 그것들은 위에 열거 된 것처럼 보드의 타일을 나타냅니다. 다음 중에서 입력 방법 (출력 방법도 결정)을 선택할 수 있습니다.

  1. STDIN에서 입력하고 STDOUT으로 출력합니다.
  2. 하나의 명령 행 인수로 입력하고 STDOUT에 출력합니다.
  3. 16 개의 단일 문자 명령 행 인수로 입력하고 STDOUT에 출력하십시오.
  4. 명명 된 함수의 인수로 입력하고 반환 값으로 출력합니다.

당신의 결과물은 당신의 차례가되어 다음 토큰을 놓을 타일을 나타냅니다. 다음과 같은 출력 형식 중에서 선택할 수 있습니다.

  1. 0부터 시작하는 인덱스 (위 그림에서 사용).
  2. 1 기반 색인.
  3. 입력 문자열 중 하나를 E대체 W하거나 B플레이어에 대해 선택한 문자열 .

규칙

전략은 결정 론적이어야합니다. 당신은 당신의 전략을 사용하여 빈 보드에서 도달 할 수없는 게임 위치, 또는 어느 한 플레이어에 이미 승리 한 위치를 올바르게 처리 할 필요가 없으며, 충돌 할 수 있습니다. 반대로, 전략을 사용하여 접근 할 수있는 보드에서는 법적 조치를 취해야합니다.

이것은 코드 골프이므로 가장 낮은 바이트 수가 이깁니다. 표준 허점은 허용되지 않습니다.

테스팅

수동으로 수행하는 것이 지루하기 때문에 항목 유효성 검사를 위해 Python 3 컨트롤러를 작성했습니다. 여기에서 찾을 수 있습니다 . 처음 세 가지 입력 형식과 Python 3 함수 (다른 언어의 함수는 프로그램에 래핑해야 함), 세 가지 출력 형식 및 두 플레이어를 모두 지원합니다. 전략이 이기지 않으면 찾은 게임이 사라 지므로 프로그램을 조정할 수 있습니다.


이 과제는 계산기 프로그램을 작성할 때 박하 사탕 AI를 압축하려고 시도했음을 상기시킵니다. ticalc.org/archives/files/fileinfo/354/35408.html
Sparr

2
Incorrect response 'WWWWWWWWBBBBBBBB' to message 'WWWWWWWWBBBBBBBB'.오래 전에 이겼어야합니까, 아니면 내가 틀렸습니까?
Sebastian Höffner 2016 년

@ SebastianHöffner 컨트롤러의 버그처럼 보입니다. 시간이 있으면 문제를 해결하려고합니다.
Zgarb 2016 년

@ SebastianHöffner 버그가 수정되었습니다.
Zgarb 2016 년

답변:


6

마벨 러스, 973b

이것은 질문에서 암시 된 전략의 순진한 구현입니다. 보드는 16 개의 명령 줄 / 메인 보드 매개 변수로 제공 될 것으로 예상되며 hex.mbl B W E E E W E E E B E E E E E E화이트의 다음 이동 위치를 인덱스없이 0으로 출력합니다.

00 }1 }0
&G B? W!
&0 &G &G
!!
00 }0 }1
&H B? W!
&1 &H &H
!!
.. }D .. }9 }9 }D }E }A }D }9 }A .. }E }F }5
}9 B! }E E? W? E? .. E? B? B? W? .. E? .. E?
B! ?0 B! &M &N &O E? &I \\ .. &J .. &K E? &5
?0 ++ ?0 &9 .. &D &P &A &I /\ &J .. &E &L !!
++ .. ++ !! .. !! &E !! \/ &L /\ &K !! &F
\\ .. // .. .. .. !! .. .. \/ .. \/ .. !!
.. =3 \/
&M /\ &N
\/ &O /\ &P
}0 }1 }6 .. }6 .. }7 &7 }2 }3 }A }A }B }E }F
..
..
..
..
..
..
..
..
..
.. .. .. .. .. .. .. .. .. .. .. .. .. B? W!
.. .. .. .. .. .. .. .. .. .. .. .. .. &Q &Q
.. .. .. .. B? .. E? W? E? .. E? B? E? &F \/
.. .. .. &S /\ &T &S &T &U E? &A &R &R !!
.. .. .. &7 .. .. \/ .. &2 &V !! &B \/
.. .. .. !! .. .. &U /\ &V &3 .. !!
.. .. .. .. .. .. .. .. .. !!
.. .. ..
.. .. E?
E? .. &6
&X E? !!
!! &Y
.. !!
}4 }8 }C
\/ \/ \/
30 30 31 31 32 33 35 36 37 39 31 30 31 31 31 33 31 34 31 35
&0 &X &1 &Y &2 &3 &5 &6 &7 &9 &A &A &B &B &D &D &E &E &F &F
:W?
}0
^4
=1
{0
:B?
}0
^0
=0
{0
:E?
}0
^1
=0
{0
:W!
}0
^4
=0
{0
:B!
}0
^0
>0
{0

더 나은 분기 및 코드 재사용 제거로 약 200자를 골프로 칠 수 있다고 생각합니다.


16 명령 줄 인수 옵션을 추가하고 검증 스크립트를 업데이트하여이 솔루션을 테스트 할 수 있습니다.
Zgarb 2016 년

Marbelous +1 (PPCG는이 문자들을 추가하면 주석이 개선되었다고 생각합니다)
Rohan Jhunjhunwala

1

파이썬 3, 100b

b=input()
i=b.find('B')
if b[i]in'BW'and'E'in b:i-=1+(b[i-1]is'W')*4
print((b[:i]+'B'+b[i+1:])[:16])
  • 플레이어 : BLACK
  • 방법 : STDIN / STDOUT, MODIFIED_BOARD

전략은 먼저 B보드에서를 검색 하는 것입니다. 아무것도 없으면 -1파이썬에서와 동일한을 반환합니다 last index. 따라서 빈 보드에서 첫 번째 색인은 index=-1입니다.

왼쪽의 필드 ( index-1)가 비어 있으면 다음 이동은 그곳으로 이동합니다. 가져 가면 왼쪽으로 올라갑니다. 나는 움직일 필요가 없다. 만약 그렇게한다면, 나는 템포를 잃고 게임을 잃을 것이다.

전체 보드에서 ( E어디서나) 나는 움직이지 않습니다.

print처음에는 조금 이상한 것 같다 : 나는 (내가 슬라이스를 통해 할)하지만 내가 16 개 문자를 잘라하는 데 필요한 새로운 보드를 구성해야합니다. 이것은 음의 인덱스로 작업하기 때문에 유물 b[i+1:]입니다. 따라서 홀 보드와 기대하는 나머지 부분을 반환하므로 나머지를 잘라내는 것이 중요합니다. 또 다른 방법은 예를 들어을 가져 와서 양의 인덱스로 작업하는 (b.find('B')+16)%16것이었지만 (+16)%161 바이트 이상 ()[:16]입니다.

언 골프 드 :

board = input()
index = board.find('B')
if board[index] in 'BW' and 'E' in board:
    index -= 1 + (board[index-1] is 'W') * 4
print((board[:index] + 'B' + board[index+1:])[:16])

테스트

16 진수 컨트롤러 테스트 스위트를 실행할 때 이상한 동작이 발생했습니다.

OUT: EEEEEEEEEEEEEEEB
OUT: WEEEEEEEEEEEEEBB
OUT: WWEEEEEEEEEEEBBB
OUT: WWWEEEEEEEEEBBBB
OUT: WWWWEEEEEEEBBBBB
OUT: WWWWWEEEEEBBBBBB
OUT: WWWWWWEEEBBBBBBB
OUT: WWWWWWWEBBBBBBBB
OUT: WWWWWWWWBBBBBBBB

Incorrect response 'WWWWWWWWBBBBBBBB' to message 'WWWWWWWWBBBBBBBB'.

나는 네 번째 턴 이후에 이겼거나 같은 보드로 풀 보드에 응답하는 것이 올바른 응답이어야한다고 생각합니다. 무엇이 잘못되었는지 잘 모르고 더 깊이 뛰어 들지 않았습니다. 모든 "특별한"사례를 다루 었는지 확인하고 싶었습니다. 그러나 누군가가 4 번 정도 공간에서 시작하는 상황을 은폐 할 필요가 없으므로 어쨌든 중요하지 않습니다.

85b

그러나 전체 보드를 확인하지 않으면 'E' in b85 바이트 만 사용하도록 코드를 단순화 할 수 있습니다.

b=input();i=b.find('B')
if i!=-1:i-=1+(b[i-1]is'W')*4
print((b[:i]+'B'+b[i+1:])[:16])

이것은 다음과 같이 이어질 것입니다 :

Incorrect response 'WWWBWWWWBBBBBBBB' to message 'WWWWWWWWBBBBBBBB'.

이것은 계산되거나 계산되지 않을 수 있으며, 그것이 유효한 움직임이 아니라는 것을 알았으므로 더 길지만 더 정확한 답을 찾기로 결정했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.