Skip to content

Commit 5efbce3

Browse files
author
Thomas Schissler
committed
Initial version
1 parent 5855933 commit 5efbce3

File tree

14 files changed

+446
-2
lines changed

14 files changed

+446
-2
lines changed

.vscode/launch.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"request": "launch",
10+
"name": "Launch Program",
11+
"skipFiles": [
12+
"<node_internals>/**"
13+
],
14+
"program": "${workspaceFolder}\\index.js",
15+
"console": "externalTerminal"
16+
},
17+
{
18+
"name": "DebugCucumber",
19+
"type": "node",
20+
"request": "launch",
21+
"program": "${workspaceRoot}/node_modules/cucumber/bin/cucumber-js",
22+
"args": [
23+
"${workspaceRoot}/GameController_ATDD/*.feature",
24+
"--tags", "@debug"
25+
]
26+
}
27+
]
28+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const assert=require('assert').strict;
2+
const battleship=require("../battleship.js");
3+
const letters=require("../GameController/letters.js");
4+
const position=require("../GameController/position.js")
5+
6+
describe('parsePositionTests', function() {
7+
it('should return a valid position for valid input', function() {
8+
var expected = new position(letters.B, 3);
9+
var actual = battleship.ParsePosition("B3");
10+
assert.deepStrictEqual(actual, expected);
11+
});
12+
});

GameController/gameController.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
class GameController {
2+
static InitializeShips ()
3+
{
4+
var colors = require("cli-color");
5+
const Ship = require("./ship.js");
6+
var ships =
7+
[
8+
new Ship("Aircraft Carrier", 5, colors.CadetBlue ),
9+
new Ship("Battleship", 4, colors.Red ),
10+
new Ship("Submarine", 3, colors.Chartreuse ),
11+
new Ship("Destroyer", 3, colors.Yellow ),
12+
new Ship("Patrol Boat", 2, colors.Orange )
13+
];
14+
return ships;
15+
}
16+
17+
static CheckIsHit (ships, shot)
18+
{
19+
if (shot == undefined)
20+
throw "The shooting position is not defined";
21+
if (ships == undefined)
22+
throw "No ships defined";
23+
var returnvalue = false;
24+
ships.forEach(function(ship) {
25+
ship.positions.forEach(position => {
26+
if (position.row == shot.row && position.column == shot.column)
27+
returnvalue = true;
28+
});
29+
});
30+
return returnvalue;
31+
}
32+
33+
static isShipValid (ship) {
34+
return ship.positions.length == ship.size;
35+
}
36+
}
37+
38+
module.exports = GameController;

