แพ้นิ้วเท้า


18

เขียนโปรแกรมที่ a จะเล่นเกมของMisère tic-tac-toe นั่นคือเป้าหมายคือการบังคับให้คู่ต่อสู้ของคุณใช้สามในแถว

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

สมมติว่าบอร์ดมีหมายเลขดังนี้:

0|1|2
-----
3|4|5
-----
6|7|8

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

ผู้ชนะคือรหัสที่สั้นที่สุด คะแนนโบนัสถ้ามันเลือกแบบสุ่มจากการเคลื่อนไหวที่ดีเท่า ๆ กันเพื่อให้คาดเดาได้ยากขึ้น

คำตอบ:


10

Python 383 ตัวอักษร

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

บอร์ดBจะแสดงเป็นจำนวนเต็มโดยใช้สองบิตต่อหนึ่งตารางโดยมี00และ01แทนค่าว่าง10แทน O และ11แทน X. Mเป็นชุดของ bitmasks ที่มี01จุดสูญเสียสามเท่า ( 21= 0b010101= แถวบนสุดเป็นต้น) Xคำนวณหากสูญเสีย สามสำหรับkอยู่บนกระดาน Sminimax ค้นหาการเคลื่อนไหวที่เหมาะสมที่สุดสำหรับ X โดยส่งคืนคะแนนคู่หนึ่ง (1 = ชนะ, -1 = แพ้, 0 = เสมอ) และดัชนีสี่เหลี่ยม ^87381(= ^0b010101010101010101) พลิก X และ O ในขณะที่ปล่อยให้ช่องว่างที่ไม่มีการเปลี่ยนแปลง

คอมพิวเตอร์ไม่เคยสูญเสียดังนั้นฉันจึงไม่จำเป็นต้องรวมเช็คนั้น :)

อาจจะมีอัลกอริทึมที่ยึดกฎที่ง่ายกว่า / สั้นกว่า แต่ก็ใช้ได้


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