进行中的ASCII Hangman


21

(受到有关代码审查的问题的启发)

假设有两个人在玩《Hangman》,但您只是听错了游戏,想绘制当前状态。

给定两个单词作为输入,每个单词匹配[A-Z]+[a-z]+(您选择)一个单词,按照以下规则将rules子手游戏的当前状态输出为ASCII艺术。

  • 第一个单词是要猜测的单词,第二个单词是已经猜测的字母。这些可以按任何顺序作为输入。
  • 要猜测的单词保证为非空,但已经被猜测的字母可能为空(即,好像是游戏的开始)。
  • 该游戏将始终是有效的子手游戏(即,不会重复猜出的字母,不会在游戏结束时猜到字母,您只会收到字母作为输入,等等)。
  • 子手图画下方必须是要猜的单词,用_空格隔开,以代替尚不为人所知的字母。例如,如果要猜的单词是BOAT,则在hangman图下面必须是_ _ _ _。如果这个词被BOATA猜,然后在下面的图必须_ _ A _
  • 下面这个词来猜测一定是已经猜到的字母是不是在这个词。它们可以按任何顺序排列,并且可以根据需要用任何非字母分隔符分隔。

从最初开始到游戏结束,这是the子手游戏的状态。每个错误猜出的字母都会使状态前进一个。因此,第一个错误猜出的字母使头部O出现,下一个使身体|出现,等等。

  +---+
  |   |
      |
      |
      |
      |
=========

  +---+
  |   |
  O   |
      |
      |
      |
=========

  +---+
  |   |
  O   |
  |   |
      |
      |
=========

  +---+
  |   |
  O   |
 /|   |
      |
      |
=========

  +---+
  |   |
  O   |
 /|\  |
      |
      |
=========

  +---+
  |   |
  O   |
 /|\  |
 /    |
      |
=========

  +---+
  |   |
  O   |
 /|\  |
 / \  |
      |
=========

输入项

  • 任何方便格式的两个字符串,第一个保证为非空。
  • 您可以按任何顺序输入(例如,先猜单词然后猜字母,反之亦然)。请在您的提交中说明输入顺序。

输出量

如上所述,进行中的子手游戏的最终ASCII艺术表现形式也以任何方便的格式出现。

规则

  • 前导或尾随的换行符或空格都是可选的,只要字符本身正确对齐即可。
  • 完整的程序或功能都是可以接受的。如果是函数,则可以返回输出而不是打印输出。
  • 如果可能,请提供一个在线测试环境的链接,以便其他人可以尝试您的代码!
  • 禁止出现标准漏洞
  • 这是因此所有常见的高​​尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

例子

#1

BOATATG

  +---+
  |   |
  O   |
      |
      |
      |
=========
_ _ A T
G

#2

ZEPPELIN

  +---+
  |   |
      |
      |
      |
      |
=========
_ _ _ _ _ _ _ _

#3

ZEPPELINEATOLINSHR

  +---+
  |   |
  O   |
 /|\  |
 / \  |
      |
=========
_ E _ _ E L I N
A T O S H R

#4

RHYTHMABCDE

  +---+
  |   |
  O   |
 /|\  |
 /    |
      |
=========
_ _ _ _ _ _
EDCBA

#5

BOATATOB

  +---+
  |   |
      |
      |
      |
      |
=========
B O A T

#6

AIRPLANEAJKEI

  +---+
  |   |
  O   |
  |   |
      |
      |
=========
A I _ _ _ A _ E
KJ

错误的字母必须保留输入顺序?
罗德

@Rod不,不需要保留错误猜测的顺序。
AdmBorkBork

2
请添加一个测试用例,其中所有字母都是正确的猜测,而所有字母都是正确的猜测
Xcoder先生17年

@ Mr.Xcoder我添加了测试案例#5,该人员立即成功猜出了“ BOAT”。
AdmBorkBork

我添加了一个仅包含2个错误字母的测试用例,以区分正确的构建顺序和自上而下/从左至右的构建。
贾斯汀·马里纳

Answers:


10

Python 2中215个 192 184 183字节

感谢RaphaëlCôté - 8个
字节感谢Jonathan Frech -1个字节

