quine-ish โอเอกซ์


19

เขียนโปรแกรมในภาษาที่คุณเลือกซึ่งเล่นเกม tic-tac-toe ที่สมบูรณ์แบบบนกระดาน 3 * 3 กับผู้เล่นคนหนึ่ง อย่างไรก็ตามการย้ายทุกครั้งจะต้องเป็นโปรแกรมที่แตกต่างซึ่งสร้างขึ้นจากการวนซ้ำก่อนหน้านี้

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

การตรวจสอบความเคลื่อนไหวนั้นไม่จำเป็นคุณสามารถถือว่าคู่ต่อสู้ของมนุษย์เล่นได้อย่างเป็นธรรม

โดยทั่วไปคุณมีโปรแกรมที่สอดคล้องกับสถานะของบอร์ด สถานะถูกพิมพ์ด้วยวิธีที่รู้จัก แต่อย่างน้อยคาดว่าจะมีรายละเอียดในระดับต่อไปนี้:

X..
00X
x..

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

ในตอนท้ายของเกมคุณจะต้องพิมพ์ผลการแข่งขัน (ไม่ว่าคุณจะชนะหรือเสมอ) ในรูปแบบที่พิสูจน์ได้อย่างชัดเจน

โดยการเล่นที่สมบูรณ์แบบฉันหมายถึงโปรแกรมจะต้องไม่แพ้และถ้ามีความเป็นไปได้ที่จะบังคับให้ชนะมันควรจะชนะ

รหัสที่สั้นที่สุดชนะผู้ชนะจะถูกเลือกอย่างน้อย 10 วันหลังจากรายการที่ถูกต้องครั้งแรก

คุณจะได้รับคะแนนลดลง 10% หากโปรแกรมของคุณสามารถจัดการสิ่งปลูกสร้างและเริ่มต้นการทำซ้ำครั้งต่อไป (ฉันรู้ว่ามันอาจจะไม่คุ้มค่าที่สุด) แน่นอนว่าตัวโปรแกรมเองต้องถูกยกเลิกเมื่อเวลาที่การทำซ้ำครั้งถัดไปยอมรับการย้ายจากผู้ใช้

หากคุณใช้อุบายแปลก ๆ แปลก ๆ โปรดโพสต์คำอธิบายสั้น ๆ พร้อมรหัสของคุณ


2
ความท้าทายดี แต่ฉันคิดว่าฉันจะยกเลิก
John Dvorak

"ทุกย่างก้าวจะต้องมีโปรแกรมที่แตกต่าง" คุณหมายถึง "แต่ละเกมจะต้องเริ่มต้นและจัดการโดยอินสแตนซ์ใหม่ที่แตกต่างของโปรแกรมดั้งเดิม" หรือไม่?
DavidC

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

คำตอบ:


13

Perl, 933 ตัวอักษร

$m=<<'';$_='         ';
sub h{/^(?:...)*(\d)\1\1/|/^.?.?(\d)..\1..\1/|/(\d)...\1...\1/|/^..(\d).\1.\1/&&$1}
sub r{substr($_,$p-1,1)=pop}sub p{my$w=pop;my@b=(0,h==$w||h&&-1);if(!$b[1]&&/ /){$b[1]=-9;
while(/ /g){local($_,$p)=($_,pos);r$w;$r=-(p($w^1))[1];@b=($p,$r)if$r>$b[1]}}@b}
if(($w=h||!/ /)||!@ARGV){$w--&&print+(nobody,X,O)[$w]," wins\n";s/(...)/$1\n/g;
tr/ 23/.XO/;print}else{$w=3;$w^=1for/\d/g;($p=pop)?r($w^1)&&!h&&(($p)=p$w)&&r$w:s/ /2/;
print"\$m=<<'';\$_='$_';\n$m\n$m"}

sub h{/^(?:...)*(\d)\1\1/|/^.?.?(\d)..\1..\1/|/(\d)...\1...\1/|/^..(\d).\1.\1/&&$1}
sub r{substr($_,$p-1,1)=pop}sub p{my$w=pop;my@b=(0,h==$w||h&&-1);if(!$b[1]&&/ /){$b[1]=-9;
while(/ /g){local($_,$p)=($_,pos);r$w;$r=-(p($w^1))[1];@b=($p,$r)if$r>$b[1]}}@b}
if(($w=h||!/ /)||!@ARGV){$w--&&print+(nobody,X,O)[$w]," wins\n";s/(...)/$1\n/g;
tr/ 23/.XO/;print}else{$w=3;$w^=1for/\d/g;($p=pop)?r($w^1)&&!h&&(($p)=p$w)&&r$w:s/ /2/;
print"\$m=<<'';\$_='$_';\n$m\n$m"}

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

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

...
...
...

เรียกใช้โปรแกรมด้วยอาร์กิวเมนต์ระหว่าง 1 ถึง 9 เพื่ออ้างสิทธิ์ในตารางนั้นเมื่อคุณย้าย โปรแกรมจะย้ายตัวเองแล้วออกสคริปต์แทนที่ด้วยสถานะใหม่ ตัวอย่างเช่น:

$ perl ./qttt 5 > ./qttt-2
$ perl ./qttt-2
O..
.X.
...

ในเทิร์นแรกเท่านั้นคุณอาจให้การย้าย0เพื่อระบุว่าคอมพิวเตอร์ควรทำการย้ายครั้งแรก Xโปรดทราบว่าผู้เล่นคนแรกจะเป็น

เมื่อเกมจบการแสดงผลจะรวมถึงบันทึกย่อของเอฟเฟกต์:

$ perl ./qttt-4 6 > ./qttt-5
$ perl ./qttt-5
O wins
OXX
OOX
X.O

โปรแกรมทำงานโดยทำการค้นหา minimax มาตรฐานของแผนผังเกม (Tic-tac-toe เป็นเกมที่มีขนาดเล็กพอที่สามารถสร้างทรีเกมเต็มรูปแบบได้ทุกครั้ง) ข้อยกเว้นคือเมื่อคอมพิวเตอร์เคลื่อนที่ก่อน - ในกรณีนี้การเริ่มต้นครั้งแรกไปที่มุมบนซ้ายนั้นยาก - รหัส

โปรดทราบว่าโปรแกรมนี้ทำงานในลักษณะของ quine ที่เหมาะสม - สคริปต์ไม่สามารถเข้าถึงไฟล์ต้นฉบับของตัวเองเพื่อผลิตผลลัพธ์


1
มันสวยงาม! ฉันไม่ได้ตระหนักว่าฉันกำลังจ้องมองที่นี่ขนาดใหญ่หมอเป็นเวลานานจากนั้นก็ทำสองครั้ง
Jesse Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.