จำลอง 'การต่อสู้' ในเกมไพ่ 'Oorlog'


15

ลองสร้างแบบจำลองสำหรับแง่มุมในเกมไพ่ซึ่งโดยส่วนตัวแล้วฉันรู้จักชื่อชาวดัตช์ 'Oorlog' (แปลเป็น 'สงคราม')

'Oorlog' ทำงานอย่างไร

ไพ่สองสำรับ (รวมถึง Jokers สองอัน) แบ่งเท่า ๆ กันระหว่างจำนวนผู้เล่นที่เล่น ผู้เล่นแต่ละคนจะสับไพ่ของตนเองวางคว่ำหน้าพวกเขาและผู้เล่นทุกคนเปิดไพ่ใบแรกของหุ้นในเวลาเดียวกัน
ผู้ชนะของ 'การต่อสู้' นั้นถูกกำหนดโดยค่าของไพ่ตามกฎเหล่านี้: Joker / Ace เอาชนะ King; กษัตริย์เอาชนะราชินี ราชินีเอาชนะแจ็ค; แจ็คเอาชนะ 10; 10 เอาชนะ 9; .... นอกจากนี้ทั้ง 2 และ 3 ยังสามารถเอาชนะ Ace / Joker กฎสุดท้ายอาจนำไปสู่รอบที่ 2 หรือ 3 ชนะ Ace หรือ Joker, Ace หรือ Joker ชนะการ์ดอื่น ๆ ซึ่งจะชนะ 2 หรือ 3 ในกรณีนี้ 2 หรือ 3 ชนะการต่อสู้
(สูทไม่เกี่ยวข้องในเกมไพ่นี้)

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

ตัวอย่าง 'การต่อสู้' กับผู้เล่นสามคน:

  1. 4, 8, แจ็ค:
    แจ็คชนะ
  2. 7, เอซ, ราชินี:
    เอซชนะ
  3. 10, 10, King:
    King ชนะ
  4. 3, Joker, 2:
    3 ชนะ
  5. Ace, Joker, 2:
    2 ชนะ
  6. 3, Queen, Ace:
    3 ชนะ
  7. Queen, Queen, 9:
    Queen & Queen กำลังมี 'สงคราม' ดังนั้นจึงดำเนินการต่อด้วยไพ่ใหม่สองใบ: 4, 8;
    8 ชนะ
  8. 4, 4, 4:
    ทุกคนมี 'สงคราม' ดังนั้นมันจะดำเนินต่อไปด้วยไพ่ใหม่สามใบ: 8, Ace, 2;
    2 ชนะ
  9. แจ็ค, 5, แจ็ค:
    แจ็ค & แจ็คกำลังมี 'สงคราม' ดังนั้นจึงยังคงมีไพ่ใหม่สองใบ: 5, 5;
    5 & ​​5 ก็เท่ากันดังนั้น 'สงคราม' จะดำเนินต่อไปอีกครั้งด้วยไพ่ใหม่สองใบ: 10, คิง;
    กษัตริย์ชนะ
  10. Joker, Joker, Ace:
    ทุกคนมี 'สงคราม' ดังนั้นจึงดำเนินการต่อด้วยการ์ดใหม่สามใบ: 9, 7, 9;
    9 & 9 ก็เท่ากันดังนั้น 'สงคราม' จะดำเนินต่อไปด้วยไพ่ใหม่สองใบ: แจ็ค, 3;
    แจ็คชนะ

ดังนั้นเข้าสู่ความท้าทายรหัส:

การป้อนข้อมูล:

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

เอาท์พุท:

STDOUT ดัชนีของผู้เล่นที่ชนะการต่อสู้
คุณสามารถเลือกได้ว่าคุณต้องการให้เป็นศูนย์การจัดทำดัชนี (เช่น0, 1หรือ2) หรือหนึ่งในการจัดทำดัชนีผลผลิต (เช่น1, 2, 3)

