Плоская игра в догадки

13

Есть игра, в которую я люблю играть. Это происходит на сетке конечного размера (но она обернута, как сфера). На этой сетке выбирается случайная (только целочисленная) точка. Затем мне, пользователю, предлагается ввести координаты. Если мои данные точно совпадают со случайной точкой, мне говорят, что я выиграл. В противном случае мне сообщают точечное расстояние между моим входом и случайной точкой. Например, если бы я угадал, (2,2)и случайная точка была в (4,3), то расстояние было бы sqrt[(3-2)^2 + (4-2)^2] = sqrt[5].

Игра продолжается до тех пор, пока игрок не окажется в правильном месте точки.


Задача Создать функциональную версию игры, описанную выше. Вы должны создать полную программу для этого. Вот что должна делать ваша программа:

  1. Запросите два ввода: высоту и ширину доски. Источник находится в верхнем левом углу доски. Эти входы не будут превышать 1024.
  2. Выберите случайную точку на этой доске; это будет точка, которую нужно угадать.
  3. Принять ввод, имитирующий поворот. Входными данными будут либо пара целых чисел, разделенных пробелами, либо два отдельных целочисленных входа. В ответ на этот ввод программа выполнит одно из двух действий:
    1. Если вход соответствует выбранной случайной точке, выведите сообщение, сигнализирующее о победе пользователя. Я бы предложил «Вы выиграли!».
    2. В противном случае выведите расстояние между точкой ввода пользователя и случайной точкой.
    В любом случае вы должны увеличить счетчик поворотов.
  4. Как только пользователь добился победы, отобразите количество поворотов, которые сделал пользователь. Программа затем выходит.

Бонусы

Бонусы применяются в порядке их появления в этом списке

  • -150 байт, если ваша программа принимает входное целое число, Dкоторое описывает размер, в котором происходит игра. Например, если D = 3, тогда вы создаете случайную точку 3целых чисел, берете 3целочисленные входные данные и выводите расстояние между этими точками.
  • -50% (или + 50%, если score < 0), если вы предоставляете графическое представление доски (ASCII или рисунок), которая показывает, где пользователь ранее угадал на сетке заданных размеров и счетчика поворотов. (Если вы идете в первый бонус, то этот бонус применяется только к 2Dи 1Dрежимам. При добавлении графического вывода 3D, вы получаете дополнительные -50%) .
  • -60 байт, если вы можете предоставить игровой режим (выбранный входом в начале; то есть, если дано 0, выполнить обычный игровой режим; когда дано 1, выполнить этот игровой режим), в котором точка перемещается на 1 единицу в случайном ортогональном направлении за ход

Подробнее об упаковке

Свертывание происходит только тогда, когда в третьем бонусе движущаяся точка перемещается через любую из границ; в этом случае точка перемещения деформируется в соответствующую точку, например так:

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

Такое поведение обтекания не влияет на догадки пользователя, за исключением того факта, что точка изменила направление.


Leaderboard

Фрагмент стека в нижней части этого поста создает каталог из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

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

Если вы хотите включить в свой заголовок несколько чисел (например, потому что ваш счет равен сумме двух файлов или вы хотите перечислить штрафы за флаг интерпретатора отдельно), убедитесь, что фактический результат является последним числом в заголовке:

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

Вы также можете сделать имя языка ссылкой, которая затем будет отображаться во фрагменте:

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

Конор О'Брайен
источник
7
Незначительный придурок: вы, вероятно, имеете в виду, что он оборачивается как торус, а не сфера. Невозможно обернуть 2D-сетку в сферу, не создавая разрывов.
Алистер Бакстон
2
Кроме того, если доска оборачивается, то может быть более короткий путь между догадкой и целью, пересекая границу.
Алистер Бакстон
1
@NBZ Да, вы можете.
Конор О'Брайен
1
@NBZ 1 единица это одно направление.
Конор О'Брайен
2
1. Я все еще не уверен, что топология. Чтобы прояснить ситуацию, если на доске есть 10x10случайная точка (9,4), я думаю (2,2), это расстояние sqrt(13)или sqrt(53)? (Примечание на будущее: если вы делаете что-то странное, не включайте случайность, потому что практически невозможно предоставить контрольные примеры). 2. В третьем бонусе следует вычислять и выводить расстояние до или после перемещения точки?
Питер Тейлор

Ответы:

8

CJam, -113 -139 -152 -157 -159 байтов

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