a,b=input()
j=' '.join
s=b-set(a)
print"""  +---+
  |   |
  %s   |
 %s%s%s  |
 %s %s  |
      |
=========
"""%tuple('O/|\/\\'[:len(s)].ljust(6)),j(['_',i][i in b]for i in a),'\n',j(s)

在线尝试!


通过将所有\ n转换为换行并使用带有“”的多行字符串,以及使用输入的“任何方便的格式”并将set调用设置回输入中,我能够减少到172个字节。
RaphaëlCôté

嗯,您可以链接更改吗?我只勉强达到184个字节
罗德

184很好:从代码中删除集合实际上破坏了输出,因此没有用。更改\ n,使他们成为新行没有帮助,但我其实只是去掉3个字节到189 tio.run/...
拉斐尔的Côté

1
我相信当出现2个错误字母时,您应该显示主体(|)而不是左臂(/):在线尝试
贾斯汀·马林纳

"\\/"等于"\/"
乔纳森·弗雷希

8

木炭83 69 68字节

Fη¿№θι⁰«ι→⊞υι»←⸿Fθ«⎇№ηιι_→»←⸿×=⁸↖=←↑⁵←+←³↓+|FLυ≡ι⁰↓O¹←|²/|³\⁴⸿ /⁵ \«

在线尝试!链接是详细版本的代码。编辑:通过切换到保存14个字节switch。通过将单字本打印|为文字来节省1个字节。注:当时的问题设置,switch根本不以详细模式的工作,需要一个尾随«在简洁模式(TIO当前版本既没有错误,因此它显示简洁翻译为67个字节),而Map的错误阻止我使用Print(Join(Map(q, Ternary(Count(h, i), i, "_")), " "));。幸运的是,我设法弄出了相同长度的节拍(实际上,我也尝试过将另一个循环切换到Map,但它也以相同的长度出现)。说明:

Fη              For each letter in the guess,
  ¿№θι⁰«        if the word to be guessed does not contain the letter,
        ι→      print the failed guess, leave a gap,
          ⊞υι»  and push the letter to the array.

←⸿              Move to the start of the previous line.

Fθ«             For each letter in the word to be guessed,
   ⎇№ηιι        if the letter has been guessed then print it
        _       otherwise print a _.
         →»     Either way, leave a gap.

←⸿              Move to the start of the previous line.

×=⁸             Print 8 =s
   ↖=←          Print a 9th =, moving into position to
      ↑⁵        print 5 |s upwards,
        ←+←³    a + and 3 -s left,
            ↓+| and a + and a | down.

FLυ             Loop once for each incorrect guess.
   ≡ι           Choose what to print based on the loop index.
     ⁰↓O        For the first incorrect guess, print an O.
     ¹←|        For the second incorrect guess, print a |.
     ²/         For the third incorrect guess, print a /.
     ³|\        For the fourth incorrect guess, print a \.
     ⁴⸿ /       For the fifth incorrect guess, print a / on the next line.
     ⁵ \        For the sixth incorrect guess, print another \.

2
这种语言...吓到我了。
谢尔盖·吉林诺夫

@SergeyGrinev D:为什么这么吓人-ASCII
码,仅ASCII,

仅限@ASCII,我注意到您修复了Map(string,expression),但Map(array,expression)仍然存在问题-当用作表达式而不是命令时,它会更改原始数组。在线尝试!
尼尔

@ASCII only呵呵,这是一门语言的好主意,但脚本看起来像Lovecraft用来召唤Cthulhu咒语的东西。
谢尔盖·吉林诺夫

@Neil这是预期的行为,主要是因为它在映射Cells数据类型时会修改画布,但是我想是的,您经常需要在映射后使用原始数据,它应该在明天修复
仅ASCII的

7

Python 2,220字节

x,y=input()
x=[['_',k][k in y]for k in x]
y-=set(x)
s='''  +---+
  |   |
  0   |
 213  |
 4 5  |
      |
'''
for i in range(6):s=s.replace(`i`,[' ','O|/\\/\\'[i]][len(y)>i])
print s+'='*9+'\n'+' '.join(x)+'\n'+''.join(y)

在线尝试!

-35字节感谢 RaphaëlCôté-
20字节,使用集
-1字节感谢micsthepick


3
用数字“替换”的好主意:)
V. Courtois