กฏท้าทาย:

  • อินพุตจะเป็นอาร์เรย์ / สตริงเดี่ยวที่แทนอาร์เรย์ ดังนั้นคุณไม่สามารถมีอาร์เรย์ของอาร์เรย์เพื่อทำให้มันง่ายขึ้น คุณไม่สามารถมีรายการตัวแทนสำหรับการ์ดที่ไม่ได้มีส่วนร่วมในสงคราม
  • เราใช้สัญลักษณ์ตัวเลขสำหรับหน้าการ์ดแทนที่จะเป็นตัวอักษร ดังนั้น Ace / Joker = 1; แจ็ค = 11; ราชินี = 12; และพระมหากษัตริย์ 13=
  • ในความท้าทายนี้เราสามารถสมมติว่าเราเล่นกับผู้เล่น 3 คนเสมอ
  • สามตัวแรกแสดงถึงการเริ่มต้นของ 'การต่อสู้' เมื่อผู้เล่นสองคนขึ้นไปมี 'สงคราม' ไพ่ต่อเนื่องในอาเรย์จะระบุการต่อสู้ของพวกเขา (ดูกรณีทดสอบเพื่อความเข้าใจที่ชัดเจนยิ่งขึ้น)

กฎทั่วไป:

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

กรณีทดสอบ:

Test case 1:  [4, 8, 11]                 ->  2 (or 3)
Test case 2:  [7, 1, 12]                 ->  1 (or 2)
Test case 3:  [10, 10, 13]               ->  2 (or 3)
Test case 4:  [3, 1, 2]                  ->  0 (or 1)
Test case 5:  [1, 1, 2]                  ->  2 (or 3)
Test case 6:  [3, 12, 1]                 ->  0 (or 1)
Test case 7:  [12, 12, 9, 4, 8]          ->  1 (or 2)
Test case 8:  [4, 4, 4, 8, 1, 2]         ->  2 (or 3)
Test case 9:  [11, 5, 11, 5, 5, 10, 13]  ->  2 (or 3)
Test case 10: [1, 1, 1, 9, 7, 9, 11, 3]  ->  0 (or 1)
Test case 11: [13, 13, 4, 1, 3]          ->  1 (or 2)
Test case 12: [13, 4, 13, 2, 3]          ->  2 (or 3)

4
ชื่อภาษาอังกฤษคือสงคราม (ลบพวกโจ๊กเกอร์และลบกฎ 2 และ 3-beat-ace)
Martin Ender

@ มาร์ตินเอนเดอร์เมื่อมีการเสมอกันผู้เล่นทั้งสองจะหงายไพ่ 3 ใบคว่ำหน้าและหงายหน้าที่ 4 ขึ้น ผู้ตัดสินอันดับที่ 4 ของรอบตัดสินและไพ่คว่ำหน้าคือ "spoils of war" นอกจากนี้เกมจะไม่ดำเนินต่อไปจนกว่าผู้เล่น 1 คนจะมีการ์ดทั้งหมดหรือไม่ ฉันไม่รู้ว่านี่เป็นกฎของท้องถิ่นหรือไม่ไม่มีใครจำได้หรือไม่ นั่นเป็นวิธีที่ฉันจำได้ว่าเล่น
Magic Octopus Urn

1
@ MagicOctopusUrn ฉันจำได้ว่าพลิกกองทิ้งเพื่อเล่นต่อไปจนกว่าผู้เล่นคนเดียวจะมีทั้งหมด
Kamil Drakari

1
@ KamilDrakari ใช่! นั่นคือวิธีที่ฉันเล่นด้วย ฉันอยู่ที่รัฐหลุยเซียนาเมื่อโตขึ้นมาเล่นเกมนี้
Magic Octopus Urn

@ MagicOctopusUrn ประสบการณ์ของฉันมาจากมินนิโซตาและเนื่องจากตอนนี้เรามีจุดข้อมูล 2 จุดฉันคิดว่ามันปลอดภัยที่จะบอกว่าอเมริกาทั้งหมดเหมือนกัน
Kamil Drakari

คำตอบ:


4

q - 142 ตัวอักษร

{p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}

หมายเหตุ: ศูนย์การจัดทำดัชนี

