Ajude-me a fechar a caixa

12

A inspiração para esse desafio deve ser ridiculamente óbvia no momento da postagem.

A tarefa

Você deve criar um programa no estilo Shut the Box (não função, programa). Os princípios básicos de fechar a caixa são:

Os jogadores tentam fechar a caixa girando um conjunto de alavancas identificadas como 1-9. Eles devem fazê-lo girando as alavancas. A sequência de eventos de cada turno é a seguinte:

  1. A posição atual das alavancas é mostrada.
    • Em um novo jogo, a posição das alavancas deve ser exibida como 123456789.
    • Em um jogo com alavancas fechadas, todas as alavancas fechadas são exibidas como -. Por exemplo, em um jogo com 1, 5 e 9 fechados, a saída seria -234-678-.
  2. Os di (c) e (são | são) rolados.
    • Se as alavancas 7, 8 e 9 estiverem todas desligadas, apenas um dado de seis faces será lançado. Caso contrário, 2 dados de seis faces são lançados.
  3. O jogador é solicitado a escolher quantas alavancas deseja virar.
    • Se o jogador escolher um número> 9 ou <0, o jogo termina.
    • Se o jogador escolher uma alavanca já fechada, o jogo termina.
  4. O jogador seleciona muitas alavancas.
    • Se a soma das alavancas não for igual ao valor dos di (c) e lançados, o jogo termina.
  5. Se todas as alavancas estiverem fechadas, parabéns, você venceu. Caso contrário, volte para a etapa 1.

Regras para o Programa

  • Em cada turno, você deve exibir as posições atuais das alavancas.
  • Você deve gerar o valor do rolo com a frase You rolled:(observe o espaço).
  • Você deve solicitar (e aguardar) o número de alavancas para alternar com a frase How many levers to flip:(observe o espaço).
  • Você deve solicitar (e aguardar) quantas alavancas o jogador especificar com a frase Which lever to flip:(observe o espaço).
  • Você deve virar as alavancas especificadas.
  • Se a qualquer momento o jogo terminar, você deverá produzir Game Over.
  • Se o jogador terminar um turno sem alavancas abertas, você deverá You win!

Jogos de exemplo

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!
Addison Crump
fonte
Oh Eu estava na minha lista para criar um desafio envolvendo a Shut the Box. Agradável!
mbomb007

Respostas:

3

Python 3, 348

Economizou 5 bytes graças a Mathias Ettinger.
Economizou 7 bytes graças ao DSM.

Ooof, este é longo. Eu também odeio que não haja uma boa maneira de fazer casos de teste.

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!')
Morgan Thrapp
fonte
2

C, 405 403 398 392 390 387 bytes

#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!");
}

Editar: D'oh! Deixou uma variável não utilizada na minha resposta. Eu o removi, mas colei a versão errada.

Cole Cameron
fonte
2

PowerShell v2 +, 330 322 bytes

$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}}

Novas linhas para maior clareza:

$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}
}

(Requer a versão 2 ou posterior, pois Get-Randomnão existia no PowerShell v1 ...)

Explicação:

Comece definindo o $araio das alavancas, tomando o intervalo 1..9e também defina $rigual a um bloco de script que executaremos mais tarde (descrito abaixo com $b). A Game Overredação é definida $gno início de um loop infinito for(){...}. A cada iteração, configuramos nossa saída $oe imediatamente a produzimos (graças ao (...)encapsulamento) -joinreunindo a matriz e substituindo cada 0uma por a -. (O 0explicado abaixo). Se a saída for igual a 9 hífens, a saída You win!e exit.

Em seguida, configuramos nossos lançamentos de dados $bchamando o armazenado $r(via &) com alguns parâmetros adicionais. O Get-Randomcomando com um -Maximumde 6(o -Maximumestá implícito) produzirá um número inteiro de 0 a 5, inclusive. Adicionamos 1a isso para obter um dado de seis lados, e adicionamos isso a outro teste aleatório de dados multiplicado pelo (($a|sort)[8]-ge7)qual verifica se o valor mais alto deixado nas alavancas é o 7,8,9primeiro, classificando $ae depois pegando o último elemento e verificando se é maior -do-ou-igual-a 7. Usamos a conversão de texto implícita para transformar o valor booleano em 0 (False) ou 1 (True) para a multiplicação, de modo que o "dado" adicional seja die*0ou die*1. Em seguida, produzimos o resultado do rolo de matriz.

Em seguida é a Read-Hostem $lpor quantos alavancas. Observe que o PowerShell adiciona automaticamente o espaço de dois pontos :após um Read-Hostprompt, por isso obtemos isso de graça pelo menos. Em seguida, verificamos se o número de alavancas que o usuário deseja acionar está entre 1 e 9, caso contrário exit.

Agora entramos em um whileloop. A cada iteração desse loop, podemos Read-Hostalavancar, armazenar $ie subtrair esse valor $b. Também subtraímos a alavanca correspondente na matriz e subtraímos quantas vezes adicionais para consultar o usuário.

A última linha (exceto a chave de fechamento) testa duas construções booleanas. A primeira, apenas $b, será apenas $Truese o usuário não subtrair adequadamente todos os números do rolo de matriz (no PowerShell, qualquer número diferente de zero é Truthy). A outra condição classifica $ae assume o valor mínimo. Se subtrairmos a mesma alavanca duas vezes, o valor mínimo será negativo (ou Verdade), caso contrário, o valor mínimo será 0(ou Falsey).

Exemplo de execução:

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
fonte
Excelente explicação! +1
Addison Crump