@ V.Courtois谢谢:)我本来要用的,translate但事实证明这会更长一些。
HyperNeutrino

@HyperNeutrino,您好!提交工作做得很好!我认为使用此方法可以将最后的2个循环合为一体,for i in range(7):s=s.replace(`i`,'O|/\\/\\'[i] if i<c else ' ')它为您提供了一个循环,如果您在c之上,则只需切换掉替换项即可。您可以通过这种方式降低到251个字节:)
拉斐尔·科特

@RaphaëlCôté高尔夫不错。谢谢!
HyperNeutrino

c变得毫无用处。只需使用len(y)并保存4个字节即可!我们摇滚!
拉斐尔·科特

5

果冻 72  73 字节

+1修复了一个显示全死者的ace游戏错误(更改LNLạ6接近尾声)

e€a⁸o”_$,ḟ@©K€Y,@“¥[$⁼Ż⁸½c¤ṫȷṃl®ḌvNṂeL©?Ḥ’ṃ“ -¶|O/\=+”¤Y⁶“$"÷ȷñŒ‘ḣ®Lạ6¤¤¦

双向链接,其左侧为单词,右侧为(游戏中唯一的)字母,并返回字符列表,或者是一个完整的程序,将输入作为命令行参数并打印结果。

在线尝试!

怎么样?

首先:

“¥[$⁼Ż⁸½c¤ṫȷṃl®ḌvNṂeL©?Ḥ’ - base 250 number
                            = 305169639782226039115281574830092231403740634016078676

是完整的倒吊人的在基座9,其中每个的9位表示的一个字符的数值: <space><newline>-|O/\=,或+

该程序的其余部分:

e€a⁸o”_$,ḟ@©K€Y,@“...’ṃ“...”¤Y⁶“...‘ḣ®Lạ6¤¤¦ - Main link word, letters
e€                                           - exists in letters for €ach char in word
  a⁸                                         - and with word (word with 0 at un-guessed)
    o”_$                                     - or with '_' (word with _ at un-guessed)
         ḟ@                                  - filter remove (incorrect guesses)
           ©                                 - copy the result to the register and yield
        ,                                    - pair
            K€                               - join €ach with spaces
              Y                              - join with (a) newlines
                            ¤                - nilad followed by link(s) as a nilad:
                 “...’                       - the number described above
                       “...”                 - list of chars " -¶|O/\=+" (¶ = a newline)
                      ṃ                      - base decompress using the chars as digits
               ,@                            - pair (using swapped @rguments)
                             Y               - join with (a) newlines
                                           ¦ - sparse application:
                              ⁶              -   of: a space character
                                             -   to indexes:
                                          ¤  -     nilad followed by links as a nilad:
                               “...‘         -       literal [36,34,28,26,27,19]
                                         ¤   -       another nilad chain:
                                     ®       -         recall from register
                                      L      -         length (# of bad guesses)
                                       ạ6    -         absolute difference with 6
                                    ḣ        -       head (get the indexes to "erase"
                                             -             by applying the space char)
                                             - as a full program: implicit print

BOATand ATOB测试用例上失败了。在线尝试!
fireflame241

谢谢你指出这一点,我将修复2个字节...只是写一个解释。
乔纳森·艾伦

完成,并将其设为1个字节。
乔纳森·艾伦

注意:当涉及到人时,“悬挂”的过去时是“悬挂”,而不是“悬挂”。只是一个小问题,所以有+1的补偿:)
HyperNeutrino

@ΗγρεŗN̛ευτŗιͷo嘿,我曾经挂在一个地方,却挂在另一个地方,换了另一个。(我也说“完全”,好像这个残缺不全的人也没有被完全绞死)。
乔纳森·艾伦

3

Japt V294个 91 83 81字节

-3个字节来自@ETHproductions对此方法的一些想法。
通过使用多行字符串旋转来获得-8个字节。
使用v2 -2个字节。

["+|||||
-
-
-  35
+|01
   24
"r\d_¨VkU l ?S:"O|/\\/\\"gZÃz '=³³¡VøX ?X:'_øVkU]·

将两个单词输入都作为字符数组,第一个猜测单词,第二个猜测字母。显示错误的字母,用,s 分隔。如果没有不正确的字母,则最后一行为空白(表示输出中包含额外的尾随换行符)。

在线尝试!

说明

隐式:UV是输入字符数组。

["..."

启动一个数组,然后向左旋转90°推吊人格式字符串。

r\d_

用以下功能替换(r)每位数字(\d):

¨VkU l ?S:"O|/\\/\\"gZÃ

如果数字为>=¨),则表示错误的猜测数(VkU l)为空格(S),否则,请获取该数字的适当正文部分("..."gZ)。

z '=³³

将悬挂的人向右旋转90°,然后=重复3 * 3(³³)次将其推入阵列。

¡VøX ?X:'_Ã

将单词映射¡到单词本身,如果单词X包含在VVøX)中,_则将单词()映射到它们自己(),否则将其映射¸到数组。

VkU]·

将猜中的字母(去掉猜中的字母(k))推到输出数组。关闭数组并使用换行符(·)连接。

旋转可视化:

+|||||      +---+
-           |   |
-      ->   0   |
-  35      213  |
+|01       4 5  |
   24             

我有类似的东西:ethproductions.github.io/japt/…(尽管现在我注意到我把中间的三个部分按错误的顺序放置)。我发现您的某些部分比我做的要短,也许我们的答案可以组合成更短的部分。
ETHproductions '17

@ETHproductions我认为您的增量想法W不起作用,因为身体部位没有从左到右/从上到下出现。不过,我能够从您的版本中保存一些字节。
贾斯汀·马里纳

2

05AB1E,83个字节

•LO„Ÿ¼Ì‘Šη…ÔÆ#δʒΣ•6B4ÝJ"+ -|="‡²¹SK©Ùg"O/|\/\"s£v5y.;}7ô»„==«5ð:¹D²SKDg'_ׇSðý®Sðý»

在线尝试!


位图:

05AB1E,18个字节

•LO„Ÿ¼Ì‘Šη…ÔÆ#δʒΣ• # Push number described below in base-10.

在线尝试!

这将推动以下位图计划:

1102220
1131113
1151113
1555113
1515113
1111113
4444444

其中以下附加字节:

05AB1E,13个字节

6B            # Convert to base-6.
  4ÝJ         # Push 01234.
     "+ -|="  # Push that string.
            ‡ # Replace numbers with those letters.

在线尝试!

用适当的字符替换位图的各个部分,剩下的5则用于以后替换the子手的各个部分:

  +---+
  |   |
  5   |
 555  |
 5 5  |
      |
=======

吊死的人:

接下来,我们通过抓住第二个输入而不是第一个输入中的字母来计算用户猜错了多少次:

05AB1E,6个字节

²¹SK   # Get wrong guesses.
    ©Ù # Store them, and get unique wrong letters.

在线尝试!


最后,我们使用辅助位图替换上吊的人,用换行符分隔并准备最终打印:

05AB1E,26个字节

g                           # Get the number of "messups".                       
 "O/|\/\"s£                 # Only that many chars of the hanged "bitmap".
           v5y.;}           # Replace 5's with "bitmap".
                 7ô»        # Split into rows.
                    „==«5ð: # Remove additional 5's.

