เล่นเกม 4x4 Hex สมบูรณ์แบบ


10

พื้นหลัง

Hexเป็นเกมกลยุทธ์นามธรรมผู้เล่นสองคนที่เล่นบน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. ดัชนี zero-based (ตามที่ใช้ในภาพด้านบน)
  2. ดัชนีแบบอิงฐานเดียว
  3. สตริงอินพุตที่มีสตริงEถูกแทนที่ด้วยสตริงใดWหรือBคุณเลือกสำหรับเครื่องเล่นของคุณ

กฎระเบียบ

กลยุทธ์ของคุณจะต้องกำหนดไว้ล่วงหน้า คุณไม่จำเป็นต้องจัดการกับตำแหน่งของเกมที่ไม่สามารถเข้าถึงได้จากกระดานเปล่าโดยใช้กลยุทธ์ของคุณหรือตำแหน่งที่ชนะสำหรับผู้เล่นทั้งสองและคุณอาจชนกับเกมเหล่านั้น ในทางกลับกันบนกระดานที่สามารถเข้าถึงได้โดยใช้กลยุทธ์ของคุณคุณจะต้องกลับไปดำเนินการทางกฎหมาย

นี่คือโค้ดกอล์ฟดังนั้นจำนวนไบต์ที่น้อยที่สุดจึงชนะ ช่องโหว่มาตรฐานไม่ได้รับอนุญาต

การทดสอบ

ฉันได้เขียนคอนโทรลเลอร์ Python 3 เพื่อตรวจสอบความถูกต้องของรายการเนื่องจากมันน่าเบื่อมากที่ต้องทำด้วยมือ คุณสามารถค้นหาได้ที่นี่ รองรับรูปแบบอินพุตสามรูปแบบแรกและฟังก์ชั่น Python 3 (ฟังก์ชั่นในภาษาอื่นจะต้องถูกรวมเข้าไปในโปรแกรม) รูปแบบเอาต์พุตทั้งสามรูปแบบและเครื่องเล่นทั้งสอง หากกลยุทธ์ไม่ชนะก็จะส่งออกเกมที่แพ้ซึ่งคุณสามารถปรับแต่งโปรแกรมของคุณได้


ความท้าทายนี้ทำให้ฉันนึกถึงการพยายามบีบอัด Tic Tac Toe AI เมื่อฉันเขียนโปรแกรมเครื่องคิดเลข ticalc.org/archives/files/fileinfo/354/35408.html
Sparr

2
Incorrect response 'WWWWWWWWBBBBBBBB' to message 'WWWWWWWWBBBBBBBB'.ฉันน่าจะชนะไปนานแล้วหรือฉันผิด
เซบาสเตียนHöffner

@ SebastianHöffnerดูเหมือนว่ามีข้อบกพร่องในตัวควบคุม ฉันจะพยายามแก้ไขเมื่อมีเวลา
Zgarb

@ SebastianHöffnerข้อผิดพลาดควรได้รับการแก้ไขแล้ว
Zgarb

คำตอบ:


6

Marbelous, 973b

นี่คือการใช้กลยุทธ์ไร้สาระในคำถามอย่างไร้เดียงสา คาดว่าบอร์ดจะได้รับพารามิเตอร์ 16 commandline / mainboard เช่นเดียวกับบอร์ดhex.mbl B W E E E W E E E B E E E E E Eและมันจะเอาท์พุทตำแหน่ง zero-indexed ของการเคลื่อนไหวครั้งต่อไปของ white

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

Marbelous +1 (PPCG คิดว่าการเพิ่มตัวละครเหล่านี้ปรับปรุงความคิดเห็น)
Rohan Jhunjhunwala

1

Python 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 ตัวอักษร นี่คือ relict ตั้งแต่ฉันทำงานกับดัชนีลบและb[i+1:]ดังนั้นจะคืนค่ารูบอร์ดและส่วนที่เหลือที่ฉันคาดไว้ทำให้เป็นเรื่องสำคัญที่จะต้องตัดส่วนที่เหลือออก อีกวิธีหนึ่งก็คือการทำงานกับดัชนีบวกเช่นโดยการรับ(b.find('B')+16)%16แต่(+16)%16()[:16]เป็นหนึ่งไบต์มากกว่า

Ungolfed:

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])

ทดสอบ

เมื่อรันชุดทดสอบ hex คอนโทรลเลอร์ฉันพบปัญหาบางอย่าง:

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 หรือตอบด้วยบอร์ดเดียวกันกับบอร์ดเต็มควรตอบสนองที่ถูกต้อง ไม่แน่ใจว่าเกิดอะไรขึ้นที่นั่นไม่ได้ดำน้ำลึกนัก - ฉันแค่ต้องการตรวจสอบว่าฉันได้รับคดี "พิเศษ" ทั้งหมดหรือไม่ แต่เนื่องจากฉันไม่ต้องปกปิดสถานการณ์ที่มีคนเริ่มบนอวกาศ 4 หรือมากกว่านั้นมันไม่สำคัญเลย

85b

อย่างไรก็ตามหากฉันอนุญาตให้ตัวเองไม่ตรวจสอบบอร์ดเต็มรูปแบบ (นั่นคือการออกจากระบบ'E' in bฉันสามารถทำให้โค้ดง่ายขึ้นเพื่อใช้เพียง 85 ไบต์:

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.