我只有一个字。起初,只有字母,而不是字母。因此,例如,单词“ town”将显示为“ ????”。 然后用户猜到字母,如果他钉了,它从变为?到实际的字母。 例如,如果他猜到t,则看起来像是“ t ???”。
问题是,我不知道如何遍历字符串并将其划分为字符。而且,如果我以某种方式执行此操作,则无法在新字符串中对其进行更改。
应该看起来像这样。
word do: [ :c |
c = guessedChar
ifTrue[mask := mask, guessedChar]
ifFalse[mask := mask, '?']
].
mask
初始化为nil,因为word
的长度可以更改并且word
为String
。
guessedChar
连接到inputField,但是一次仅包含一个字符。
会不会更好,对每个猜中的字符都做一次还是保留所有猜中的字符的集合并每次运行一次?
答案 0 :(得分:2)
String
是Collection
个对象中的Character
个。因此,您也可以使用适用于其他集合的相同方法(例如#select:
,#collect:
或#reject:
)
guessedCharacters := 'ts'.
mask := word collect:[:each | (guessedCharacters includes: each)
ifTrue:[each]
ifFalse:[$?]].
请注意,'t'
是带有String
t的Character
。可以将Character
前缀写为$
作为文字字符$t
。
由于String
是SequenceableCollection
的子类,因此可以通过,
连接两个字符串。但是,您无法连接String
和Character
。
您可以使用#copyWith:
将Character
附加到String
。结果是一个新的String
,它不会修改现有实例。
答案 1 :(得分:1)
您可以使用
word doWithIndex: [:c :i | c = guess ifTrue: [mask at: i put: c]]
等效于:
i := 1.
word do: [:c |
c = guess ifTrue: [mask at: i put: c].
i := i + 1]
除了不必初始化和递增i
(这会更容易出错,也更冗长)
附录
鉴于String
的实例不能增长或改变其大小,这是不可变的,我假设可能发生变化的是变量word
。在这种情况下,您应该相应地初始化mask
,以便两个字符串始终保持相同的长度。像这样:
word: aString
word := aString.
mask := word copy atAllPut: $?
如果您还想保留已经猜到的字符:
word: aString
| guessed |
word := aString.
guessed := mask reject: [:c | c = $?].
mask := word copy atAllPut: $?.
guessed do: [:c | self try: c].
#try:
是我们以前使用的方法
try: aCharacter
word doWithIndex: [:c :i | c = aCharacter ifTrue: [mask at: i put: c]]
((如果需要,您可能想要uppercase
东西)
答案 2 :(得分:0)
c:set...