在线尝试!

这样就产生了前几首,剩下的仅剩下的几首以diff格式输出了两个单词。


以下文字:

打印第一个单词而不会丢失猜测:

05AB1E,15个字节

¹D²SK          # Word without the missing guesses.
     Dg'_ׇ    # Replace missing guesses with "_".
           Sðý # Join by spaces.

在线尝试!


05AB1E,5个字节

®     # Print stored missing guesses.
 Sðý  # Separated by spaces.
    » # Print everything in stack with newlines.

在线尝试!

打印我们存储在寄存器中的先前计算的未命中猜测。


1
我真的很喜欢位图的想法(甚至尝试在自己的答案中实现它),但是您的答案是将左臂(/)放在主体(|)之前。两个错误的字母应导致头部和身体部位显示出来。在线尝试
贾斯汀·马里纳

1

果冻,86字节

3ȷ6Dẋ6Ḍ+“Ȧṇ⁹c’
œ-Lḣ@“Ñæçðøþ‘⁵*$€×“µI,’D¤¤S+¢Dị“+-|/\O ”Us7Y,”=x9¤Y;⁷,œ-ðjɓi@€ị³;”_¤K;⁷

在线尝试!

哇...这很有趣。我从来没有使用过太多¤字符。

怎么运行的

3ȷ6Dẋ6Ḍ+“Ȧṇ⁹c’ (1) the literal 300000030000003000000300000030003001222100
3ȷ6              - literal 3*10^6 = 3000000
   D             - digits
    ẋ6           - repeat six times
      Ḍ          - return to integer: 300000030000003000000300000030000003000000
       +         - add
        “Ȧṇ⁹c’   - literal 2998222100

