in reply to Looking for pointers or optimizations.

Looking at your 3:11 PM version, I'd make a few more changes:

  1. You split(//,$word) twice, perhaps every time through the while loop. Move them up, prior to looping.
  2. You have @words, $words, $word, and %word. Below, I ditch the temporary $words, and introduce @chars and %chars.
... #my $words = @words; # just use (scalar @words) chomp(my $word = lc($words[int(rand(scalar @words))])); my @chars = split//,$word; my %chars = map { $_ => 1 } @chars; ... while ($turns > 0) { ... foreach my $char (@chars) { # split not needed ... else { #my %word = map{$_=>1}split(//,$word); # not needed if (exists($chars{$guess})) { # changed %word to %chars ...

Minor update - tweaked my 'foreach' comment