สั่งซื้อและความโกลาหลและ Codegolf


10

คำสั่งซื้อและความโกลาหลเป็นรูปแบบของ Tic-Tac-Toe ที่เล่นบนกระดาน 6x6 สิ่งที่ทำให้เกมมีความโดดเด่นอย่างไรก็ตามผู้เล่นทั้งสองสามารถวาง X หรือ O! เทิร์นแต่ละครั้ง (เริ่มต้นด้วยคำสั่งซื้อ) ผู้เล่นวาง X หรือ O ในช่องว่างใด ๆ
การชนะนั้นง่ายมาก คำสั่งซื้อจะชนะหากมี 5 Xs หรือ Os (แนวตั้งแนวนอนหรือแนวทแยงมุม) ในแถวบนกระดาน ความโกลาหลชนะหากบอร์ดเต็มและไม่มีสตริง 5 X หรือ OS บนกระดาน งานของคุณ? เพราะนี่คือProgramming Puzzles และ Code Golf คุณจะเขียนโปรแกรมเกมและเล่นกอล์ฟ

กฎระเบียบ

  • คุณต้องยอมรับอินพุตเป็นx y tตำแหน่งxและyพิกัดและtเป็นชนิดไทล์ ( XหรือO) พิกัดเริ่มต้นด้วย0 0ที่มุมบนซ้ายและเพิ่มขึ้นเป็น5 5(มุมล่างขวา)
  • คุณต้องยอมรับที่qจะออกและพิมพ์INVALIDถ้าผู้ใช้ป้อนพิกัดที่ไม่ถูกต้อง, ไทล์, อินพุตใด ๆ ที่ไม่อยู่ในรูปแบบของx y tหรือพยายามวางไทล์ที่มีอยู่แล้ว (ยกเว้นเพียงอย่างเดียวqเนื่องจากโปรแกรมจะออกจากโปรแกรม)
  • P1 WINSหากสั่งซื้อชนะคุณจะเอาท์พุท P2 WINSหากความโกลาหลชนะคุณจะเอาท์พุท
  • สั่งซื้อจะต้องไปก่อน
  • .พื้นที่ว่างเปล่าเป็นตัวแทนจาก
  • ไทล์เป็นXและO(ตัวพิมพ์ใหญ่) คุณไม่ต้องยอมรับตัวพิมพ์เล็ก แต่จำเป็นต้องใช้ตัวพิมพ์ใหญ่
  • .XOบอร์ดของคุณเพียงจะต้องประกอบด้วย
  • คุณกำลังจำลองผู้เล่นทั้งสองเล่นเกมโดยไม่ได้รับบอร์ดและตรวจสอบว่าใครชนะ มันยอมรับการย้ายเป็นอินพุตจากนั้นพิมพ์กระดานรับการย้ายอีกครั้งและต่อ ๆ ไปจนกว่าผู้เล่นคนหนึ่งจะชนะ

บอร์ดเริ่มต้นมีลักษณะดังนี้:

......
...... 
......
......
......
...... 

และหลังจากอินพุตของผู้เล่นคนแรก (คำสั่งซื้อ) 1 2 Xมันควรมีลักษณะเช่นนี้:

......
...... 
.X....
......
......
......  

ในทำนองเดียวกันเมื่อผู้เล่นคนถัดไป (ความโกลาหล) เข้า3 3 Oก็จะมีลักษณะเช่นนี้:

......
...... 
.X....
...O..
......
......  

และสิ่งนี้จะดำเนินต่อไปจนกว่าผู้เล่นคนหนึ่งจะชนะ

เช่นเคยช่องโหว่มาตรฐานที่นำความสนุกออกมาจากทุกสิ่งถูกห้าม

ผู้ชนะคือผู้ที่มีรหัสสั้นที่สุดในวันที่ 15 มิถุนายน 00:00 UTC (ประมาณหนึ่งเดือนหลังจากที่โพสต์ความท้าทายนี้)


จะเป็นอย่างไรถ้าผู้เล่นพิมพ์ในตำแหน่งที่ได้เล่นไปแล้ว?
Loovjo

@Loovjo มันจะกลับINVALIDมา ฉันได้แก้ไขแล้วในตอนนี้ขอบคุณ
ASCIIThenANSI

