Como todo jogo de tabuleiro, Batalha Naval pôde ser organizado matricialmente. Na implementação, uma matriz quadrada (16x16) de 256 células, denominada ShipsTable, indica onde estão as embarcações. Cada célula da matriz guarda na realidade um índice para a estrutura da embarcação correspondente. É desnecessário guardar uma estrutura para cada célula, pois uma mesma embarcação pode ocupar várias células.
Uma outra matriz, de nome FoundTable e de mesmo tamanho da ShipsTable indica se os tiros do usuário foram ou não sucedidos. Inicialmente, a matriz é preenchida com o valor TB_EMPTY. Quando o usuário erra um tiro, à célula correspondente da matriz é atribuído o valor TB_MISSED, indicando o insucesso. Similarmente, quando o usuário acerto um tiro, à célula é atribuído o valor TB_FOUND, indicando que o usuário encontrou uma célula ocupada. Quando todas as células de uma mesma embaracação são encontradas, a elas é atribuído o valor TB_DESTROYED, indicando que a embarcação foi destruída.
A estrutura utilizada para as embarcações é a seguinte:
typedef struct { const Model_t *pModel; int PositionX; int PositionY; Direction_t Direction; int Counter; } Ship_t;
pMode é um ponteiro para a estrutura de modelo apresentada na seção 3. PositionX e PositionY indicam a posição da primeira célula da embarcação no tabuleiro e Direction, para que direção ela aponta. Por último, Counter é um contador de tiros recebidos. O contador inicialmente guarda o valor do número de células ocupadas pela embarcação. Cada vez que ela atingida, o contador é decrementado de 1. A embarcação é dita destruída quando o contador chega a zero.
A exposição da embarcação é feita com base nos quatro primeiros campos da estrutura. Inicialmente, uma translacação é feita até a célula indicada pela posição (PositionX, PositionY). Em seguida, uma rotação é feita com base na direção Direction. Por último, o modelo dado pelo ponteiro pModel é utilizado para a renderização da embarcação.
O fluxo do jogo é dado pela seguinte seqüência. Inicialmente, nehuma embarcação é visível. À medida que o usuário atira, a matriz FoundTable é modificada baseada na matriz ShipsTable. Por exemplo, quando o usuário atira na posição (x, y), o jogo verifica na matriz ShipsTable, se aquela célula está ocupada. Se não, a célula (x, y) de FoundTable é marcada como TB_MISSED. Se sim, a célula (x, y) é marcada como TB_FOUND. Além disso, o contador da embarcação dada em ShipsTable(x, y) é decrementado. Quando o contador chega a zero, as células correspondetes de FoundTable são marcadas com TB_DESTROYED e a embarcação passa a ser exibida.
O jogo é dado por encerrado quando o usuário destrói todas as embarcações presentes no tabuleiro, ou seja, quando todas elas estão sendo exibidas. A relação do número de acertos sobre o número de tiros dá o percentual de desempenho do usuário.