我在Perl中编写一个简单的猜谜游戏时遇到了问题。
游戏应该选择50-100范围内的数字。
游戏中有2个人。玩家和计算机轮流使用这些数字直到其中一个猜测正确。
猜猜每个玩家应该保存为哈希,其中key是猜测数字,值是用户输入的数字。
例如
用户输入
56,53,67和67是匹配。
所以它假设看起来像这样:
my %guesses = (1 => 56, 2 => 53, 3 => 67 )
我刚开始学习Perl而我无法理解哈希。你能帮我解决一下如何在代码中实现这个部分吗?
(我认为循环中也存在错误,导致它无法正常工作?)
这是我的代码:
use warnings;
use strict;
sub loot{
$lower_limit = 50;
$upper_limit = 100;
my $random_number = int(rand($upper_limit-$lower_limit)) + $lower_limit;
return $random_number;
}
my $number = loot;
my $counter = 0;
print $number;
print "\n";
my $state = false;
while( $state == true ){
++$counter;
print "Pick number: \n";
my $variable = <STDIN>;
chomp($variable);
if($variable == $number){
print "You have won";
print "\n";
$state = true;
printf "You made : $counter guesses.";
exit;
}
else{
print "--------- \n";
my $a = loot;
print "Computer guess it: $a ";
print "\n";
if($a == $number){
$state = true;
print "Computer won";
print "\n";
printf "Computer made : $counter guesses.";
exit;
}
}
答案 0 :(得分:2)
首先,一些反馈,因为你刚刚开始学习Perl。
1)为事物提供有意义的名字。选择随机数的子程序应该是loot
,而不是rand_int_between
。下限和上限应该是函数的参数,而不是函数体中的硬编码。
sub rand_int_between {
my ($lo, $hi) = @_;
return int(rand($hi - $lo) + $lo);
}
2)不要调用状态变量$state
。相反,使用类似$keep_guessing
的内容,以便更自然地阅读条件。代码的清晰度反映了您思路的清晰度。
3)Perl中没有内置值true
和false
。因此,我怀疑你只是为了节目拍了use strict
,而你的真实代码却没有。不要这样做。它可以帮到你。
4)不要使用$variable
之类的变量名称。而是使用像$picked
这样有意义的东西。
5)如果要映射严格增加的整数序列而没有间隙到数据,则使用的正确结构是数组而不是散列。
6)哈希没有固有的顺序。这意味着,如果你想列出玩家按顺序进行的所有动作,你将不得不浪费周期排序这些键,而如果你只是将动作保存在一个数组中,它自然会按播放顺序排序。
6)无论如何,脚本中没有哈希值。你根本不保存动作。您也没有指定哈希服务的目的。所以,人们必须想象你可能想用它做些什么。
考虑到这些要点,这就是人们写这样一个游戏的方式:
#!/usr/bin/env perl
use strict;
use warnings;
use constant DEBUG => !!$ENV{DEBUG_GUESSING_GAME};
play( 50, 100 );
sub play {
my ($lo, $hi) = @_;
my $secret = rand_int_between($lo, $hi + 1);
DEBUG
and warn "Secret number is $secret\n";
my %human_moves;
my $turn;
while ( 1 ) {
++ $turn;
my $picked = human_picks($lo, $hi);
$human_moves{ $turn } = $picked;
if ( $secret == $picked ) {
printf "You won after %d guesses\n", $turn;
last;
}
$picked = computer_picks($lo, $hi);
if ( $secret == $picked ) {
printf "The computer won after %d turns\n", $turn;
last;
}
}
print "Your guesses were:\n";
print "\t$human_moves{$_}\n" for sort { $a <=> $b } keys %human_moves;
return;
}
sub computer_picks {
return rand_int_between(@_);
}
sub human_picks {
my ($lo, $hi) = @_;
printf "Pick a number between %d and %d\n", $lo, $hi;
my $input = <STDIN>;
trim( $input );
return $input;
}
sub trim {
$_[0] =~ s/^\s+//;
$_[0] =~ s/\s+\z//;
return;
}
sub rand_int_between {
my ($lo, $hi) = @_;
return int(rand($hi - $lo) + $lo);
}
该行
$human_moves{ $turn } = $picked;
将$turn
的当前值与人类玩家选择的数字相关联。
sort { $a <=> $b } keys %human_moves
按数字顺序对%human_moves
哈希的键进行排序,从最小到最大(参见perldoc -f sort
)。
因此,循环
print "\t$human_moves{$_}\n" for sort { $a <=> $b } keys %human_moves;
打印移动顺序中猜到的每个数字。
如果您已将动作保存在数组中,只需
print "\t$_\n" for @human_moves;
就足够了。