Программа имеет длину 51 байт и имеет право на бонусы -150 байт и -60 байт .

Режим игры и количество измерений читаются как аргумент командной строки, размер в каждом измерении из STDIN. Поскольку сообщение о победе является произвольным , программа напечатает 0.0(расстояние до цели), чтобы указать, что игра окончена.

Тестовые прогоны

$ 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

Как это устроено

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.
Деннис
источник
2
И Деннис всех переиграл. Опять таки.
Seadrus
1
Вы случайно обновили счет до 152 вместо -152, став последним в списке лидеров
Moose
7

Пиф, 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

Старое решение: (54-150 = -96)

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

Весь ввод происходит в новой строке.

  • Первое целое число представляет режим игры ( либо, 1либо0 )
  • Первое Второе целое число Dпредставляет размеры игры.
  • Следующие Dвходы представляют размер поля
  • Каждый Dвход с этого момента является догадкой

Пример воспроизведения (подсказки не появляются в реальной программе):

  #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
лось
источник
Разве второй ход не должен победить?
JNF
@JNF точка может перемещаться в игровом режиме 1 (бонус -60 байт)
Jakube
Боже мой, это какой-то длинный код. Не совсем в гольф, хотя. Например, я вижу два пробела, которые можно удалить. Также: вы можете использовать J=YmOvwvwвместо VvwaYOvw;JY, что на 2 байта короче. Я не просматривал другой код, но я думаю, что вы также можете сократить несколько вещей там.
Якуб
@ Якуб, я предполагал, что подсказка говорит нам, где находится точка
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

Первый вызов только пока. Попробуйте онлайн

Mego
источник
3

Пип, 43 42 байта - 150 = -108

Принимает размеры платы в качестве аргументов командной строки (с D подразумевается из числа аргументов). Принимает догадки как разделенные пробелами числа на стандартном вводе.

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

Этот код в значительной степени использует возможности программирования массивов в Pip. Массив аргументов cmdline хранится в g. Мы создаем точку, которая догадалась путем сопоставления оператора randrange RRнад gи дергать полученный список в yпеременной. Затем следует основной цикл while, где условие выглядит следующим образом:

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

Если расстояние было ненулевым, внутренняя часть цикла печатает его. Если это было ноль, мы достигли целевой точки; цикл останавливается, и программа выводит сообщение о победе и количество ходов.

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

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
источник
2

R 134 - 150 = -16 байт

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
источник
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
источник
1

Дьялог АПЛ , 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

Ok:

Обратите внимание, что это выполняется в источнике индекса 0 ( ⎕IO←0), который используется по умолчанию во многих APL.
Принимает логический режим в качестве правого аргумента ( M), а размеры в качестве левого аргумента ( S).
Количество измерений D, которое должно быть установлено (например, D←3перед вызовом, согласно OP).
P←?Sцель получает случайную точку в диапазоне 1, хотя каждая из границ измерения
{... }⍣≢C←0повторяет функцию до тех пор, пока результат не отличается от результата C, который изначально получает 0
?2случайное число 0 или 1
¯1 1[... ]индекс из списка двух чисел,
умноженных на режим; делает, 0если режим равен 0
D↑pad с 0s, чтобы соответствовать количеству измерений, корректирует текущую цель, модуль размера мира
(?D)⌽ вращать список случайным образом (от 0 до количества измерений-1)
P+
S|
P← сохранить новое предположение
C+←1счетчика приращения точки цели
P≢G←⎕:, и если оно отличается от точки цели, то ...
P-Gрасстояния в
2*⍨квадрате каждого измерения
+/суммируют их
.5*⍨квадратно-корневую
⎕←печать, которая
0⊣возвращает 0 (т. е. идентично исходному значению, поэтому repeat)
C... else, возвращает количество догадок (которое, в отличие от 0, останавливает цикл и возвращает последнее значение)

Адам
источник
@Dennis На самом деле, я сломал его, когда сделал его функцией, так что теперь это снова программа. Я сэкономил столько байтов, сколько стоило мне «программирование», переключившись на начало индекса 0, что позволяет OP.
Адам
1
OK. Из любопытства: какой это диалект? Я понятия не имею, что должна делать первая строка ...
Деннис
@ Денис Дьялог. Это традиционная функция, первая строка - строка [0], то есть заголовок функции, но выглядит необычно, потому что у нее есть левое-аргумент fn-name-right-arg, но нет результата.
Адам