Game tebak datar

13

Ada permainan yang saya suka mainkan. Itu terjadi pada kotak ukuran terbatas (tapi itu dibungkus, seperti bola). Pada kisi itu, titik acak (hanya bilangan bulat) dipilih. Kemudian, saya, pengguna, diminta untuk memasukkan koordinat. Jika input saya persis sama dengan titik acak, saya diberitahu bahwa saya telah menang. Kalau tidak, saya diberitahu jarak titik-bijaksana antara input saya dan titik acak. Misalnya, jika saya menebak (2,2)dan titik acak berada (4,3), maka jaraknya akan menjadi sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

Permainan berlanjut sampai pemain tiba di lokasi yang benar dari titik tersebut.


Tujuan Membuat versi fungsional permainan yang dijelaskan di atas. Anda harus membuat program lengkap untuk melakukannya. Inilah yang harus dilakukan oleh program Anda:

  1. Minta dua input: tinggi dan lebar papan. Asalnya ada di kiri atas papan. Input ini tidak akan melebihi 1024.
  2. Pilih titik acak di papan itu; ini akan menjadi titik untuk ditebak.
  3. Terima input yang mensimulasikan belokan. Input akan berupa sepasang integer yang dipisahkan ruang atau dua input integer yang terpisah. Menanggapi masukan ini, program akan melakukan satu dari dua hal:
    1. Jika input cocok dengan titik acak yang dipilih, output pesan menandakan kemenangan pengguna. Saya akan menyarankan "Kamu menang!".
    2. Jika tidak, keluarkan jarak antara titik input pengguna dan titik acak.
    Dalam kedua kasus, Anda harus menambah penghitung putaran.
  4. Setelah pengguna mencapai kemenangan, tampilkan jumlah putaran yang dilakukan pengguna. Program kemudian keluar.

Bonus

Bonus diterapkan sesuai urutan kemunculannya dalam daftar ini

  • -150 byte jika program Anda mengambil integer input Dyang menjelaskan dimensi di mana game berlangsung. Misalnya, jika D = 3, maka Anda membuat titik 3bilangan bulat acak , mengambil 3input bilangan bulat, dan menampilkan jarak antara titik-titik itu.
  • -50% (atau + 50% jika score < 0) jika Anda memberikan representasi grafis dari papan (ASCII atau Gambar) yang menunjukkan di mana pengguna sebelumnya telah menebak pada kotak dimensi yang diberikan dan penghitung putaran. (Jika Anda memilih bonus pertama, maka bonus ini hanya berlaku untuk 2Ddan 1Dmode. Jika Anda menambahkan output grafis 3D, Anda mendapatkan tambahan -50%.)
  • -60 byte jika Anda dapat memberikan gamemode (dipilih oleh input di awal; yaitu, ketika diberikan 0, melakukan gamemode biasa; ketika diberikan 1, lakukan gamemode ini) di mana titik bergerak 1 unit dalam arah ortogonal acak per putaran

Lebih lanjut tentang pembungkus

Pembungkus hanya terjadi ketika, dalam bonus ketiga, titik bergerak bergerak melintasi batas mana pun; dalam hal ini, titik bergerak dibengkokkan ke titik masing-masing, seperti:

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

Perilaku membungkus ini tidak mempengaruhi tebakan pengguna, selain dari fakta bahwa titik telah berubah arah.


Papan peringkat

Cuplikan Stack di bagian bawah posting ini menghasilkan katalog dari jawaban a) sebagai daftar solusi terpendek per bahasa dan b) sebagai leaderboard keseluruhan.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

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

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (mis. Karena skor Anda adalah jumlah dari dua file atau Anda ingin membuat daftar hukuman penterjemah secara terpisah), pastikan bahwa skor sebenarnya adalah angka terakhir di tajuk:

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

Anda juga dapat membuat nama bahasa menjadi tautan yang kemudian akan muncul di cuplikan:

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

Conor O'Brien
sumber
7
Nitpick minor: Anda mungkin bermaksud membungkus seperti torus, bukan bola. Mustahil untuk membungkus kisi 2D ke dalam bola tanpa membuat diskontinuitas.
Alistair Buxton
2
Juga jika papan membungkus maka mungkin ada jalan yang lebih pendek antara tebakan dan target dengan melewati batas.
Alistair Buxton
1
@NBZ Ya, Anda bisa.
Conor O'Brien
1
@NBZ 1 unit itu satu arah.
Conor O'Brien
2
1. Saya masih tidak yakin apa topologi itu. Untuk membantu menjernihkan semuanya, jika papannya adalah 10x10, titik acaknya adalah (9,4), dan saya kira (2,2), apakah jaraknya sqrt(13)atau sqrt(53)? (Catatan untuk masa depan: jika Anda melakukan sesuatu yang aneh, jangan masukkan keacakan karena itu hampir tidak mungkin untuk memasok kasus uji). 2. Dalam bonus ketiga, haruskah jarak dihitung dan dikeluarkan sebelum atau setelah titik bergerak?
Peter Taylor

Jawaban:

8

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

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

Program ini panjangnya 51 byte dan memenuhi syarat untuk bonus -150 byte dan -60 byte .

