Um jogo de adivinhação plana

13

Há um jogo que eu gosto de jogar. Isso acontece em uma grade de tamanho finito (mas é envolto, como uma esfera). Nessa grade, um ponto aleatório (somente número inteiro) é selecionado. Então, eu, o usuário, sou solicitado a inserir uma coordenada. Se minha entrada corresponde exatamente ao ponto aleatório, disseram-me que venci. Caso contrário, me disseram a distância em pontos entre minha entrada e o ponto aleatório. Por exemplo, se eu adivinhasse (2,2)e o ponto aleatório estivesse (4,3), então a distância seria sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

O jogo continua até que o jogador chegue ao local correto do ponto.


Objetivo Crie uma versão funcional do jogo descrito acima. Você deve criar um programa completo para fazer isso. Aqui está o que seu programa deve fazer:

  1. Solicite duas entradas: a altura e a largura do quadro. A origem está no canto superior esquerdo do quadro. Essas entradas não excederão 1024.
  2. Selecione um ponto aleatório nesse quadro; este será o ponto a ser adivinhado.
  3. Aceite a entrada simulando uma curva. A entrada será um par de números inteiros separados por espaço ou duas entradas inteiras separadas. Em resposta a esta entrada, o programa fará uma de duas coisas:
    1. Se a entrada corresponder ao ponto aleatório selecionado, envie uma mensagem sinalizando a vitória do usuário. Eu sugeriria "Você ganhou!".
    2. Caso contrário, imprima a distância entre o ponto de entrada do usuário e o ponto aleatório.
    Em qualquer um dos casos, você deve incrementar o contador de voltas.
  4. Depois que o usuário tiver alcançado a vitória, exiba o número de turnos que ele fez. O programa então sai.

Bónus

Os bônus são aplicados na ordem em que aparecem nesta lista

  • -150 bytes se o seu programa usa um número inteiro de entrada Dque descreve a dimensão na qual o jogo ocorre. Por exemplo, se D = 3você criar um ponto aleatório de 3números inteiros, receber 3entradas inteiras e gerar a distância entre esses pontos.
  • -50% (ou + 50% se score < 0) se você fornecer uma representação gráfica da placa (ASCII ou Figura) que mostre onde o usuário adivinhou anteriormente na grade de determinadas dimensões e no contador de curvas. (Se você optar pelo primeiro bônus, ele se aplicará apenas aos modos 2De 1D. Se você adicionar uma saída gráfica em 3D, receberá um adicional de -50%.)
  • -60 bytes se você pode fornecer um modo de jogo (selecionado por uma entrada no início; isto é, quando fornecido 0, executa o modo de jogo regular; quando determinado 1, executa este modo de jogo) no qual o ponto move 1 unidade em uma direção ortogonal aleatória por turno

Mais sobre embalagem

O empacotamento ocorre apenas quando, no terceiro bônus, o ponto móvel se move através de qualquer um dos limites; neste caso, o ponto móvel é distorcido para o respectivo ponto, assim:

...              ...
..R (move right) R..
...              ...

Esse comportamento de empacotamento não afeta o palpite do usuário, além do fato de que o ponto mudou de direção.


Entre os melhores

O snippet de pilha na parte inferior desta postagem gera o catálogo a partir das respostas a) como uma lista da solução mais curta por idioma eb) como uma tabela geral de líderes.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

# Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Conor O'Brien
fonte
7
Nitpick menor: você provavelmente quer dizer que envolve como um toro e não uma esfera. É impossível envolver uma grade 2D em uma esfera sem criar descontinuidades.
Alistair Buxton
2
Além disso, se o tabuleiro envolver, pode haver um caminho mais curto entre o palpite e o alvo cruzando uma borda.
Alistair Buxton
1
@NBZ Sim, você pode.
Conor O'Brien
1
@NBZ 1 unidade em uma única direção.
Conor O'Brien
2
1. Ainda não tenho certeza de qual é a topologia. Para ajudar a esclarecer as coisas, se o quadro é 10x10, o ponto aleatório é (9,4), e eu acho (2,2), é a distância sqrt(13)ou sqrt(53)? (Observação para o futuro: se você estiver fazendo algo estranho, não inclua aleatoriedade, pois torna quase impossível fornecer casos de teste). 2. No terceiro bônus, a distância deve ser calculada e emitida antes ou depois do ponto se mover?
Peter Taylor #

Respostas:

8

CJam, -113 -139 -152 -157 -159 bytes

