Płaska gra w zgadywanie

13

Jest taka gra, w którą lubię grać. Dzieje się to na siatce o skończonych rozmiarach (ale jest owinięty jak kula). Na tej siatce wybierany jest losowy (tylko liczba całkowita) punkt. Następnie ja, użytkownik, otrzymuję monit o podanie współrzędnych. Jeśli mój wkład dokładnie pasuje do losowego punktu, powiedziano mi, że wygrałem. W przeciwnym razie powiedziano mi o punktowej odległości między moim wejściem a punktem losowym. Na przykład, jeśli zgadłem, (2,2)a losowy punkt był w (4,3), wtedy odległość byłaby sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

Gra trwa, dopóki gracz nie dotrze do właściwej lokalizacji punktu.


Cel Utwórz funkcjonalną wersję gry opisaną powyżej. Aby to zrobić, musisz utworzyć pełny program. Oto, co powinien zrobić Twój program:

  1. Poproś o dwa dane wejściowe: wysokość i szerokość tablicy. Początek znajduje się w lewym górnym rogu planszy. Te dane wejściowe nie przekroczą 1024.
  2. Wybierz losowy punkt na tej planszy; to będzie punkt do zgadnięcia.
  3. Zaakceptuj wejście symulujące zakręt. Wejście będzie albo oddzieloną spacją liczbą całkowitą, albo dwoma oddzielnymi wejściami całkowitymi. W odpowiedzi na te dane wejściowe program wykona jedną z dwóch czynności:
    1. Jeśli wejście odpowiada wybranemu losowo punktowi, wyślij komunikat sygnalizujący zwycięstwo użytkownika. Sugerowałbym „Wygrałeś!”.
    2. W przeciwnym razie wyświetl odległość między punktem wejściowym użytkownika a punktem losowym.
    W obu przypadkach należy zwiększyć licznik obrotów.
  4. Gdy użytkownik osiągnie zwycięstwo, wyświetl liczbę wykonanych przez niego obrotów. Program następnie kończy pracę.

Bonusy

Bonusy są stosowane w kolejności, w jakiej występują na tej liście

  • -150 bajtów, jeśli twój program przyjmuje całkowitą liczbę wejściową Dopisującą wymiar, w którym gra się odbywa. Np. Jeśli D = 3, to utworzysz losowy punkt 3liczb całkowitych, weź wartości 3całkowite i wyprowadzisz odległość między tymi punktami.
  • -50% (lub + 50%, jeśli score < 0), jeśli zapewnisz graficzną reprezentację planszy (ASCII lub obraz), która pokazuje, gdzie użytkownik wcześniej odgadł na siatce o podanych wymiarach i licznik obrotów. (Jeśli wybierzesz pierwszą premię, ta premia dotyczy tylko trybów 2Di 1D. Jeśli dodasz wyjście graficzne 3D, otrzymasz dodatkowe -50%.)
  • -60 bajtów, jeśli możesz podać tryb gry (wybrany przez wejście na początku; to znaczy, jeśli podano 0, wykonaj zwykły tryb gry; jeśli podano 1, wykonaj ten tryb gry), w którym punkt przesuwa się o 1 jednostkę w losowym kierunku ortogonalnym na turę

Więcej na temat pakowania

Zawijanie następuje tylko wtedy, gdy w trzeciej premii punkt ruchu przesuwa się przez dowolną granicę; w tym przypadku punkt ruchomy jest wypaczony do odpowiedniego punktu, tak jak:

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

To zachowanie owijania nie wpływa na zgadywanie użytkownika, poza tym, że punkt zmienił kierunek.


Tabela liderów

Fragment kodu na dole tego postu generuje katalog na podstawie odpowiedzi a) jako listy najkrótszych rozwiązań dla każdego języka oraz b) jako ogólnej tabeli wyników.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

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

Conor O'Brien
źródło
7
Drobny nitpick: prawdopodobnie masz na myśli, że owija się jak torus, a nie kula. Niemożliwe jest owinięcie siatki 2D kulą bez tworzenia nieciągłości.
Alistair Buxton,
2
Również, jeśli plansza się zawija, wtedy może być krótsza ścieżka między zgadywaniem a celem przez przekroczenie krawędzi.
Alistair Buxton
1
@NBZ Tak, możesz.
Conor O'Brien
1
@NBZ 1 jednostka to pojedynczy kierunek.
Conor O'Brien
2
1. Nadal nie jestem pewien, jaka jest topologia. Aby pomóc wyjaśnić sytuację, jeśli plansza jest 10x10, losowy punkt to (9,4), jak sądzę (2,2), odległość sqrt(13)lub sqrt(53)? (Uwaga na przyszłość: jeśli robisz coś dziwnego, nie dołączaj losowości, ponieważ prawie niemożliwe jest dostarczenie przypadków testowych). 2. Czy w trzeciej premii należy obliczyć odległość i wyprowadzić ją przed lub po przesunięciu punktu?
Peter Taylor,

Odpowiedzi:

8

CJam, -113 -139 -152 -157 -159 bajtów

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

Program ma 51 bajtów długości i kwalifikuje się do premii -150 bajtów i -60 bajtów .

