Помоги мне закрыть ящик

12

Вдохновение для этого вызова должно быть смехотворно очевидно во время публикации.

Задание

Вы должны создать программу в стиле Shut the Box (не функция, а программа). Основы закрытой коробки:

Игроки пытаются закрыть ящик, повернув набор рычагов с метками 1-9. Они должны сделать это, щелкая рычаги. Последовательность событий каждого хода такова:

  1. Текущее положение рычагов показано.
    • В новой игре положение рычагов должно отображаться как 123456789.
    • В игре с закрытыми рычагами все закрытые рычаги отображаются как -. Например, в игре с закрытыми 1, 5 и 9 выводом будет -234-678-.
  2. Ди (с) е (есть | являются) проката.
    • Если все рычаги 7, 8 и 9 выключены, бросается только один шестигранный кубик. В противном случае бросаются 2 шестигранных кубика.
  3. Игроку предлагается выбрать, сколько рычагов он хочет щелкнуть.
    • Если игрок выбирает число> 9 или <0, игра заканчивается.
    • Если игрок выбирает уже закрытый рычаг, игра заканчивается.
  4. Игрок выбирает столько рычагов.
    • Если сумма рычагов не равна значению брошенного ди (с) е, игра заканчивается.
  5. Если все рычаги закрыты, поздравляю, вы выиграли. В противном случае вернитесь к шагу 1.

Правила для Программы

  • На каждом ходу вы должны выводить текущие позиции рычагов.
  • Вы должны вывести значение рулона с фразой You rolled:(обратите внимание на пробел).
  • Вы должны указать (и подождать), чтобы количество рычагов переключилось с фразой How many levers to flip:(обратите внимание на пробел).
  • Вы должны запросить (и подождать) столько рычагов, сколько указано игроком с фразой Which lever to flip:(обратите внимание на пробел).
  • Вы должны щелкнуть указанными рычагами.
  • Если в какой-то момент игра заканчивается, вы должны вывести Game Over.
  • Если игрок заканчивает ход без открытых рычагов, вы должны вывести You win!

Примеры игр

123456789
You rolled: 5
How many levers to flip: 5
Which lever to flip: 1
Which lever to flip: 2
Which lever to flip: 3
Which lever to flip: 4
Which lever to flip: 5
Game Over
123456789
You rolled: 5
How many levers to flip: 3
Which lever to flip: 2
Which lever to flip: 2
Which lever to flip: 1
Game Over
123456789
You rolled: 12
How many levers to flip: 2
Which lever to flip: 3
Which lever to flip: 9
12-45678-
You rolled: 6
How many levers to flip: 2
Which lever to flip: 2
Which lever to flip: 4
1---5678-
You rolled: 11
How many levers to flip: 2
Which lever to flip: 5
Which lever to flip: 6
1-----78-
You rolled: 8
How many levers to flip: 1
Which lever to flip: 8
1-----7--
You rolled: 8
How many levers to flip: 2
Which lever to flip: 1
Which lever to flip: 7
---------
You win!
Аддисон Крамп
источник
Ой. У меня было это в моем списке, чтобы создать задачу, включающую Shut the Box. Ницца!
mbomb007

Ответы:

3

Питон 3, 348

Сохранено 5 байтов благодаря Матиасу Эттингеру.
Сохранено 7 байтов благодаря DSM.

Ох, это долго. Я также ненавижу, что нет хорошего способа делать тестовые случаи.

from random import*
*l,='123456789'
q=['-']*9
r=randint
p=print
f=' to flip: '
while l!=q:
 p(*l,sep='');t=r(1,6)+r(1,6)*(l[6:]!=q[6:]);p('You rolled: %s'%t);d={int(input('Which lever'+f))for _ in' '*int(input('How many levers'+f))}
 if len(set(d))-len(d)+1-all(str(x)in l for x in d)+t-sum(d):exit('Game Over')
 for x in d:l[x-1]='-'
p('You win!')
Морган Трепп
источник
2

C 405 403 398 392 390 387 байт

#define R 1+rand()/(2147483647/6+1)
#define G return puts("Game Over");
#define I(s,w)printf(s);scanf("%d",&w);
w,s;main(r,l){char b[]="123456789";for(srand(time(0));w^9;w=strspn(b,"-")){puts(b);printf("You rolled: %d\n",r=R+(strspn(b+6,"-")<3?R:0));I("How many levers to flip: ",l)for(;l--;s+=w,b[w-1]=45){I("Which lever to flip: ",w);if(w>9|w<0|b[w-1]<48)G}if(s^=r)G}puts("You win!");}

Ungolfed

/* Macro to get random integer in range [1,6] */
#define R 1+rand()/(2147483647/6+1)

