Alternatively, don’t let the user send you that data at all. Let them give you a number, 1-8, that defines their next move (or move attempt).
You already store the current location, so if they are at X…

5 1 7
2 X 4
6 3 8

Their new location is given by:

$output = array('x'=> intval(substr($dbresult['curpos'],1))-1, 'y' => ord(substr($dbresult['curpos'],0,1))-65);
$input = $input - 1; //Because we like working in zero-index terms...
if($input & 4) {
//They went in a diagonal.
$output['x'] += (($input & 2) - 0.5)/abs(($input & 2) - 0.5);
$output['y'] += (($input & 1) - 0.5)/abs(($input & 1) - 0.5);
} else {
//They went in an cardinal.
$tomod = ($input & 1) ? "x" : "y";
$output[$tomod] += (($input & 2) - 0.5)/abs(($input & 2) - 0.5);
}
$output = chr(min(max($output['y'],0),5)+65).(min(max($output['x'],0),5)+1);

(and you always thought your maths teacher was lying when they said you would be using it in the future…)

I dont have time or frankly energy to type out a solution. I’d start looking into things like, oh idk, index, preventDefault, setAttribute. If it’s what the customer sees or interacts with, it’s front end.

I mean sure, knock yourself out with a backend solution, but this is 100% something your front end should be responsible for. You can tell me WRONG all you want, but again, according to the specifics,…