Last active
June 27, 2019 09:51
-
-
Save SkymanOne/e4a61f07a6bd4230033e831dc8f1ab4d to your computer and use it in GitHub Desktop.
Solution for Codewars 3 Kyu kata: https://www.codewars.com/kata/battleship-field-validator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace codewars10._06 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//set up the field as an array from the example test case | |
int[,] field = new int[10, 10] | |
{{1, 0, 0, 0, 0, 1, 1, 0, 0, 0}, | |
{1, 0, 1, 0, 0, 0, 0, 0, 1, 0}, | |
{1, 0, 1, 0, 1, 1, 1, 0, 1, 0}, | |
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | |
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, | |
{0, 0, 0, 0, 1, 1, 1, 0, 0, 0}, | |
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, | |
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, | |
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, | |
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; | |
Console.WriteLine(ValidateBattlefield(field).ToString()); | |
} | |
public static bool ValidateBattlefield(int[,] field) | |
{ | |
//count number of ships identified | |
int n_of_battleships = 0; | |
int n_of_cruisers = 0; | |
int n_of_destroyers = 0; | |
int n_of_submarines = 0; | |
//go through each cell in the field | |
for (int x = 0; x < 10; x++) | |
{ | |
for (int y = 0; y < 10; y++) | |
{ | |
if (Is1There(ref field, y, x)) | |
{ | |
//if the cell conatains 1, we run method "FindTheShip" to identify the type of a ship | |
switch (FindTheShip(ref field, y, x)) | |
{ | |
case 4: | |
n_of_battleships++; | |
break; | |
case 3: | |
n_of_cruisers++; | |
break; | |
case 2: | |
n_of_destroyers++; | |
break; | |
case 1: | |
n_of_submarines++; | |
break; | |
default: | |
return false; | |
} | |
} | |
} | |
} | |
// compare the number of ships of each type with the expected value | |
if (n_of_battleships != 1 || n_of_cruisers != 2 || n_of_destroyers != 3 || n_of_submarines != 4) | |
return false; | |
return true; | |
} | |
public static int FindTheShip(ref int[,] field, int y, int x) | |
{ | |
int n_of_cells = 1; | |
//if there is a cell that stays close to the current cell, we return | |
if (AreCellsAroundShip(ref field, y, x)) | |
return -1; | |
//we find the cell which is next to the current cell and go in the direction of this cell | |
//then return to original point where we go in the opposite direction if the original point is the centre of the ship | |
if (y != 9 && Is1There(ref field, y + 1, x)) | |
{ | |
for (int i = y + 1; Is1There(ref field, i, x); i++, n_of_cells++) | |
{ | |
//we still check cells near to the cell to find whether ships are close to each other | |
if (AreCellsAroundShip(ref field, i, x)) | |
return -1; | |
//we mark counted cells by replacing them by 2 to avoid counting the same ship multiple number of times | |
field[i, x] = 2; | |
} | |
} | |
if (y != 0 && Is1There(ref field, y - 1, x)) | |
{ | |
for (int i = y - 1; Is1There(ref field, i, x); i--, n_of_cells++) | |
{ | |
if (AreCellsAroundShip(ref field, i, x)) | |
return -1; | |
field[i, x] = 2; | |
} | |
} | |
if (x != 9 && Is1There(ref field, y, x + 1)) | |
{ | |
for (int i = x + 1; Is1There(ref field, y, i); i++, n_of_cells++) | |
{ | |
if (AreCellsAroundShip(ref field, y, i)) | |
return -1; | |
field[y, i] = 2; | |
} | |
} | |
if (x != 0 && Is1There(ref field, y, x - 1)) | |
{ | |
for (int i = x - 1; Is1There(ref field, y, i); i--, n_of_cells++) | |
{ | |
if (AreCellsAroundShip(ref field, y, i)) | |
return -1; | |
field[y, i] = 2; | |
} | |
} | |
switch (n_of_cells) | |
{ | |
case 4: | |
return 4; | |
case 3: | |
return 3; | |
case 2: | |
return 2; | |
case 1: | |
return 1; | |
default: | |
return -1; | |
} | |
} | |
public static bool Is1There(ref int[,] field, int y, int x) => field[y, x] == 1 ? true : false; | |
//check cells that are near the current cell, but not directly close to it, otherwise it is a ship | |
public static bool AreCellsAroundShip(ref int[,] field, int y, int x) | |
{ | |
if (x != 0 && y != 0 && Is1There(ref field, y - 1, x - 1)) | |
return true; | |
if (x != 9 && y != 0 && Is1There(ref field, y - 1, x + 1)) | |
return true; | |
if (x != 9 && y != 9 && Is1There(ref field, y + 1, x + 1)) | |
return true; | |
if (x != 0 && y != 9 && Is1There(ref field, y + 1, x - 1)) | |
return true; | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment