Нетризованная игра в кости

10

Те из вас, кто любит Numberphile, знакомы с доктором Джеймсом Граймом, который описал на своем канале нетранзитивную игру в кости .

Игра состоит из трех 6-гранных кубиков:

  • Die 1: 3,3,3,3,3,6
  • Die 2: 2,2,2,5,5,5
  • Die 3: 1,4,4,4,4,4

Два игрока выбирают кубик для использования. Они бросают их, и высшие умирают, побеждает лучше всех.

Вероятно, умирает 1 удар, умирает 2 с вероятностью> 50%. Точно так же, умирают 2 удара, умирают 3, и, что интересно, умирают 3 удара, умирают 1.

Написать программу взятия 1, 2или в 3качестве входных данных. Это указывает на штамп, выбранный пользователем. Затем программа выбирает кубик, который побьет пользователя, и выводит результаты 21 броска, и " Computer/User wins with x points"

правила

  • Code-golf, голосует за нарушение порядка
  • Вы должны использовать RNG (или лайки), чтобы фактически симулировать броски костей.
  • Я не слишком строг в отношении формата вывода. Это нормально, пока вы показываете кубики, как-то разделяете 21 бросок (в отличие от того, как вы разделяете кубики в одном броске) и выводите это предложение выше.
  • Ввод может быть stdin, аргумент командной строки, с экрана и т. Д.

пример

вход

1

Вывод

4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 6
1 3
4 3
4 3
1 3
4 3
1 3
4 3
4 3
4 3
4 3
4 6
 Computer wins with 16 points

Здесь пользователь выбирает кубик 1, и его броски показываются в правом столбце. Программа выбирает die 3 и бьет его.

TwiNight
источник

Ответы:

1

GolfScript, 112 105 символов

3,21*{..+6rand<3*+)}%3/\{)\.+-1%>2<.p~<}+,,"User
Computer"n/1$11<=" wins with "+\[.~22+]$1>~+" points"+

Запустите его онлайн .

Скрипт ожидает ввода в STDIN и затем печатает результат бросков костей (компьютер первого столбца, второй пользователь) и окончательную статистику в STDOUT.

Говард
источник
4

APL ( 106 114)

'Computer' 'User'[1+X],'wins with','points',⍨|Z-21×X←11>Z←+/>/⎕←⍉↑{⍵[{?6}¨⍳21]}¨(↓5 6⍴545170074510753⊤⍨18⍴7)[⎕+⍳2]

Объяснение:

  • (↓5 6⍴545170074510753⊤⍨18⍴7)[⎕+⍳2]: Большое число - это игральные кости в виде базы 7. Мы создаем матрицу 6x5, содержащую значения костей в следующем порядке: 2 3 1 2 3. Запрашиваем ввод данных пользователем, добавляем их в вектор 1 2и выбираем эти строки из матрицы. Поскольку список кубиков смещен, пользователь теперь получает тот, который он выбрал (справа), а компьютер получает более сильный.
  • {⍵[{?6}¨⍳21]}¨: сделать 21 бросок за каждую из этих двух костей.
  • ⎕←⍉↑: положить рулоны в матричной форме и вывести их.
  • Z←+/>/: получить оценку компьютера (количество раз, когда значение компьютера было выше, чем у пользователя)
  • X←11>Z: установить X, выиграл ли пользователь (если 11 выше, чем у компьютера).
  • 'Computer' 'User'[1+X], Xпобедил ли пользователь.
  • 'wins with','points',⍨|Z-21×X: Zоценка компьютера, поэтому, если компьютер выиграл дисплей Z, в противном случае отображается 21-Z.
Мэринус
источник
Счет не является разницей итогов (которая ожидается равной 0 для всех пар костей), вместо этого победитель каждого из 21 броска получает 1 очко. В этом примере у пользователя есть 5 очков (из 5 выигрышных бросков: 4-6, 1-3, 1-3, 1-3, 4-6), и компьютер получает 16 очков отдыха.
TwiNight
@TwiNight: исправил это
marinus
Отрицательные моменты, когда пользователь выигрывает. Вы можете исправить то, |Z-21×Xчто не меняет количество символов
TwiNight
2

R - 228

d=matrix(rep(c(rep(3,5),6,2,2,2,5,5,5,1,rep(4,5)),2),6)
x=scan()
r=expand.grid(Computer=d[,x+2],User=d[,x])[sample(36,21,T),]
print(r)
s=summary.factor(names(r)[max.col(r)])
cat(names(which.max(s)),"wins with",max(s),"points\n")

Пример выполнения:

> source('ntd.R')
1: 2
2: 
Read 1 item
     Computer User
28          3    5
31          3    5
36          6    5
18          6    2
11          3    2
31.1        3    5
14          3    2
8           3    2
9           3    2
17          3    2
2           3    2
29          3    5
3           3    2
16          3    2
4           3    2
21          3    5
14.1        3    2
23          3    5
16.1        3    2
17.1        3    2
19          3    5
Computer wins with 14 points
Джефф Риди
источник
Вы можете заменить summary.factorс table, экономя 9 символов.
Брайан Диггс
2

Mathematica 208 172 166 159

Пробелы добавлены для ясности

