Имитация «битвы» в игровой карточной игре «Орлог»

15

Давайте создадим симулятор для аспекта в карточной игре, который я лично знаю под голландским названием «Oorlog» (переводится как «Война»).

Как работает «Орлог»?

Две колоды карт (каждая включает в себя два джокера) поровну поделены между количеством игроков. Каждый игрок перетасовывает свою собственную колоду, ставит ее вверх дном перед собой, и все игроки одновременно открывают первую карту колоды.
Победитель этой «битвы» определяется значениями карт, следующих следующим правилам: Джокер / Туз побеждает Короля; Король побеждает королеву; Королева побеждает Джека; Джек побеждает 10; 10 поражений 9; .... Кроме того, 2 и 3 побеждают туз / джокер. Последнее правило может привести к циклу, в котором 2 или 3 бьют Ace или Joker, Ace или Joker бьют какую-то другую карту, которая в свою очередь бьет 2 или 3. В этом случае 2 или 3 выигрывает битву.
(Костюм не имеет значения в этой карточной игре.)

Когда два или более игрока имеют равные старшие карты, у них появляется «война». Это означает, что они кладут одну карту вверх дном, а затем каждая открывает новую карту из своей колоды, снова смотря, у кого самая высокая карта. Это продолжается до тех пор, пока один игрок не выиграет весь бой.
(Все карты этого сражения попадают в колоду сброса игрока, который выиграл битву. Затем все открывают новую карту. Когда в колоде игрока нет карт, они переворачивают свою колоду сброса вверх ногами и продолжают эту новую колоду. Это продолжается до тех пор, пока игрок не выберет все свои карты, а затем выигрывает игрок с наибольшим количеством карт.)

Пример «битвы» с тремя игроками:

  1. 4, 8, Джек:
    Джек выигрывает.
  2. 7, Ace, Queen:
    Ace выигрывает.
  3. 10, 10, король:
    король побеждает.
  4. 3, Джокер, 2:
    3 победы.
  5. Туз, Джокер, 2:
    2 победы.
  6. 3, королева, туз:
    3 победы.
  7. Queen, Queen, 9:
    Queen и Queen ведут «войну», поэтому она продолжается двумя новыми картами: 4, 8;
    8 побед.
  8. 4, 4, 4: у
    всех идет «война», поэтому она продолжается тремя новыми картами: 8, туз, 2;
    2 победы.
  9. Джек, 5 лет, Джек:
    Джек и Джек ведут «войну», поэтому продолжается две новые карты: 5, 5;
    5 и 5 также равны, поэтому «война» снова продолжается с двумя новыми картами: 10, Король;
    Король побеждает.
  10. Джокер, Джокер, Туз: у
    всех «война», поэтому она продолжается тремя новыми картами: 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
Английское название действительно War (минус джокеры и минус правило 2-и-3-beat-ace).
Мартин Эндер
@MartinEnder также, когда есть ничья, оба игрока переворачивают 3 карты лицом вниз, а 4 - вверх. Четвёртое определяет победителя раунда, а закрытые карты являются «трофеями войны». Кроме того, разве игра не продолжается до тех пор, пока у одного игрока не появятся все карты? Я не знаю, если это было местное правило или нет, кто-нибудь еще помнит это? Вот так я помню игру.
Волшебная Урна Осьминога
1
@MagicOctopusUrn Я помню, как перелистывал стопки сброса, чтобы продолжить игру, пока один игрок не получит все это.
Камил Дракари
1
@KamilDrakari да! Вот так я и играл. Я рос в Луизиане, играя на этом.
Волшебная Осьминог Урна
@MagicOctopusUrn Мой опыт из Миннесоты, и, поскольку у нас сейчас есть 2 точки данных, я думаю, можно с уверенностью сказать, что вся Америка одинакова.
Камил Дракари

Ответы:

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}

Примечание: ноль индексируется.

В q нет понятия читать stdin, поэтому вы должны вызывать его как функцию: {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])

Возвращает нулевой индекс. 127 байт, если мне разрешили начальную сделку в виде отдельного массива (конечно, это также работает для произвольного числа рук):

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
Кевин Круйссен
источник