Determine a string's Scrabble score and validity
Perl 5 228 205 186 184 178 177 153 150 149 142 137 135

Run with perl -E.

Golfed:


$_=&lt;&gt;;@a=@b=map-ord,'            0 0@0 H        ``'=~/./g;say s!.!($a[$q=64-ord$&amp;]+=8)&lt;8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&amp;&amp;$j&lt;3?$-:Invalid


This solution uses some non-printable characters, so a hexdump is provided below:

00000000: 245f 3d3c 3e3b 4061 3d40 623d 6d61 702d  $_=&lt;&gt;;@a=@b=map-
00000010: 6f72 642c 2703 0904 0909 2030 2030 030e  ord,'..... 0 0..
00000020: 4030 0e20 0704 4809 1809 601d 0e0e 6027  @0. ..H...`...`'
00000030: 3d7e 2f2e 2f67 3b73 6179 2073 212e 2128  =~/./g;say s!.!(
00000040: 2461 5b24 713d 3634 2d6f 7264 2426 5d2b  $a[$q=64-ord$&amp;]+
00000050: 3d38 293c 383f 242d 2b3d 312d 3239 2f24  =8)&lt;8?$-+=1-29/$
00000060: 625b 2471 5d3a 2b2b 246a 2167 657e 7e5b  b[$q]:++$j!ge~~[
00000070: 322e 2e31 355d 2626 246a 3c33 3f24 2d3a  2..15]&amp;&amp;$j&lt;3?$-:
00000080: 496e 7661 6c69 64                        Invalid


Alternatively, using Ctrl+Key:

$_=&lt;&gt;;@a=@b=map-ord,'^C^I^D^I^I 0 0^C^N@0^N ^G^DH^I^X^I`^]^N^N`'=~/./g;print s!.!($a[$q=64-ord$&amp;]+=8)&lt;8?$-+=1-29/$b[$q]:++$j!ge~~[2..15]&amp;&amp;$j&lt;3?$-:Invalid


Ungolfed+commented:

# Read in input
$_=&lt;&gt;;
# @a and @b: represents approximately 8x the number of tiles (when rounded up). The 
#   non-multiple-of-8 values distinguish tiles that are given equally, but are worth
#  different values
@b=@a=map-ord,"...."~=/./g;
# above is equivalent to
# @a=@b=(-03,-09,-04,-09,-09,-32,-48,-32,-48,-03,-14,-64,-48,-14,-32,-07,-04,-72,-09,-24,-09,-96,-29,-14,-14,-96);
say
    # for each character
    s!.!
        # $q: A-&gt;-1, B-&gt;-2, etc.
        # decrement number of $q tiles, add points if needed, otherwise
        #    increment j, which counts number of wilds used
        # truncate(1-29/b[q]): decimal values were chosen specifically
        #    for this to return the point value. b[q] is the number of tiles
        #    of the qth letter after a originally given.
        #  $- contains the score, is initially zero (if in a one line program, 
        #   as the golfed version is), and is always an integer
        ($a[$q=64-ord$&amp;]+=8)&lt;8 ? $- += 1 - 29/$b[$q] : ++$j
    # s returns length, check if between 2 and 15
    !ge ~~ [2..15]
    # make sure less than 3 negative tiles (aka wilds) 
    &amp;&amp; $j &lt; 3 ?
        # print score
        $-
    # or invalid
    : Invalid