l~]:B:mr{_ea:i~mr0a*W2mr#+*.+B:,.=_[l~].-:mh_p}g],(

O programa tem 51 bytes de comprimento e se qualifica para os bônus de -150 bytes e -60 bytes .

O modo de jogo e o número de dimensões são lidos como um argumento da linha de comando, o tamanho em cada dimensão do STDIN. Como a mensagem da vitória é arbitrária , o programa será impresso 0.0(distância ao objetivo) para indicar que o jogo acabou.

Execuções de teste

$ cjam game.cjam 0 3; echo
2 2 2
1 1 1
1.4142135623730951
1 1 0
1.7320508075688774
1 0 1
1.0
0 0 1
0.0
4
$ cjam game.cjam 1 3; echo
2 2 2
0 0 0
1.0
0 0 0
0.0
2

Como funciona

l~]       e# Read a line from STDIN, evaluate it and collect the result.
:B        e# Save the resulting array in B. The result is [B1 ... Bd],
          e# where Bk is the board size in dimension k.
:mr       e# Pseudo-randomly select a non-negative integer below Bk,
          e# for each k between 1 and d.
{         e# Do:
  _       e#   Copy the item on the stack. The original becomes a dummy value
          e#   that will be used to count the number of turns.
  ea      e#   Push the array of command-line arguments.
  :i~     e#   Cast each to integer and dump them on the stack.
          e#   This pushes m (game mode) and d (number of dimensions).
  mr      e#   Pseudo-randomly select a non-negative integer below d.
  0a*     e#   Push an array of that many zeroes.
  W2mr#   e#   Elevate -1 to 0 or 1 (selected pseudo-randomly).
  +       e#   Append the result (1 or -1) to the array of zeroes.
  *       e#   Repeat the array m times.
  .+      e#   Perform vectorized addition to move the point.
  B:,.=   e#   Take the k-th coordinate modulo Bk.
  _[l~]   e#   Push a copy and an evaluated line from STDIN.
  .-:mh   e#   Compute their Euclidean distance.
  _p      e#   Print a copy.
}g        e# While the distance is non-zero, repeat the loop.
],(       e# Get the size of the stack and subtract 1.
          e# This pushes the number of turns.
Dennis
fonte
2
E Dennis superou todos os outros. Novamente.
Seadrus 02/11/2015
1
Você acidentalmente atualizou a pontuação de 152 em vez de -152, colocando-o em último lugar na tabela classificativa
Moose
7

Pitão, 91 (-150 -60) = -119

VvwaYOvw;JY#IqQ1=dOlY XYd@S[0 @Jd +@Yd?O2_1 1)1)=T[)VYaT^-Nvw2)=ZhZ=b@sT2Iqb0Bb;p"Won in "Z

Solução antiga: (54-150 = -96)

JYVQaYOvw;#=J[)VYaJ^-Nvw2)=ZhZ=b@sJ2Iqb0Bb;p"Won in "Z

Toda entrada ocorre em uma nova linha.

  • Primeiro inteiro representa o modo de jogo ( quer 1ou0 )
  • O primeiro segundo inteiro Drepresenta as dimensões do jogo.
  • As próximas Dentradas representam o tamanho do campo
  • Todas as Dentradas a partir deste ponto são suposições

Exemplo de reprodução (as dicas não aparecem no programa atual):

  #Hint: Gamemode (1 or 0)
1
  #Hint: Dimensions
3
  #Hint: X-size
4
  #Hint: Y-size
4
  #Hint: Z-size
4
  #Hint: Guesses
  #Hint:[3, 2, 1]
3
2
2
1.0
  #Hint:[3, 2, 1]
3
2
1
1.0
  #Hint:[2, 2, 1]
2
2
1
1.0
  #Hint:[3, 2, 1]
3
2
1
Won in 4
alce
fonte
O segundo movimento não deveria ganhar?
JNF #
@JNF o ponto pode mover-se em modo de jogo 1 (-60 bytes bónus)
Jakube
Santo Moly, isso é algum código pyth longo. Não é realmente um golfe. Por exemplo, vejo dois espaços que podem ser removidos. Além disso: você pode usar em J=YmOvwvwvez de VvwaYOvw;JY, que é 2 bytes mais curto. Não examinei o outro código, mas acho que você também pode reduzir algumas coisas por lá.
27475 Jakarta
@ Jakube, eu estava assumindo a dica diz-nos onde o ponto de atualmente
JNF
3

Python 2, 210 - 150 = 60

from random import*
q,r,o=map,raw_input,int
a=q(randrange,q(o,r().split(' ')))
m=q(o,r().split(' '))
t=1
while m!=a:print sum([(c-d)**2for c,d in zip(m,a)])**.5;m=q(o,r().split(' '));t+=1
print'You won in %d'%t

Primeiro desafio apenas até agora. Experimente online

Mego
fonte
3

Pip, 43 42 bytes - 150 = -108

Toma as dimensões da placa como argumentos de linha de comando (com D implícito no número de argumentos). Adivinha como números separados por espaço em stdin.

YRR_MgWd:++i&RT$+(y-(q^s))**2Pd"Won in ".i

Esse código tira grande vantagem dos recursos de programação de array do Pip. A matriz de cmdline args é armazenada em g. Geramos o ponto a ser imaginado por mapeamento do operador randrange RRsobre g, e puxar a lista resultante na yvariável. Em seguida, vem o loop while principal, onde a condição é a seguinte:

d:++i&RT$+(y-(q^s))**2

  ++i&                  Increment i, the guess counter; the result is always > 0, so the
                          short-circuiting & operator evaluates the next expression:
              q         Read a line from stdin
               ^s       Split on spaces
           y-(   )      Subtract from our chosen point itemwise
          (       )**2  Square, itemwise
        $+              Fold on +, summing the list of squares
      RT                Square root
d:                      Assign this distance to d

Se a distância for diferente de zero, o interior do loop a imprimirá. Se fosse zero, atingimos o ponto alvo; o loop é interrompido e o programa gera a mensagem de vitória e o número de turnos.

Exemplo de execução:

C:\Users\dlosc> pip.py -f guessing.pip 10 5 6 4
5 2 3 2
3.1622776601683795
6 2 3 2
4.123105625617661
3 2 3 2
1.4142135623730951
3 1 3 2
2.23606797749979
3 2 2 2
1.7320508075688772
2 2 3 2
1
2 2 3 1
1.4142135623730951
2 3 3 2
Won in 8
DLosc
fonte
2

R, 134-150 = -16 bytes

function(...){G=sapply(list(...),sample,1)
C=0
repeat{g=scan()
C=C+1
if(any(G!=g))cat(sqrt(sum((G-g)^2)))else{cat("Won in",C);break}}}
modelo
fonte
2

Haskell, 240 - 150 = 90

import System.Random
r x=randomRIO(0,x-1)
m=map read.words
g=getLine
main=do g;(fmap m g::IO[Int])>>=mapM r>>=b 1
b c v=do i<-fmap(sqrt.fromIntegral.sum.map(^2).zipWith(-)v.m)g;if i==0 then putStrLn$"Won in "++show c else do print i;b(c+1)v
Damien
fonte
1

Dyalog APL , 77 71-210 = -139

S F M
P←?S
{P←S|P+(?D)⌽D↑Mׯ1 1[?2]
C+←1
P≢G←⎕:0⊣⎕←.5*⍨+/2*⍨P-G
C}⍣≢C←0

Está bem:

Observe que isso é executado na origem do índice 0 ( ⎕IO←0), que é padrão em muitos APLs.
Adota o modo booleano como argumento da direita ( M) e os tamanhos das dimensões como argumento da esquerda ( S).
O número de dimensões é D, que deve ser definido (por exemplo D←3) antes da chamada, conforme OP).
P←?So objetivo obtém um ponto aleatório no intervalo 1, embora cada dimensão limite
{}⍣≢C←0repita a função até que o resultado seja diferente de C, que inicialmente obtém o 0
?2número aleatório 0 ou 1
¯1 1[]indexe da lista de dois números
multiplicados por modo; faz 0se o modo for ajustar a meta atual, salvar um novo contador de incremento de pontos de meta0
D↑ pad com 0s para corresponder ao número de dimensões e
(?D)⌽gire a lista aleatoriamente (de 0 a número de dimensões-1)
P+
S| módulo em tamanho de mundo da e
P←
C+←1
P≢G←⎕:palpite de entrada e se for diferente do ponto de meta, então ... as
P-Gdistâncias em cada dimensão
2*⍨ao quadrado
+/somam a impressão de
.5*⍨raiz quadrada
⎕←que
0⊣retorna 0 (ou seja, idêntico ao valor inicial, repita)
C... caso contrário, retorne o número de suposições ( sendo diferente de 0, interrompe o loop e retorna o último valor)

Adão
fonte
@ Dennis Na verdade, eu quebrei quando fiz uma função, então agora é um programa novamente. Eu salvei tantos bytes quanto "programmity" me custou mudando para a origem do índice 0, que o OP permite.
Adám 02/11/2015
1
ESTÁ BEM. Por curiosidade: Que dialeto é esse? Eu não tenho idéia do que a primeira linha deve fazer ...
Dennis
@Dennis Dyalog. Esta é uma função tradicional, a primeira linha é a linha [0], ou seja, o cabeçalho da função, mas parece incomum porque possui o argumento à esquerda fn-name à direita arg, mas não há resultado.
Adám 03/11/2015