R, 288 281 267 257 247 bytes
thanks to @cole for -1 byte, reordering the ?
to collapse the 2 into rep(2,10)
-10 bytes realizing that row(m) == t(col(m))
-10 bytes thanks to user2390246 for reconfiguring the weights
function(n){m=matrix(sample(strsplit("EOAINRTLSUDGBCMPFHVW?YKJXQZ","")[[1]],n^2,T,rep(c(12,8,9,6,4:1),c(1,1:4,1,10,5))),n,n)
K=(n+1)/2
if(n>8){L=col(m)
m[i]=chartr("A-Z?","a-z!",m[i<-!((x=(L-K)%%3)|t(x)|L%in%c(1,n)|t(L)%in%c(1,n))])}
m[K,K]=" "
m}
Returns a matrix. Fairly simple implementation; samples n^2 values with the proper distribution, stores as an nxn
matrix.
K
is the index of the center.
computes the indices of the matrix where the row and column distances from the center are both multiples of 3 and not on the edge (i.e., not 1
or n
), lowercases those, replaces ?
with !
, replaces the center with " "
, and returns the matrix.
There's actually an R package, ScrabbleScore
that has Scrabble letter frequencies. However, due to the way it's stored, it's only a 13 byte improvement, so it's not worth it. It is, however, probably helpful for Beatnik golfing.