I am creating a multiplayer Battleship game using an Apache/PHP server (yes, I know Node would be much better for this, but I'll get around to learning it later). Anyways, I am at the point in which both players are uploading their game boards to start the game. While my client side JavaScript would obviously properly compile and validate boards before sending them off to the server, that is still vulnerable to cheating, so the server must also double check. However, on the server, speed and efficiency is everything.
As of now, this is the process my server follows:
Server receives the board as a JSON encoded multidimensional array via an AJAX request.
$board = json_decode($_REQUEST["board"]);
Server validates the structure of the passed input.
$validate = array(gettype($board) == "array", count($board) == 10);
for($i = 0; $i < count($board); $i++) {
array_push($validate, count($board[$i]) == 10);
for($ii = 0; $ii < count($board[$i]); $ii++) {
array_push($validate, gettype($board[$i][$ii]) == "integer");
}
}
if(in_array(0, $validate)) throwError();
In the array, numbers zero through five represent blank, aircraft carrier, battleship, cruiser, submarine, and destroyer tiles respectively. I count the proper quantity of each.
$valueCount = array_count_values(array_merge($board[0], $board[1], $board[2], $board[3], $board[4], $board[5], $board[6], $board[7], $board[8], $board[9]));
$template = array("0"=>83,"1"=>5, "2"=>4, "3"=>3, "4"=>3, "5"=>2);
if($template != $valueCount) throwError();
I need to ensure that ship tiles are only vertical or horizontal lines.
$shipsValid = array(false, false, false, false, false);
$transpose = array_map(null, $board[0], $board[1], $board[2], $board[3], $board[4], $board[5], $board[6], $board[7], $board[8], $board[9]);
for($i = 0; $i < 9; $i++) {
$temp1 = array_count_values($board[$i]);
$temp2 = array_count_values($transpose[$i]);
if($temp1["1"] == 5 || $temp2["1"] == 5) shipsValid[0] = true;
if($temp1["2"] == 4 || $temp2["2"] == 4) shipsValid[1] = true;
if($temp1["3"] == 3 || $temp2["3"] == 3) shipsValid[2] = true;
if($temp1["4"] == 3 || $temp2["4"] == 3) shipsValid[3] = true;
if($temp1["5"] == 2 || $temp2["5"] == 2) shipsValid[4] = true;
}
if(in_array(0, $shipsValid)) throwError();
I need to ensure ships are continuous with no gaps.
??????????????????????????
With enough work, I could have completed step five, but it would have been grossly inefficient, looping through everything repeatedly. So, in conclusion, how can I make what I have designed more efficient, and how I complete the final step (5) to validating the uploaded board?
Example Board (Valid):
"[[0,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,0,0,2,0,0],
[0,0,0,0,0,0,0,2,0,0],
[0,0,0,0,0,0,0,2,0,0],
[0,3,3,3,0,0,0,2,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,5,0,0,0,4,4,4,0],
[0,0,5,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]]"
Example Board (Invalid, for many reasons):
"[[0,1,1,0,1,1,0,0,0,1],
[0,0,0,0,0,0,0,2,0,0],
[0,0,0,0,0,0,0,2,0,0],
[0,0,0,0,0,0,0,2,0,0],
[0,6,6,6,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,4,4,4,4,4],
[0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0]]"
See Question&Answers more detail:
os