1
ควรออกจากเกมเมื่อตรวจพบไพ่ 5 ใบในแถว?
Kyle Kanos

1
บางทีฉันอาจมองข้าม แต่ต้องพิมพ์บอร์ดไปที่หน้าจอหรือเพียงตรวจสอบสถานะของบอร์ดและเอาท์พุทที่ผู้เล่นชนะ?
Kodos Johnson

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

คำตอบ:


1

PHP, 316

นี่คือการส่งของฉัน มันจะต้องมีการดำเนินการโดย php ในบรรทัดคำสั่ง

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

<?for(;$i++<6;)$b.='......|';while(($a=trim(fgets(STDIN)))!='q'){preg_match('/^([0-5]) ([0-5]) ([XO])$/',$a,$d)&($b[$c=$d[2]*7+$d[1]]=='.')?$b[$c]=$d[3]:print"INVALID\n";echo str_replace("|","\n",$b); foreach([0,5,6,7]as$e)preg_match('/(X|O)(.{'.$e.'}\1){4}/',$b)-1?:die("P1 Wins");strstr($b,'.')?'':die("P2 Wins");}

และนี่คือรหัสที่ไม่ตีกอล์ฟ:

<?php
error_reporting(E_ALL & ~E_NOTICE);

for(;$i++<6;)$b.='......|';
while(($a=trim(fgets(STDIN)))!='q'){

    #Validate and assign 
    preg_match('/^([0-5]) ([0-5]) ([XO])$/',$a,$d)&($b[$c=$d[2]*7+$d[1]]=='.')?$b[$c]=$d[3]:print"INVALID\n";

    #Output
    echo str_replace("|","\n",$b); 

    #Check if Order wins
    foreach([0,5,6,7]as$e) {
        preg_match('/(X|O)(.{'.$e.'}\1){4}/',$b)-1?:die("P1 Wins");
    }

    #Check if Chaos wins
    strstr($b,'.')?'':die("P2 Wins");
}

ใช่ประกาศเป็นเรื่องปกติ
ASCIIThenANSI

4

JavaScript, 360

แก้ไขเกมแบบอินเทอร์แอคทีฟที่แก้ไขควรรันแม้จะอยู่ใน MSIE

ตามที่ได้รับการร้องขอเกมที่ใช้ข้อความป้อนผ่านป๊อปอัพเอาท์พุทในคอนโซล (เพื่อให้มีแบบอักษร monospaced)

ออกจากเกมด้วย 'q' หรือคลิก 'ยกเลิก' ที่พร้อมท์

ไม่ใช้คุณสมบัติ ES5 ควรรันบนเบราว์เซอร์ตัวดัดแปลง (ซึ่งคุณสามารถมีแผงคอนโซล JS)

b='\n......'.repeat(6).split('');
for(h=t=0;!h&t<36;)
{
  i=prompt();
  if(i=='q')i=null;
  i=i.match(/([0-5]) ([0-5]) ([XO])/);
  m='INVALID';
  if(b[p=i?i[2]*7-~i[1]:0]=='.')
  {
    ++t;
    b[p]=i[3];
    m=b.join('');
    for(x=z='',c=0;c++<6;)
      for(x+='_',z+='_',r=0;r<6;r++)
        x+=b[c+r*7],z+=b[c<4?c-1+r*8:c+1+r*6];
    h=(/X{5}|O{5}/.test(b.join('')+x+z))
  }
  console.log(m);
}
console.log("P"+(2-h)+" WINS")

ทีนี้รุ่นอินเทอร์แอคทีฟและกราฟิกที่สนุกสนานยิ่งขึ้นให้เรียกใช้ข้อมูลโค้ดเพื่อเล่น


รุ่นที่คลิกได้ดี! (ข้อเสนอแนะเล็ก ๆ น้อย ๆ : คุณสามารถใช้การคลิกขวา / ซ้ายแทนปุ่มตัวเลือก)
xebtl

@ xebtl ฉันจะลองดู
edc65

1

Java, 565 ตัวอักษร D:

public class M{public static void main(String[]r){int[]p=new int[36];int u=0;for(;;){String l=new java.util.Scanner(System.in).nextLine();if(l == "q")break;int a=l.charAt(0)-'0'+(l.charAt(2)-'0')*6,i=p[a]==0?1:0;if(i>0)p[a]=l.charAt(4);u+=i;r(i==0?"INVALID\n":"");if(u==36){r("P2 WINS");break;}for(int x=0;x<6;x++)for(int y=0;y<6;y++)for(int d=0;d<3;d++)try{int e=1,c=p[x+y*6],z=x,h=y;if(c=='X'||c=='Y'){for(;e<6;e++){if(d%2==0)z++;if(d>0)h++;if(p[z+h*6]!=c)break;}if(e==5){r("P1 WINS");return;}}}catch(Exception e){}}}static void r(Object o){System.out.print(o);}}

นี่อาจเป็นโค้ดกอล์ฟที่ยาวที่สุดเท่าที่เคยมีมา ฉันไม่เก่งในเรื่องนี้


1

อ็อกเทฟ 453

format plus 'XO.'
disp(F=zeros(6))
r=@()fread(0,1);R=@()r()-47;q=@(m)printf(m)&&quit;e=@()q("INVALID");l=@(n)n<1||n>6&&e();s=@()r()==32||e();w="P1 WINS";f=@(v)abs(sum(v))==22.5&&q(w);g=@(m)any(abs(sum(m))==22.5)&&q(w);d=@diag;while 1
i=R();i==66&&quit;l(i);s();l(j=R());s();F(j,i)&&e();abs(v=R()-36.5)==4.5||e();F(j,i)=v;disp(F)
r();f(d(F,-1));f(d(F,0)(2:6));f(d(F,0)(1:5));f(d(F,1));g(F(1:5,:));g(F(2:6,:));g(F(:,1:5)');g(F(:,2:6)');F&&q("P2 WINS");end

การใช้งานค่อนข้างตรงไปตรงมาเป็น "เคล็ดลับ" ที่แท้จริงเพียงอย่างเดียวที่ใช้format plusในการดูแลการพิมพ์ นี่คือเวอร์ชันที่มีความคิดเห็น:

format plus 'XO.'               # this is where the magic happens

## initialize and print empty board
disp(F=zeros(6))

## shortcuts
r=@()fread(0,1);
R=@()r()-47;
q=@(m)printf(m)&&quit;
e=@()q("INVALID");
l=@(n)n<1||n>6&&e();
s=@()r()==32||e();
w="P1 WINS";
f=@(v)abs(sum(v))==22.5&&q(w);
g=@(m)any(abs(sum(m))==22.5)&&q(w);
d=@diag;

while 1
  i=R();                        # read index 1
  i==66&&quit;                  # ‘q’?
  l(i);                         # check bounds
  s();                          # read and check space
  l(j=R());                     # read and check index 2
  s();                          # read and check space
  F(j,i)&&e();                  # square already filled?
  abs(v=R()-36.5)==4.5||e();    # valid mark?
  F(j,i)=v;                     # assigndisp(F)                       # and print board
  r();                          # read off newline

  ## check diagonals
  f(d(F,-1));
  f(d(F,0)(2:6));
  f(d(F,0)(1:5));
  f(d(F,1));

  ## check rows
  g(F(1:5,:));
  g(F(2:6,:));

  ## check columns
  g(F(:,1:5)');
  g(F(:,2:6)');

  ## check chaos
  F&&q("P2 WINS");
end

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

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

F =

......
......
......
......
......
......

นอกจากนี้ฉันตีความว่าการย้ายแต่ละครั้งจะมีการแยกกัน


ตัวอย่างการทำงานร่วมกัน ( -qสวิตช์เป็นเพียงการปราบปรามส่วนหัวของคู่):

$ octave -q order_chaos.m 
......
......
......
......
......
......
3 3 X
......
......
......
...X..
......
......
2 3 O
......
......
......
..OX..
......
......
3 3 O
INVALID

การย้ายที่ไม่ถูกต้องทำให้โปรแกรมออก (ไม่แน่ใจว่าตั้งใจหรือไม่)


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

@ ASCIIThenANSI เพียงแค่นั้น โดยคาดว่าการย้ายแบบฟอร์มแต่ละครั้งx y tในบรรทัดแยกต่างหาก (และไม่มีอินพุตอื่น)
xebtl

และมันจะพิมพ์บอร์ดหลังจากป้อนข้อมูลทุกครั้งหรือไม่
ASCIIThenANSI

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