GameController/letters.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require('enum').register();
2+
var Letters = new Enum({'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8}, { ignoreCase: true });
3+
4+
module.exports = Letters;

GameController/position.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Position
2+
{
3+
constructor(column, row)
4+
{
5+
this.column = column;
6+
this.row = row;
7+
}
8+
}
9+
10+
module.exports = Position;

GameController/ship.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Ship
2+
{
3+
constructor (name, size, color) {
4+
this.name = name;
5+
this.size = size;
6+
this.color = color;
7+
this.positions = [];
8+
}
9+
10+
addPosition(position) {
11+
this.positions.push(position);
12+
}
13+
}
14+
15+
module.exports = Ship;
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Feature: IsShipValid
2+
In order to avoid cheeting
3+
As a player
4+
I want to be notified if my ship has a invalid placement
5+
6+
@debug
7+
Scenario: Valid ship placement
8+
Given I have a 5 ship with 5 positions
9+
When I check if the ship is valid
10+
Then the result should be "true"
11+
12+
@debug
13+
Scenario: Invalid ship placement
14+
Given I have a 5 ship with 4 positions
15+
When I check if the ship is valid
16+
Then the result should be "false"

GameController_ATDD/support/steps.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const { Given, When, Then, defineParameterType } = require("cucumber");
2+
const assert = require('assert').strict;
3+
const shipDef = require("../../GameController/ship.js");
4+
const position = require("../../GameController/position.js");
5+
const letters = require("../../GameController/letters.js");
6+
const gameController = require("../../GameController/gameController.js");
7+
8+
var ship;
9+
var actual;
10+
11+
defineParameterType({name: "bool", regexp: /"([^"]*)"/, transformer(text) {return text.toLowerCase()=="true"}});
12+
13+
Given("I have a {int} ship with {int} positions", function(size, positions){
14+
ship = new shipDef();
15+
ship.size = size;
16+
for(var i = 1; i <= positions; i++) {
17+
ship.addPosition(new position(letters.A, i))
18+
}
19+
});
20+
21+
When("I check if the ship is valid", function(){
22+
actual = gameController.isShipValid(ship);
23+
});
24+
25+
Then("the result should be {bool}", function(expected){
26+
assert.strictEqual(actual, expected);
27+
});
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const assert = require('assert').strict;
2+
const gameController=require("../GameController/gameController.js");
3+
const letters=require("../GameController/letters.js");
4+
const position=require("../GameController/position.js")
5+
6+
describe('checkIsHitTests', function() {
7+
8+
it('should return true if there is a ship at the shooting position', function() {
9+
var ships = gameController.InitializeShips();
10+
counter=1;
11+
ships.forEach(ship => {
12+
for(var i = 1; i <= ship.size; i++) {
13+
column = letters.get(counter);
14+
ship.addPosition(new position(letters.get(counter), i))
15+
}
16+
counter++;
17+
})
18+
var actual = gameController.CheckIsHit(ships, new position(letters.B,3));
19+
assert.ok(actual);
20+
});
21+
22+
it('should return false if there is no ship at the shooting position', function() {
23+
var ships = gameController.InitializeShips();
24+
counter=1;
25+
ships.forEach(ship => {
26+
for(var i = 1; i <= ship.size; i++) {
27+
ship.addPosition(new position(letters.get(counter), i))
28+
}
29+
counter++;
30+
})
31+
var actual = gameController.CheckIsHit(ships, new position(letters.G,1));
32+
assert.strictEqual(actual, false );
33+
});
34+
35+
it('should throw an exception if positstion is undefined', function() {
36+
var ships = gameController.InitializeShips();
37+
assert.throws(
38+
() => {
39+
var actual = gameController.CheckIsHit(ships, undefined);
40+
}
41+
)
42+
});
43+
44+
it('should throw an exception if ship is undefined', function() {
45+
assert.throws(
46+
() => {
47+
var actual = gameController.CheckIsHit(undefined, new position(letters.G,1));
48+
}
49+
)
50+
});
51+
});
52+
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const assert = require('assert').strict;
2+
const gameController=require("../GameController/gameController.js");
3+
const letters=require("../GameController/letters.js");
4+
const position=require("../GameController/position.js")
5+
const ship=require("../GameController/ship");
6+
7+
describe('isShipValidTests', function() {
8+
9+
it('should return true if the ship is valid', function() {
10+
var testship = new ship("Battleship", 3, 0);
11+
testship.addPosition(new position(letters.A, 1));
12+
testship.addPosition(new position(letters.A, 2));
13+
testship.addPosition(new position(letters.A, 3));
14+
15+
var actual = gameController.isShipValid(testship);
16+
assert.ok(actual);
17+
});
18+
19+
it('should return false if the ship is invalid', function() {
20+
var testship = new ship("Battleship", 3, 0);
21+
22+
var actual = gameController.isShipValid(testship);
23+
assert.ok(!actual);
24+
});
25+
});
26+
27+

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
# battleship-nodejs
2-
Battleship case study for NodeJs
1+
Start application
2+
node index.js
3+
4+
Execute all tests
5+
npm test
6+
7+
Execute Mocha tests (Unit Tests)
8+
mocha './**/*Tests.js'
9+
10+
Execute Cucumber tests
11+
./node_modules/.bin/cucumber-js .\GameController_ATDD

0 commit comments

Comments
 (0)