Mode permainan dan jumlah dimensi dibaca sebagai argumen baris perintah, ukuran di setiap dimensi dari STDIN. Karena pesan kemenangan arbitrer , program akan mencetak 0.0(jarak ke tujuan) untuk menunjukkan bahwa permainan telah berakhir.

Tes berjalan

$ 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

Bagaimana itu bekerja

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
sumber
2
Dan Dennis telah mengalahkan semua orang. Lagi.
Seadrus
1
Anda secara tidak sengaja memperbarui skor menjadi 152 bukannya -152, menempatkan Anda terakhir di papan peringkat
Moose
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

Solusi lama: (54-150 = -96)

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

Semua input dilakukan pada baris baru.

  • Integer pertama mewakili mode permainan ( baik 1atau0 )
  • Pertama bilangan bulat Kedua Dmewakili dimensi bermain.
  • Lanjut D input mewakili ukuran lapangan
  • Setiap D input dari titik ini adalah dugaan

Putar sampel (petunjuk tidak muncul dalam program yang sebenarnya):

  #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
Moose
sumber
Bukankah langkah kedua menang?
JNF
@JNF intinya dapat bergerak dalam gamemode 1 (-60 byte bonus)
Jakube
Moly suci, itu adalah kode pyth panjang. Tidak benar-benar bermain golf. Misalnya saya melihat dua spasi, yang bisa dihapus. Juga: Anda dapat menggunakan J=YmOvwvwsebagai gantinya VvwaYOvw;JY, yang lebih pendek 2 byte. Saya belum melihat-lihat kode yang lain, tetapi saya kira Anda juga dapat mempersingkat beberapa hal di sana.
Jakube 2-15
@ Jakube, saya berasumsi petunjuk itu memberi tahu kita di mana titik saat ini
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

Tantangan pertama hanya sejauh ini. Cobalah online

Mego
sumber
3

Pip, 43 42 byte - 150 = -108

Mengambil dimensi papan sebagai argumen baris perintah (dengan D tersirat dari jumlah argumen). Mengambil tebakan sebagai angka yang dipisahkan ruang pada stdin.

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

Kode ini mengambil keuntungan besar dari fitur pemrograman array Pip. Array cmdline args disimpan di g. Kita menghasilkan titik yang akan ditebak oleh pemetaan operator randrange RRlebih g, dan mencabut daftar yang dihasilkan ke dalam yvariabel. Kemudian muncul loop sementara utama, di mana kondisinya adalah sebagai berikut:

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

Jika jaraknya bukan nol, bagian dalam loop akan mencetaknya. Jika nol, kita sudah mencapai titik target; loop berhenti, dan program menampilkan pesan kemenangan dan jumlah putaran.

Contoh dijalankan:

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
sumber
2

R, 134 - 150 = -16 byte

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
sumber
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
sumber
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

Baik:

Perhatikan bahwa ini berjalan dalam indeks asal 0 ( ⎕IO←0) yang merupakan default di banyak APL.
Mengambil mode boolean sebagai argumen kanan ( M), dan ukuran dimensi sebagai argumen kiri ( S).
Jumlah dimensi adalah D, yang harus diatur (misalnya D←3) sebelum memanggil, sesuai OP).
P←?Ssasaran mendapatkan titik acak dalam rentang 1 meskipun masing-masing dimensi terikat
{... }⍣≢C←0ulangi fungsi hingga hasilnya berbeda C, yang awalnya mendapat 0
?2angka acak 0 atau 1
¯1 1[... ]indeks dari daftar dua angka
dikalikan dengan mode; membuat 0jika mode 0
D↑pad dengan 0s untuk mencocokkan jumlah dimensi
(?D)⌽daftar putar secara acak (0 hingga jumlah dimensi-1)
P+menyesuaikan
S|modulus ukuran-dunia saat ini sasaran,
P←simpan
C+←1penghitung
P≢G←⎕:masukan kenaikan titik sasaran yang baru , dan jika berbeda dari sasaran, maka ...
P-Gjarak di setiap dimensi
2*⍨kuadratkan
+/jumlahnya
.5*⍨dengan hasil
⎕←cetak akar kuadrat yang
0⊣mengembalikan 0 (yaitu identik dengan nilai awal, jadi ulangi)
C... selain itu, kembalikan jumlah tebakan (yang berbeda dari 0, hentikan perulangan dan kembalikan nilai terakhir)

Adm
sumber
@ Dennis Sebenarnya, saya merusaknya ketika saya membuatnya menjadi fungsi, jadi sekarang ini adalah program lagi. Saya menghemat banyak byte sebagai "program" yang menghabiskan biaya dengan beralih ke indeks asal 0, yang memungkinkan OP.
Adám
1
BAIK. Karena penasaran: dialek apa ini? Saya tidak tahu apa yang seharusnya dilakukan oleh baris pertama ...
Dennis
@Dennis Dyalog. Ini adalah fungsi tradisional, baris pertama adalah garis [0], yaitu fungsi header, tetapi terlihat tidak biasa karena memiliki nama kiri -f fn-nama kanan-arg, tetapi tidak ada hasil.
Adám