我在Pascal
上做作业。我几乎把所有的事情都做完了,只是试着比较两个字符串来检查游戏是否完成。但是,当我在guess
过程中比较它们时,即使encryption
字符串已经与theWord
字符串相同,它也总是错误的。我不太明白Pascal是如何处理字符串的。然后,我尝试在输出true
的main
中对它们进行比较。我真的很困惑。我尝试了SameStr
、CompareText
、=
,结果都是一样的。
代码:
program hangman;
Uses sysutils;
const
times = 6;
var
theWordSize,i : integer;
theWord,encryption : string;
function encrypt (): string;
var
list : string;
begin
for i := 1 to theWordSize do
list[i] := '*';
encrypt := list;
end;
procedure reveal(letter: char);
begin
for i := 1 to theWordSize do
if (theWord[i] = letter) then
encryption[i] := theWord[i];
end;
procedure guess();
var
letter : char;
j : integer;
begin
writeln('hello');
j := times;
while (j > 0) do
begin
writeln('Guess a letter( ':16, j:1, ' times left ): ':15);
readln(letter);
if pos(letter,theWord)<>0 then // guess correctly
begin
reveal(letter);
writeln('Correct! Word: ':15, encryption:7);
writeln(SameText(theWord,encryption));
if SameText(theWord,encryption) then
begin
writeln('You win! The correct word: ':28, theWord:7);
exit
end;
inc(j)
end
else if (j > 1) then // guess wrong
writeln('Wrong! Word: ':15, encryption:7)
else
writeln('You lose! The man is dead. Correct Word: ':43, theWord:7);
dec(j)
end
end;
{* Main program: *}
begin
theWord := 'mystery';
theWordSize := byte(theWord[0]);
//writeln(theWord[i]=='m');
writeln('Weclome to Hangman game:');
encryption := encrypt();
writeln('Mystery Word: ':14, encryption:theWordSize);
guess();
for i := 0 to theWordSize do
encryption[i] := theWord[i];
writeln(SameText(theWord,encryption));
end.
部分运行结果:
Guess a letter( 6 times left ):
e
Correct! Word: m*ste**
FALSE
Guess a letter( 6 times left ):
r
Correct! Word: m*ster*
FALSE
Guess a letter( 6 times left ):
y
Correct! Word: mystery
FALSE
Guess a letter( 6 times left ):
a
Wrong! Word: mystery
Guess a letter( 5 times left ):
a
Wrong! Word: mystery
Guess a letter( 4 times left ):
a
Wrong! Word: mystery
Guess a letter( 3 times left ):
a
Wrong! Word: mystery
Guess a letter( 2 times left ):
a
Wrong! Word: mystery
Guess a letter( 1 times left ):
a
You lose! The man is dead. Correct Word: mystery
TRUE
SO有一种荣誉准则,即在涉及家庭作业的地方,我们不告诉你答案就行了。因此,我将向您展示使用拉撒路的方法调试器来自己确定问题的原因。问题是,像fpc这样的编译器如果不能正确地进行字符串比较,就不会存活很长时间,所以像SameText这样的函数失败的原因一定是因为你正在比较的字符串实际上不相等。问题是"为什么不呢?"并且找出调试的全部内容。
如果你还没有安装Lazarus,现在就安装并在其中打开你的项目。如果,第一次编译Hangman时,你会得到错误
Hangman.lpr(64,56(错误:无法访问ansi/wide或longstring的元素零,请使用(set(length代替
这是因为Lazarus假设您使用的是所谓的"巨大字符串"可以达到2Gb大小,而您显然打算使用传统Pascal"ShortStrings"是最多255个字符的数组,前面有一个长度字节。
要强制Lazarus使用ShortStrings,请添加
$mode objfpc}{$H-}
就在"程序Hangman"下面。同时,当你在它,改变
theWordSize := byte(theWord[0]);
至
theWordSize := Length(theWord);
因为无论HugeStrings与ShortStrings和make没有关于字符串内部结构的假设。
我要采取的下一步是更改将theWord
设置为的行
theWord := 'm'; //'mystery';
以便使调试期间的打字量最小化。然后,放置一个调试器线上的断点
if SameText(theWord,encryption) then
通过在檐沟左侧边缘附近单击(具有源行号的区域在其中(。
编译并运行程序,一旦控制台窗口出现,键入
m返回
完成此操作后,调试器将在断点处停止。按F8单步调试程序,您会发现它进入
inc(J);
很明显SameText
失败了,这就是你带着q来的地方。没有意义在继续应用程序的当前运行时,请按Ctrl-F7终止它并重置调试器。
再次运行应用程序,仔细查看执行行的结果
writeln('Mystery Word: ':14, encryption:theWordSize);
你会注意到它没有显示任何值encryption
。这是出了什么问题的重要线索。我是你键入的值没有错,因此encryption
不能具有相同的值。唯一剩下要做的就是找出它到底有什么价值。请注意如果您尝试使用F7评估encryption
,则它显示为空白,而不是你所期望的星号。
对于下一个位,在线上放置一个断点
for i := 1 to theWordSize do
在encrypt
函数中,并将代码窗口拖动到屏幕右侧。然后,按要打开Watches
窗口,如有必要,将其拖到通过移动代码窗口释放的空间中,并在其中输入以下表达式
list[0]
和
list[1]
这是为了让您能够观察列表的长度字节和第一个字符中的值。运行应用程序直到encrypte
断点,然后绕过CCD_ 18循环。你会发现的价值
list[0]
即使在list[1]
的值设置为"m"之后,也不会发生更改。
所以,encrypt
返回的是一个空字符串QED,我相信你会意识到如何解决。如果这件事很累人,很抱歉,但至少应该这样让你知道如何系统地调试你遇到的下一个问题。