œ-Lḣ@“Ñæçðøþ‘⁵*$€×“µI,’D¤¤S+¢Dị“+-|/\O ”Us7Y,”=x9¤Y,œ-;⁷ð,ɓi@€ị³;”_¤K;⁷
œ-Lḣ@“Ñæçðøþ‘⁵*$€×“µI,’D¤¤S - representation of the body parts
œ-L                           - wrong letters length
   ḣ@                         - get that many elements from the start of
                        ¤¤    - the literal:
     “Ñæçðøþ‘                   - [16, 22, 23, 24, 29, 31]
             ⁵*$€               - 10 to the power of each of them
                 ×              - multiplies by
                  “µI,’D        - the list [6, 4, 3, 5, 4, 5]
                          S   - sum
+¢Dị“+-|/\O ”Us7Y,”=x9¤;⁷  - complete the man
+                           - add
 ¢                          - the literal 3000000...1222100 calculated by link 1
  D                         - digits
   ị“+-|/\O ”               - index into the string “+-|/\O ”
             Us7Y           - reverse, split into lines of 7, join by linefeeds
                 ,          - append
                  ”=x9¤;⁷     - the string “=========”
                       ;⁷    - add a newline
,œ-                 - append missed letters:
,                      - append
 œ-                    - set difference
ð,ɓi@€ị³;”_¤K;⁷     - append the blanks        
ð,ɓ                   - append
   i@€ị³;”_¤            - each letter if it is included in guesses, _ otherwise
            K         - join by spaces  
             ;⁷       - add a newline

这把人引错了顺序。躯干应该在头部之后,在左臂之前。
毛茸茸的

1

C#,305个 296字节

using System.Linq;w=>g=>{var r=string.Concat(g.Where(c=>!w.Contains(c)));var n=r.Length;return$@"  +---+
  |   |
  {(n>0?"O":" ")}   |
 {(n>2?"/":" ")+(n>1?"|":" ")+(n>3?"\\":" ")}  |
 {(n>4?"/":" ")} {(n>5?"\\":" ")}  |
      |
=========
{string.Join(" ",w.Select(c=>g.Contains(c)?c:'_'))}
"+r;}

感谢@raznagul,节省了9个字节。

在线尝试!

完整/格式化版本:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<string, Func<string, string>> f = w=>g=>
        {
            var r = string.Concat(g.Select(c => !w.Contains(c) ? c + "" : ""));
            var n = r.Length;

            return $@"  +---+
  |   |
  {(n > 0 ? "O" : " ")}   |
 {(n > 2 ? "/" : " ") + (n > 1 ? "|" : " ") + (n > 3 ? "\\" : " ")}  |
 {(n > 4 ? "/" : " ")} {(n > 5 ? "\\" : " ")}  |
      |
=========
{string.Join(" ", w.Select(c => g.Contains(c) ? c : '_'))}
" + r;
        };

        Console.WriteLine(f("BOAT")("ATG") + "\n");
        Console.WriteLine(f("ZEPPELIN")("") + "\n");
        Console.WriteLine(f("ZEPPELIN")("EATOLINSHR") + "\n");
        Console.WriteLine(f("RHYTHM")("ABCDE") + "\n");
        Console.WriteLine(f("BOAT")("ATOB") + "\n");

        Console.ReadLine();
    }
}

这也适用于314个字节(可能还会更短):

