Perl猜谜游戏 - 将数据保存到哈希

时间:2017-05-23 21:41:34

标签: perl hash key

我在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;
            }
    }

1 个答案:

答案 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中没有内置值truefalse。因此,我怀疑你只是为了节目拍了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;

就足够了。