เล่น Connect 4!


20

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

กระดานเป็นอาร์เรย์ 6x7 ซึ่งแต่ละเซลล์อาจว่างเปล่า ('') มีชิ้นส่วนของคุณ ('X') หรือชิ้นส่วนของคู่ต่อสู้ ('O') บอร์ดตัวอย่าง:

O      
XX    X
XOX  OO
XOO OXO
OXXOXXO
XOXOXOX

คุณต้องการเล่นในคอลัมน์ 3 (คอลัมน์คือ 0-6, หมายเลขจากซ้าย) สำหรับการชนะในแนวทแยง ดังนั้นคุณส่งออก:

3

รหัสของคุณจะต้องส่งออกหมายเลขคอลัมน์และจะต้องเป็นไปตามเกณฑ์ต่อไปนี้:

  1. คุณไม่สามารถเล่นในคอลัมน์ที่มี 6 ชิ้นอยู่ในนั้น
  2. หากมีการชนะอย่างน้อยหนึ่งครั้งคุณต้องเล่นอย่างใดอย่างหนึ่ง
  3. หากคุณสามารถป้องกันคู่ต่อสู้ไม่ให้ชนะในการย้ายครั้งต่อไปคุณต้องทำเช่นนั้น

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

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

รหัสที่สั้นที่สุดชนะ

ตัวอย่างที่ 1

      X
      O
      X
      O
 OOO  X
 XXX  O

คุณต้องเล่นทั้งคอลัมน์ 0 หรือ 4 เพื่อชนะ

ตัวอย่างที่ 2

      X
X     X
O     O
XOX  XO
XXO XOX
XXO XXO

คุณต้องเล่นคอลัมน์ 3 เพื่อป้องกันการชนะทันทีของคู่ต่อสู้

ตัวอย่างที่ 3

X      
XO     
OX    O
XO   XX
XXO OOO
OOO XXO

คุณไม่สามารถชนะหรือหยุดฝ่ายตรงข้ามไม่ให้ชนะดังนั้นคุณสามารถเล่นคอลัมน์ใดก็ได้ 1-6 (0 เต็ม)

ตัวอย่างที่ 4

X      
O      
X      
OOO    
XOX    
OXOX   

คุณไม่สามารถเล่นในคอลัมน์ 3 ได้เพราะจะทำให้คู่ต่อสู้ของคุณชนะทันที คุณอาจเล่นในคอลัมน์ 1-2 หรือ 4-6

คำตอบ:


9

C, 234 286 256 ตัวอักษร

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

รหัสนี้มีความอ่อนไหวมากต่อรูปแบบไฟล์อินพุต - แต่ละบรรทัดต้องมี 7 ตัวอักษร + ขึ้นบรรทัดใหม่
กระดานได้รับการปฏิบัติเหมือนเป็นเมทริกซ์ 8x8 แทนที่จะเป็น 7x6 คอลัมน์ที่ 8 มีการขึ้นบรรทัดใหม่และ 2 แถวพิเศษมีค่าศูนย์ดังนั้นพวกมันจึงไม่เข้าไปยุ่งเกี่ยวกับการแก้ปัญหา สิ่งเหล่านี้ช่วยได้จริง - เมื่อเลื่อนจากคอลัมน์ขวาสุดไปที่คอลัมน์ใหม่คุณจะทำหน้าที่ตรวจสอบขอบเขต

wตรวจสอบหนึ่งตำแหน่งสำหรับโอกาสที่จะชนะหรือบล็อก qควรเป็นเซลล์เพื่อตรวจสอบรอบ ๆ มันใช้การวนซ้ำเพื่อวนซ้ำ 4 ทิศทาง (เริ่มต้นที่ 9,8,7 และหลายต่อหลายครั้ง 1)
Cตรวจสอบลำดับของอักขระที่เหมือนกันเริ่มต้นqในทิศทางdทั้งไปและกลับ มันคืนค่าผลรวมของทั้งสองซีเควนซ์ (ไม่นับตำแหน่งเริ่มต้น) ดังนั้นหากส่งคืน 3 จะมีแถว 4

char B[99],q;
C(i,d){
    return B[d*i+++q]-B[q]?d>0?C(1,-d):0:1+C(i,d);
}
w(x){
    return x&&C(1,x>6?x:1)>2|w(x-1);
}
t(l,c,r,v){
    for(;c--;)B[q=c]&32&B[c+8]-32?r=w(9,B[c]=l)?v=c:v||r*t(79,l,0,1)?r:c,B[c]=32:0;
    return r;
}
main(){
    putchar(48+t(88,16+read(0,B+16,48),0,0)%8);
}

5

Python 2.x - 594 591 576 557 523 459 458 433 ไบต์

นี่คือสิ่งที่ดีที่สุดที่ฉันเคยประสบความสำเร็จ ฉันเดาว่ามันยากที่จะเอาชนะ C. ความท้าทายที่ยอดเยี่ยมฉันต้องพูด

r=range
f=[]
exec'f+=list(raw_input());'*6
def n(p):
 o,b,a,k=[],1,'O',lambda q:any([o[i:i+4]==list(q)*4for o in(f[x-x%7:],f[x%7::7])for i in r(3)]+[all(q==f[7*(y+u*i)+z+i]for i in r(4))for u,z,v,c in((1,0,3,4),(-1,3,6,3))for y in r(z,v)for z in r(c)])
 for x in r(42):
    if x>34<a>f[x]or x<35and f[x+7]>'0'>f[x]:f[x]=p;z=k(p)*b;o=z*[x]+o+[x]*(a==p or n(a)[1]);b-=z;f[x]=' '
 return o[0]%7,b
a,b,c,d=n('X')+n('O')
print(a,(c,a)[d])[b]

if-line (7 บรรทัด) มีการเยื้องของหนึ่งแท็บ SE ไม่ชอบแท็บ


2
ฉันใช้เวลามากเกินไปในการปรับปรุงสิ่งเหล่านี้ นอกจากนี้เวอร์ชัน 458 ไบต์ไม่ทำงานอย่างถูกต้องเช่น # 4 เอาไป 25 ไบต์และมันจะ มายากล.
seequ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.