using System.Linq;w=>g=>{var r=string.Concat(g.Select(c=>!w.Contains(c)?c+"":""));var s=$@"  +---+
  |   |
  0   |
 213  |
 4 5  |
      |
=========
{string.Join(" ",w.Select(c=>g.Contains(c)?c:'_'))}
"+r;for(int i=0;i<6;++i)s=s.Replace(i+"",i<r.Length?i<1?"O":i<2?"|":i<3?"/":i<4?"\\":i<5?"/":"\\":" ");return s;}

您可以替换g.Select(c=>!w.Contains(c)?c+"":"")g.Where(c=>!w.Contains(c))
raznagul

@raznagul谢谢!
TheLethalCoder

1

的JavaScript(ES6),203 196 187 186 185 184 180 177 176字节

以currying语法将输入作为2个单独字符的数组。

a=>g=>`  +---+
  |   |
  1   |
 324  |
 5 6  |
      |
=========
${a.map(x=>g[s="includes"](x)?x:"_")}
`.replace(/\d|,/g,m=>" O|/\\/\\"[!!w[~-m]*~~m],w=g.filter(x=>!a[s](x)))+w

尝试播放

o.innerText=(f=
a=>g=>`  +---+
  |   |
  1   |
 324  |
 5 6  |
      |
=========
${a.map(x=>g[s="includes"](x)?x:"_")}
`.replace(/\d|,/g,m=>" O|/\\/\\"[!!w[~-m]*~~m],w=g.filter(x=>!a[s](x)))+w)([...i.value="ZEPPELIN"])([...j.value=""])
oninput=_=>o.innerText=f([...i.value.toUpperCase()])([...j.value.toUpperCase()])
label,input{font-family:sans-serif;font-size:14px;height:20px;line-height:20px;vertical-align:middle}input{margin:0 5px 0 0;width:100px;}
<label for=i>Word: </label><input id=i type=password><label for=j>Guesses: </label><input id=j><pre id=o>


中间的“身体”这块应该来第二和左臂第三,让您的字符串的数字部分应该是13245 6(见最后测试案例)。
贾斯汀·马里纳

糟糕,不知道我是怎么做到的。感谢您指出,@JustinMariner
Shaggy

0

Scala392389字节

这可能仍然是可打高尔夫球的。

这是在一个函数中,该函数以st作为参数,带有s要猜测的单词和t包含已经尝试过的字母的字符串。

var f=s.map(x=>if(t contains x)x else"_") mkString " "
var o="""  +---+
  |   |
  0   |
 213  |
 4 5  |
      |
=========
"""
var c=0
var g=t.filter(x=>if(s contains x){false}else{c match{case 0=>o=o.replace("0","o")
case 1=>o=o.replace("1","|")
case y if y==2|y==5=>o=o.replace(y+"","\\")
case y if y==3|y==4=>o=o.replace(y+"","/")
case _=>()}
c+=1
true})
o.replaceAll("\\d"," ")+f+"\n"+g

编辑:
-1字节:t.contains(x) -> t contains x
-1字节:s.contains(x) -> s contains x
-1字节:.mkString(" ") -> mkString " "

在线尝试!


0

PHP 7,246字节

for($t="  +---+
  |   |
  1   |
 324  |
 5 6  |
      |
=========
";$c=($w=$argv[1])[$i++];)$t.=strstr($g=$argv[2],$c)?"$c ":"_ ";for($t.="
";$c=$g[$k++];)strstr($w,$c)?:$t.=$c.!++$n." ";for(;$p++<6;)$t=strtr($t,$p," O|/\/\\"[$p>$n?0:$p]);echo$t;

从命令行参数获取输入。运行-nr在线尝试

for($t="  +---+\n  |   |\n  1   |\n 324  |\n 5 6  |\n      |\n=========\n";
    $c=($w=$argv[1])[$i++]; # 1. loop $c through word
)
    $t.=strstr($g=$argv[2],$c)  # if guessed,
        ?"$c ":"_ ";                # then append letter, else append underscore
for($t.="\n";$c=$g[$k++];)  # 2. loop through guesses
    strstr($w,$c)?:             # if not in word
        $t.=$c.!++$n." ";           # add to output, increment $n
for(;$p++<6;)               # 3. loop through possible false guesses
    $t=strtr($t,$p," O|/\/\\"[  # replace digit:
        $p>$n                   # if above no. of wrong guesses
            ?0:$p                   # then with space, else with hangman character
    ]);
echo$t;                     # 4. print
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.