GolfScript - 181 个字符
换行符不是必需的。输出为标准输出,但 stderr 中存在一些错误。
\10
应替换为相应的 ASCII 字符,程序长度为 181 个字符。
{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{\!:F;>P{\(@{3&\(@.2$&F|:F;|}%\+}%\+F![f]P+:P
;}do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ 10R*+n*
输入/输出示例:
$ cat inp
[ ]
[ ]
[ ]
[ ]
[ # # #]
[ ## ######]
[==========]
T2 Z6 I0 T7
$ cat inp|golfscript tetris.gs 2>/dev/null
[ ]
[ ]
[ ]
[# ###]
[# ### ]
[##### ####]
[==========]
10
Tetromino 压缩:
棋子存储为三个 8 位基数。这是一个简单的二进制表示,例如T=[7,2,0], S=[6,3,0], J=[2,2,3]
. [1]
用于I
压缩中的片段,但这被明确设置为[1,1,1,1]
稍后(即4*
在代码中)。所有这些数组都连接成一个数组,该数组被转换为一个整数,然后是一个字符串(基数为 126 以最小化不可打印字符、长度,并且不会遇到 utf8)。这个字符串很短:"R@1(XBc_"
.
然后解压就很简单了。我们首先进行基数 126 转换,然后进行基数 8 转换("~\10"{base}/
,即迭代"~\10"
并对每个元素进行基本转换)。结果数组被分成 3 组,数组为I
是固定的(3/~4*
)。然后,我们将每个元素转换为基数 2,并(在删除零之后)将每个二进制数字替换为字符串中该索引的字符" #"
(2base{" #"=}%...-1%
- 请注意,否则我们需要反转数组2
会成为"# "
代替" #"
).
棋盘/棋子格式,掉落棋子
棋盘只是一个字符串数组,每一行一个字符串。最初没有对此进行任何工作,因此我们可以使用以下命令生成它n/(
在输入上。片段也是字符串数组,在其 X 位置左侧填充空格,但没有尾随空格。通过预先添加到数组中并不断测试是否存在碰撞来丢弃碎片。
碰撞测试是通过迭代片段中的所有字符并与棋盘上相同位置的字符进行比较来完成的。我们想要重视#
+=
and #
+#
作为碰撞,所以我们测试 ((piecechar&3)&boardchar) 是否非零。在进行此迭代时,我们还使用 ((piecechar&3)|boardchar) 更新棋盘(的副本),这会正确设置对的值#
+
,
+#
,
+[
。如果将棋子移至另一行后发生碰撞,我们将使用此更新的棋盘。
删除填充的行非常简单。我们删除所有行"= "&
返回假。填充的行将两者都没有=
or
,因此连词将是一个空字符串,相当于 false。然后我们计算已删除的行数,将计数添加到分数中并在前面添加这些行数"[ ... ]"
s。我们通过获取网格的第一行并替换来紧凑地生成它#
with
.
Bonus
由于我们计算棋子落下时棋盘在每个位置的样子,因此我们可以将它们保留在堆栈中而不是删除它们!对于总共三个字符,我们可以输出所有这些位置(如果我们将棋盘状态设置为单倍行距,则可以输出两个字符)。
{):X!-{2B{" #"=}%X" ":f*+-1%}%:P;:>.{>[f]P+:P(!:F;{\(@{3&\(@.2$&F|:F;|}%\+}%\+F!}
do;{"= "&},.,7^.R+:R;[>0="#"/f*]*\+}0"R@1(XBc_""~\10"{base}:B/3/~4*"nIOZTLSJR "
";:"*~;n%)n*~ ]{n*n.}/10R*