ไม่มีความคิดในการอ่าน stdin ใน q ดังนั้นคุณควรเรียกมันว่าเป็นฟังก์ชั่น: {p:til 3;while[1<(#:)p;h:(n:(#:)p)#x;x:n _x;$[1~min h;p:$[max a:h in(2;3);$[1<(#:)(?:)h(&:)a;p(&:)h=3;p(&:)a];p(&:)h=1];p:p(&:)h=max h]];(*:)p}[1,2,3]

ค่อนข้างยาวจริง ๆ แล้ว แต่มีมุมที่มากมาย มันทำให้บัญชีรายชื่อของผู้เล่นที่ใช้งานอยู่และกินรายชื่อของการ์ดในวง สิ่งที่เป็นปัญหามากที่สุดคือการตรวจจับผู้ชนะที่ถูกต้องในมือเช่น[13, 2, 3]เนื่องจากการ3เต้น2ตามปกติ แต่จะต้องมีการทำซ้ำเพื่อใส่ลงในกล่องมุม


3

JavaScript (ES6), 146 ไบต์

f=a=>(b=a.splice(0,3)).filter(m=>m-n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length>1?b.indexOf(n):f([...b.map(m=>m-n?0:a.shift()),...a])

ส่งคืนดัชนี zero-based 127 bytes ถ้าฉันอนุญาตให้ดีลเริ่มต้นเป็น array ที่แยกกัน (มันใช้งานได้กับจำนวนมือโดยพลการแน่นอน):

f=(b,a)=>b.filter(m=>m==n,n=Math.max(...b.includes(1)?b.filter(m=>m<4):b)).length<2?b.indexOf(n):f(b.map(m=>m-n?0:a.shift()),a)

0

Java 8, 257 ไบต์

int c(int[]a){int t=0,f=0,q,r=0,i=-1,l=a.length,x[];for(;++i<3;t=a[i]>t?a[r=i]:t)a[i]+=a[i]==1?f++*0+13:0;for(;i-->0;t=f>0&a[i]<4?t!=3?a[r=i]:t>a[i]?a[r=i]:t:t);for(f=-1,x=new int[q=l<7?3:l>7?l-3:5];l>3&++i<q;)x[i]=t==a[i]|i>2?a[++f+3]:0;return l>3?c(x):r;}

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

คำอธิบาย:

ลองที่นี่

int c(int[]a){      // Method with integer-array parameter and integer return-type
  int t=0,f=0,q,    //  Temp integers
      r=0,          //  Result-integer
      i=-1,         //  Index-integer
      l=a.length,   //  Length of the input-array
      x[];          //  Temp array we use when there is a war
  for(;++i<3;       //  Loop (1) from 0 to 3 (exclusive)
      t=            //    After every iteration, change `t` to:
        a[i]>t?     //     If the current item is larger than `t`:
         a[r=i]     //      Use the current item (and save its index in `r`)
        :           //     Else:
         t)         //      Leave `t` the same
    a[i]+=a[i]==1?  //   If the current item is a 1 (Ace/Joker):
         f++*0      //    Increase `f` by 1,
         +13        //    and change the 1 to 14 (by increasing with 13)
        :           //   Else:
         0;         //    Leave the current item the same (by increasing with 0)
                    //  End of loop (1) (implicit / single-line body)
  for(;i-->0;       //  Loop from 2 down to 0 (inclusive)
    t=f>0&a[i]<4?   //   If a Joker/Ace was present, and the current item is 2 or 3:
       t!=3?        //    And if it's not a 3 (so either 2 or 14)
        a[r=i]      //     Change `t` to the current item (and save its index in `r`)
       :t>a[i]?     //    Else-if the current item is 2, and `t` is a Joker/Ace:
        a[r=i]      //     Change `t` to the current item (and save its index in `r`
       :            //    Else:
        t           //     Leave `t` the same
      :             //   Else:
       t            //    Leave `t` the same
  );                //  End of loop (2)
  for(f=-1,         //  Reset `f` to -1
      x=new int[    //  Create the temp array `x` with length:
       q=l<7?       //   If the current length is 6 or lower:
          3         //    New length after war is 3
         :l>7?      //   Else-if the current length is 8 or higher:
          l-3       //    New length after war is current length - 3
         :          //   Else(-if current length is 7)
          5];       //    New length after war is 5
      l>3&          //  If there is a war:
          ++i<q;)   //   Loop (3) from 0 to the new length (exclusive)
    x[i]=t==a[i]    //    If the current item is at war,
         |i>2?      //    or the current item is after the first 3 items:
          a[++f+3]  //     Fill the new array with the correct next item
         :          //    Else:
          0;        //     Fill the item of the new array with 0
                    //     (since it won't participate in the next round)
                    //   End of loop (3)
  return l>3?       //  If there was a war:
          c(x)      //   Recursive-call with the new array
         :          //  Else:
          r;        //   Return the index of the card that won
}                   // End of method
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.