代码在Windows和Android上的执行方式不同
我正在编写一个名为Jotto的简单游戏。一个玩家试图猜测一个秘密的五个字母的单词;每个字母都是独一无二的。在每个 5 个字母的猜词之后,您会被告知猜中的多少个字母也在秘密词中。这是我第一次尝试使用 Delphi 进行跨平台开发。我已经在 Delphi 中开发了 Windows 应用程序,并使用 Flutter 为 Android 开发了一些应用程序。
所有代码在 Windows(32 位)上按预期执行,但在 Android(64 位,SDK 25.2.5)上不执行。没有出现异常,但计算出的每回合正确猜测的数量是不正确和不可预测的(即,total下面的计算结果是关闭的)。通过调试器运行代码显示局部变量有时也不正确。
以下是相关函数:
function TJotto.OccurrencesOfChar(const aWord, aChar: string): integer;
var
i: integer;
begin
result := 0;
for i := 1 to Length(aWord) do
if aWord[i] = aChar then
inc(result);
end;
和
function TJotto.MakeGuess(aGuessWord: string): string;
var
i: integer;
total: integer;
wordToDisplay: string;
begin
total := 0; // number of matches
wordToDisplay := aGuessWord;
// save copy of guess before deleting duplicate letters
// because guess will be displayed
// did user solve puzzle?
if aGuessWord = FSecretWord then
Exit('You did it! The word was ' + aGuessWord);
// make sure all letters in aGuessWord are different
// otherwise a guess like 'vexed' will say an E is present in FSecretWord twice
for i := 5 downto 1 do
if OccurrencesOfChar(aGuessWord, aGuessWord[i]) > 1 then
Delete(aGuessWord, i, 1);
// go through each letter in aGuessWord to see if it's in FSecretWord
// keep a running total number of matches
for i := 1 to Length(aGuessWord) do
total := total + OccurrencesOfChar(FSecretWord, aGuessWord[i]);
result := wordToDisplay + #9 + total.ToString;
end;
回答
注意:在 Delphi 10.4 之前,移动编译器默认使用基于 0 的字符串索引。请参阅从零开始的字符串。
使用Low()和High()内部函数来迭代字符串。
您看到的不规则是因为在字符串边界之外进行索引。调试时,使用溢出和范围检查来检测此类错误。
您的代码将如下所示:
function TJotto.OccurrencesOfChar(const aWord, aChar: string): integer;
var
i: integer;
begin
result := 0;
for i := Low(aWord) to High(aWord) do
if aWord[i] = aChar then
inc(result);
end;
和
function TJotto.MakeGuess(aGuessWord: string): string;
var
i: integer;
total: integer;
wordToDisplay: string;
begin
total := 0; // number of matches
wordToDisplay := aGuessWord;
// save copy of guess before deleting duplicate letters
// because guess will be displayed
// did user solve puzzle?
if aGuessWord = FSecretWord then
Exit('You did it! The word was ' + aGuessWord);
// make sure all letters in aGuessWord are different
// otherwise a guess like 'vexed' will say an E is present in FSecretWord twice
for i := High(aGuessWord) downto Low(aGuessWord) do
if OccurrencesOfChar(aGuessWord, aGuessWord[i]) > 1 then
Delete(aGuessWord, i+1-Low(aGuessWord), 1); // Delete uses one-based array indexing even in platforms where the strings are zero-based.
// go through each letter in aGuessWord to see if it's in FSecretWord
// keep a running total number of matches
for i := Low(aGuessWord) to High(aGuessWord) do
total := total + OccurrencesOfChar(FSecretWord, aGuessWord[i]);
result := wordToDisplay + #9 + total.ToString;
end;