i; /* Index variable */
main(r,l,w,s)
{
    /* Running game board */
    char b[]="123456789";

    /* Run while still levers not pulled */
    for(srand(time(0));i^9;i=strspn(b,"-"))
    {
        puts(b); /* Print game board */
        r=R+(b[6]^45||b[7]^45||b[8]^45?R:0); /* Get dice roll */
        printf("You rolled: %d\n",r); /* Print dice roll */
        printf("How many levers to flip: ");
        scanf("%d",&l); /* Get # of levers */
        for(i=s=0;i++<l;s+=w)
        {
            printf("Which lever to flip: ");
            scanf("%d",&w); /* Get lever # */
            if(w>9||w<0||b[w-1]==45) /* If invalid lever or lever already pulled, game over man */
                return puts("Game Over");
            b[w-1]=45; /* flip the lever */
        }
        if(s^r) /* If sum does not equal roll, game over */
            return puts("Game Over");
    }
    puts("You win!");
}

Редактировать: D'Oh! Оставил неиспользованную переменную в моем ответе по гольфу. Я удалил его, но вставил не ту версию.

Коул Камерон
источник
2

PowerShell v2 +, 330 322 байта

$a=1..9;$r={1+(Random 6)};for($g="Game Over"){($o=-join$a-replace0,'-');if($o-eq'-'*9){"You win!";exit}"You rolled: "+($b=(&$r)+(&$r)*(($a|sort)[8]-ge7));$l=Read-Host "How many levers to flip";if(9-lt$l-or1-gt$l){$g;exit}while($l){$b-=($i=Read-Host "Which lever to flip");$a[$i-1]-=$I;$l-=1}if($b-or($a|sort)[0]){$g;exit}}

Новые строки для ясности:

$a=1..9
$r={1+(Random 6)}
for($g="Game Over"){
  ($o=-join$a-replace0,'-')
  if($o-eq'-'*9){"You win!";exit}
  "You rolled: "+($b=(&$r)+(&$r)*(($a|sort)[8]-ge7))
  $l=Read-Host "How many levers to flip"
  if(9-lt$l-or1-gt$l){$g;exit}
  while($l){
    $b-=($i=Read-Host "Which lever to flip")
    $a[$i-1]-=$i
    $l-=1
  }
  if($b-or($a|sort)[0]){$g;exit}
}

(Требуется версия 2 или более поздняя, ​​поскольку Get-Randomв PowerShell v1 не было ...)

Объяснение:

Начните с установки $aряда рычагов, взяв диапазон 1..9, а также установите $rравным блоку скрипта, который мы выполним позже (описано ниже с помощью $b). Game OverФормулировка получает значение $gв начале бесконечного цикла for(){...}. На каждой итерации мы устанавливаем наш вывод $oи немедленно выводим его (благодаря (...)инкапсуляции), -joinобъединяя массив и заменяя каждый 0на -. ( 0Объясняется ниже). Если результат равен 9 дефисам, выведите You win!и exit.

Затем мы устанавливаем наши броски костей $b, вызывая хранимые $r(через &) некоторые дополнительные параметры. Get-RandomКоманда с -Maximumиз 6( -Maximumподразумеваются) будет производить целое число от 0 до 5 включительно. Мы добавляем 1к этому, чтобы получить шестигранный кубик, и добавляем его к другому случайному броску кубика, умноженному на (($a|sort)[8]-ge7)который проверяется, является ли наибольшее значение, оставшееся на рычагах, одним из них 7,8,9, сначала сортируя, $aа затем беря последний элемент и проверяя, больше ли он -то-или-равно 7. Мы используем неявные типажи , чтобы включить логическое значение в 0 (ложь) или 1 (True) для умножения, так что дополнительные «умирает» либо die*0или die*1. Затем мы выводим результат броска кубика.

Далее идет Read-Hostв $lтечение скольких рычагов. Обратите внимание, что PowerShell автоматически добавляет двоеточие :после Read-Hostзапроса, так что мы получаем его по крайней мере бесплатно. Затем мы проверяем, что количество рычагов, которые пользователь хочет перевернуть, составляет от 1 до 9, иначе exit.

Теперь мы входим в whileпетлю. Каждую итерацию этого цикла мы Read-Hostопределяем, сохраняем в $iи вычитаем это значение из $b. Затем мы также вычитаем соответствующий рычаг в массиве и вычитаем, сколько дополнительных раз нужно запросить у пользователя.

Последняя строка (исключая закрывающую скобку) проверяет две логические конструкции. Первое, просто $b, будет, только $Trueесли пользователь не вычел все числа из броска кубика (в PowerShell любое ненулевое число - это Истина). Другое условие сортирует $aи принимает минимальное значение. Если мы вычли один и тот же рычаг дважды, то минимальное значение будет отрицательным (или Truthy), в противном случае минимальное значение будет 0(или Falsey).

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

PS C:\Tools\Scripts\golfing> .\shut-the-box.ps1
123456789
You rolled: 6
How many levers to flip: 1
Which lever to flip: 6
12345-789
You rolled: 6
How many levers to flip: 2
Which lever to flip: 2
Which lever to flip: 4
1-3-5-789
You rolled: 6
How many levers to flip: 2
Which lever to flip: 1
Which lever to flip: 5
--3---789
You rolled: 10
How many levers to flip: 2
Which lever to flip: 3
Which lever to flip: 7
-------89
You rolled: 9
How many levers to flip: 1
Which lever to flip: 9
-------8-
You rolled: 8
How many levers to flip: 1
Which lever to flip: 8
---------
You win!
AdmBorkBork
источник
Отличное объяснение! +1
Эддисон Крамп