猜谜游戏


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输入整数,然后输出这些点之间的距离。
  • score < 0如果您提供木板的图形表示(ASCII或图片),则显示-50%(如果为,则为+ 50%),该图形表示用户先前在给定尺寸的网格和转弯计数器上的猜测位置。(如果您获得第一笔奖金,那么此奖金仅适用于2D1D模式。如果添加3D图形输出,则会获得额外的-50%。)
  • 如果您可以提供一种游戏模式(通过输入在开始时选择;即在给定时0,执行常规游戏模式;在给定时1,执行此游戏模式),则该点为-60字节,其中该点每回合在随机正交方向上移动1个单位

有关包装的更多信息

只有在第三个奖励中,移动点跨越任何边界时,才会发生包装。在这种情况下,移动点会扭曲到相应的点,如下所示:

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

这种包裹行为不会影响用户的猜测,因为点已更改方向。


排行榜

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言的最短解决方案列表,b)作为整体排行榜。

为了确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# 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
小nitpick:您可能会说它像圆环一样包裹着,而不是球形。在不产生不连续性的情况下将2D网格包裹到球体上是不可能的。
Alistair Buxton,2015年

2
同样,如果木板缠绕,那么通过越过边缘,猜测和目标之间的路径可能会更短。
Alistair Buxton,2015年

1
@NBZ是的,可以。
Conor O'Brien 2015年

1
@NBZ 1个方向。
Conor O'Brien 2015年

2
1.我仍然不确定拓扑是什么。为了帮助解决问题,如果木板是10x10,随机点是(9,4),我想这(2,2)是距离sqrt(13)还是sqrt(53)?(将来的注意事项:如果您做任何奇怪的事情,请不要包括随机性,因为它几乎不可能提供测试用例)。2.在第三笔奖金中,应该在点移动之前或之后计算并输出距离吗?
彼得·泰勒

Answers:


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

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

旧解决方案:(54-150 = -96)

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

所有输入都在新行上进行。

  • 第一个整数表示游戏模式(要么10
  • 第一,第二整数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 2015年

@JNF点可以在游戏模式1中移动(-60字节奖励)
Jakube 2015年

天哪,这是一些长的pyth代码。虽然不是真的打高尔夫球。例如,我看到两个空格可以删除。另外:您可以使用J=YmOvwvw代替VvwaYOvw;JY,后者要短2个字节。我没有看过其他代码,但是我想您也可以在其中缩短一些内容。
2015年

@Jakube,我假设提示告诉我们当前的位置
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

到目前为止只有第一个挑战。在线尝试


3

点,43 42个字节-150 = -108

将面板尺寸作为命令行参数(从args的数量中隐含D)。将猜测作为标准输入上以空格分隔的数字。

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

该代码充分利用了Pip的数组编程功能。cmdline args数组存储在中g。我们生成点通过映射randrange运营商猜到RRg,和猛拉结果列表到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

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

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

1

Dyalog APL77 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

好:

请注意,这在索引原点0(⎕IO←0)中运行,这在许多APL中是默认值。
将布尔模式作为右参数(M),将尺寸大小作为左参数(S)。
尺寸数为D,必须D←3在调用之前根据OP 进行设置(例如)。
P←?S尽管每个维度范围,目标都获得了范围1内的随机点
{}⍣≢C←0重复该函数,直到结果与不同C,该函数最初获得的是0
?2随机数0或1
¯1 1[]从两个数字的列表中得到的索引
乘以模式;使得0如果mode是0
D↑填充以0s来匹配维度数的pad,则
(?D)⌽随机旋转列表(0到维度数1)
P+调整当前目标的
S|世界尺寸模数,
P←保存新的目标点
C+←1增量计数器
P≢G←⎕:输入的猜测值,如果与目标点不同,则...
P-G每个维度的距离
2*⍨平方
+/求和,得出它们
.5*⍨的平方根
⎕←打印结果
0⊣返回0(即等于初始值,所以重复)
C...否则,返回猜测的数量(与0不同的值将停止循环并返回最后一个值)


@Dennis实际上,我在将其设置为函数时将其破坏,所以现在它又是一个程序。通过切换到OP允许的索引原点0,我节省了与“可编程性”一样多的字节。
2015年

1
好。出于好奇:这是哪一种方言?我不知道第一行应该做什么...
丹尼斯

@丹尼斯·迪亚洛格(Dennis Dyalog)。这是一个传统函数,第一行是[0]行,即函数头,但看起来不寻常,因为它具有left-arg fn-name right-arg,但没有结果。
2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.