Tryb gry i liczbę wymiarów odczytuje się jako argument wiersza poleceń, wielkość w każdym wymiarze z STDIN. Ponieważ komunikat o zwycięstwie jest arbitralny , program wydrukuje 0.0(odległość do bramki), aby wskazać, że gra się skończyła.

Przebiegi testowe

$ 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

Jak to działa

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
źródło
2
A Dennis ograł wszystkich. Jeszcze raz.
Seadrus
1
Przypadkowo zaktualizowałeś wynik do 152 zamiast -152, umieszczając Cię na ostatnim miejscu w tabeli liderów
Łoś
7

Pyth, 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

Stare rozwiązanie: (54-150 = -96)

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

Wszystkie dane wejściowe odbywają się w nowej linii.

  • Pierwsza liczba całkowita reprezentuje tryb gry ( albo 1lub0 )
  • Pierwsza druga liczba całkowita Dreprezentuje wymiary gry.
  • Następne Ddane wejściowe reprezentują rozmiar pola
  • Każde Dwejście od tego momentu jest domysłem

Odtwarzanie przykładowe (podpowiedzi nie pojawiają się w rzeczywistym programie):

  #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
Łoś
źródło
Czy drugi ruch nie powinien wygrać?
JNF
@JNF punkt może się poruszać w trybie 1 (bonus -60 bajtów)
Jakube
Holy Moly, to jakiś długi kod pyth. Nie bardzo golfowy. Na przykład widzę dwie spacje, które można usunąć. Ponadto: Możesz użyć J=YmOvwvwzamiast VvwaYOvw;JY, który jest o 2 bajty krótszy. Nie przejrzałem drugiego kodu, ale myślę, że można tam również skrócić kilka rzeczy.
Jakube,
@ Jakube, zakładałem, że podpowiedź mówi nam, gdzie jest teraz punkt
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

Pierwsze wyzwanie tylko do tej pory. Wypróbuj online

Mego
źródło
3

Pip, 43 42 bajty - 150 = -108

Traktuje wymiary tablicy jako argumenty wiersza poleceń (z D domyślną z liczby argumentów). Przyjmuje domysły jako liczby rozdzielone spacją na standardowym wejściu.

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

Ten kod w dużym stopniu wykorzystuje funkcje programowania tablic Pipa. Tablica argumentów cmdline jest przechowywana w g. Generujemy punkt się domyślić, mapując operatora randrange RRnad gi pociągnąć otrzymanej listy do yzmiennej. Następnie pojawia się główna pętla while, w której warunek jest następujący:

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

Jeśli odległość była niezerowa, drukuje ją wewnętrzna część pętli. Jeśli było zero, osiągnęliśmy punkt docelowy; pętla zatrzymuje się, a program wyświetla komunikat o zwycięstwie i liczbę zwojów.

Przykładowy przebieg:

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
źródło
2

R, 134-150 = -16 bajtów

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}}}
flodel
źródło
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
źródło
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

Dobrze:

Zauważ, że działa to w indeksie origin 0 ( ⎕IO←0), który jest domyślny w wielu APL-ach.
Pobiera tryb logiczny jako prawy argument ( M), a rozmiary wymiarów jako lewy argument ( S).
Liczba wymiarów to D, którą należy ustawić (np. D←3) Przed wywołaniem, zgodnie z OP).
P←?Scel otrzymuje losowy punkt w zakresie 1, choć każda z granic wymiaru
{}⍣≢C←0Powtarzaj funkcję, aż wynik będzie inny niż C, który początkowo otrzymuje 0
?2losową liczbę 0 lub 1
¯1 1[]indeks z listy dwóch liczb
pomnożonych przez tryb; sprawia 0, że jeśli trybem jest 0
D↑pad z 0s, aby dopasować liczbę wymiarów,
(?D)⌽losowo obracaj listę (od 0 do liczby wymiarów-1)
P+dostosuj aktualny
S|moduł światowego rozmiaru celu
P←zapisz nowe dane wejściowe
C+←1licznika przyrostu punktu celu
P≢G←⎕:, a jeśli różni się on od punktu celu, to ...
P-Godległości w każdym wymiarze
2*⍨kwadratowym
+/zsumuj je
.5*⍨pierwiastek kwadratowy,
⎕←który
0⊣zwróci 0 (tj. identyczny z wartością początkową, więc powtórz)
C... inaczej, zwróć liczbę domysłów (która różni się od 0, zatrzymuje zapętlenie i zwraca ostatnią wartość)

Adám
źródło
@Dennis Właściwie zepsułem go, kiedy uczyniłem go funkcją, więc teraz jest to znowu program. Zapisałem tyle bajtów, ile kosztowała mnie „programowość”, przechodząc na indeks 0, na co pozwala OP.
Adám
1
DOBRZE. Z ciekawości: co to za dialekt? Nie mam pojęcia, co powinna zrobić pierwsza linia ...
Dennis
@Dennis Dyalog. Jest to tradycyjna funkcja, pierwszą linią jest linia [0], tj. Nagłówek funkcji, ale wygląda ona nietypowo, ponieważ ma lewy argument fn-name prawy-argument, ale nie ma wyniku.
Adám