# [R], <s>288</s> <s>281</s> <s>267</s> 257 bytes

<!-- language-all: lang-r -->

_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))`_

    function(n){m=matrix(sample(strsplit("EAIONRTLSUDGBCMPFHVW?YKJXQZ","")[[1]],n^2,T,c(12,9,9,8,6,6,6,4,4,4,4,3,rep(2,10),rep(1,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}

[Try it online!][TIO-j7htvwnq]

[R]: https://www.r-project.org/
[TIO-j7htvwnq]: https://tio.run/##RU9rS8NAEPyeX9EeBHZxg16q0kLPUp/VxHd9NUQIIcGD3jVcTgy2/e3xqC/my@wMzM6YtuwMg7Z817mVCw0al0qozBrZQJ2pal5AbU1dzaUFdjI@v766m8b3D8dnh0eXN6eTx6fRS3TxfDtjxBgmCU9T0q8hTSkHHtLAoU/7G@z@oEemqCAkvoMbxmkPEUmTRi8SoLc4boeeLEEf9HEZi3wxB4WeSmQq8rfMWANsHMxG7mMWfHYZOWcYdAEaAXEQoe/3cGWhwVXsS@27Hi7ZCTH@n5ji2iVGFKWCdZin1u2HkbaAEgbolrjadVEJN8n71fm3wf@c9gs "R – Try It Online"

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.