b=Boole;{#, Row@{
         If[# > 10, "Play", "Comput"], "er wins with ",
         Max[#, 21 - #], " points"} &@ Total[b[#1 > #2] & @@@ #]} &@
   Table[1 + i + 3 b[6 Random[] > 2 i + 1],{21}, {i, {#, Mod[# + 1, 3]}}] &
Доктор Велизарий
источник
Я думаю, что выходные данные должны перечислять значения каждого броска костей.
DavidC
@ чувак да, я потерял его во время тестирования. Я сделал быстрое исправление, просто чтобы держать мяч в движении. Я подумаю позже, как это улучшить.
Доктор Велизарий
Теперь, кажется, работает нормально.
DavidC
@ Чувак намного лучше
доктор Велизарий,
Действительно мило. +1
Mr.Wizard
1

Рубин 1.8, 165

i,s,*d=getc,21,[4]*5<<1,[3]*5<<6,[2,5]*3
puts"#{s.times{p r=[i,i-1].map{|o|d[o%3][rand 6]};s+=r[0]<=>r[1]}>s?"Human":"Computer"} wins with #{[s/=2,21-s].max} points"

getc получает входное значение ascii (только ruby ​​1.8), которое по модулю 3 совпадает с целочисленным значением.

sначинается в 21, поэтому s.times{code}будет выполняться code21 раз и возвращать 21. На каждой итерации цикл либо добавляет, либо вычитает 1 из s в зависимости от того, кто выиграл, поэтому мы можем увидеть, кто выиграл, посмотрев, sоказался ли он ниже 21. До сих пор аккуратно , но тогда мне нужно неуклюжее выражение, [s/=2,21-s].maxчтобы извлечь фактическое количество очков. Я давно хотел сделать арифметику с возвращаемым значением <=>, так что я все равно счастлив.

histocrat
источник
1

Mathematica 234 247

Код

g@n_ := {t = RandomChoice[{{5, 25, 1, 5}/36 -> {{3, 1}, {3, 4}, {6, 1}, {6, 4}}, 
         {5, 1, 5, 1}/12 -> {{2, 3}, {2, 6}, {5, 3}, {5, 6}},
         {1, 1, 5, 5}/12 -> {{1, 2}, {1, 5}, {4, 2}, {4, 5}}}[[n]], 21], 
         Row[{If[(c = Count[t, {x_, y_} /; y > x]) > 10, "Computer ", "Player "], 
         "wins with ", If[c > 10, c, 21 - c], " points"}]}

Применение

{Рулон игрока, Рулон компьютера}

g[1]
g[2]
g[3]

Результаты


объяснение

nэто число 1, 2 или 3, соответствующее кубику игрока. Поскольку n также определяет (но не равен) матрицу компьютера, мы можем сгенерировать все возможные броски костей, когда n = 1, n = 2, n = 3. Мы также можем определить их соответствующие вероятности.

Изучите данные сразу после RandomChoice:

{5, 25, 1, 5} / 36 -> {{3, 1}, {3, 4}, {6, 1}, {6, 4}}

Если игрок тянет кубик 1, единственными возможными исходами являются следующие 4 пары

{{3, 1}, {3, 4}, {6, 1}, {6, 4}}

Соответствующие вероятности этих пар

{5, 25, 1, 5}/36, это,

{5/36, 25/36, 1/36, 5/36}

RandomChoice[<data>, 21] выводит 21 бросок двух кубиков.

DavidC
источник
1

C, 205 191

p;r(c){return 1+c+3*(rand()%6>2*c);}main(i,c,q,s){for(c=51-getchar();++i<23;printf("%u %u\n",q,s))q=r(c),p+=(s=r(-~c%3))<q;printf("%ser wins with %u points",p<11?"Comput":"Us",p<11?21-p:p);}

Читает выбор пользователя из стандартного ввода.

перестал поворачиваться против часовой стрелки
источник
Некоторые советы: for(c=51-getchar(p=0);, printf("%ser wins), перезаказ выражение , rчтобы начать с (и экономией пространства.
Угорен
И еще: (c+1)%3-> -~c%3, сделать pстатический (инициализируется 0), удалить {}после for( ;-> ,внутри них), использовать p<11?:дважды внутри printfвместо назначения p,q.
Угорен
И вы можете установить s,qв цикле printf, и увеличивать pвпоследствии, тем самым сохраняя скобки. Также измените cназначение на использование %3или %7, задав другой порядок 0,1,2.
Угорен
1

фактор

С включает в себя: 388

Без: 300

USING: arrays formatting io kernel math math.parser prettyprint random sequences ;
IN: N
CONSTANT: d { { 3 3 3 3 3 6 } { 2 2 2 5 5 5 } { 1 4 4 4 4 4 } }
: p ( -- ) 1 read string>number [ 3 mod 1 + ] keep [ 1 - d nth ] bi@ 2array 21 iota [ drop first2 [ random ] bi@ [ 2array . ] 2keep < ] with map [ ] count [ 11 > "Comput" "Play" ? ] [ "er wins with %d points" sprintf ] bi append print ;

Да, Фактор на самом деле не тот язык, который можно использовать при игре в гольф, но это приятно.

Мэтью Рольф
источник
0

Python 182

from random import*
u=2+input()
r=[eval("int(choice(`0x1d67e987c0e17c9`[i%3::3])),"*21)for i in(u,u-1)]
U,C=map(sum,r)
print r,['Us','Comput'][U<C]+'er wins with %d points'%abs(U-C)
daniero
источник
0

R 206

u=scan()
D=list(c(rep(3,5),6),c(2,5),c(1,rep(4,5)))
S=sample
U=S(D[[u]],21,T)
C=S(D[[(u+1)%%3+1]],21,T)
print(cbind(U,C))
W=sum(U>C)
I=(W>10)+1
cat(c("Computer","User")[I],"wins with",c(21-W,W)[I],"points")
flodel
источник