Skip to content

Commit

Permalink
finished ship placement. Closes #1. Closes #12. Closes #20
Browse files Browse the repository at this point in the history
  • Loading branch information
warreq committed Sep 27, 2015
1 parent 7757e0e commit 8637512
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 68 deletions.
12 changes: 6 additions & 6 deletions src/main/java/edu/dirtybit/battlechat/model/Fleet.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ public Fleet(int canoes, int cruisers, int submarines, int destroyers, int battl

int i = 0;
for (i = 0; i < canoes; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.CANOE));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.CANOE));
}
for (i = 0; i < cruisers; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.CRUISER));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.CRUISER));
}
for (i = 0; i < submarines; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.SUBMARINE));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.SUBMARINE));
}
for (i = 0; i < destroyers; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.DESTROYER));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.DESTROYER));
}
for (i = 0; i < battleships; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.BATTLESHIP));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.BATTLESHIP));
}
for (i = 0; i < carriers; i++) {
this.ships.add(new Ship(0, 0, Rotation.Horizontal, ShipType.CARRIER));
this.ships.add(new Ship(0, 0, Rotation.HORIZONTAL, ShipType.CARRIER));
}
}

Expand Down
27 changes: 18 additions & 9 deletions src/main/java/edu/dirtybit/battlechat/model/GameState.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public GameState(GameConfiguration config, Player player) {
this.cfg = (BattleShipConfiguration) config;
this.boards = new ArrayList<>();
this.hasPlaced = new ArrayList<>();
for(int i = 0; i < cfg.getPropertyAsInt(ConfigKeys.PLAYER_COUNT); i++) {
this.hasPlaced.add(false);
}

this.initializeBoards(this.cfg);
this.phase = Phase.NOT_STARTED;
Expand Down Expand Up @@ -137,18 +140,18 @@ protected Fleet randomizeFleet(Fleet fleet) {
for (int i = 0; i < fleet.getShips().size(); i++) {
Ship ship = fleet.getShips().get(i);
// Start with a random rotation
ship.setRotation(rng.nextBoolean() == true ? Rotation.Horizontal : Rotation.Vertical);
ship.setRotation(rng.nextBoolean() == true ? Rotation.HORIZONTAL : Rotation.VERTICAL);
// Get the max possible placement values given the rotation
int xmax = ship.getRotation() == Rotation.Horizontal ? testboard.getWidth() - (ship.getShiptype().getLength() - 1) : testboard.getWidth();
int ymax = ship.getRotation() == Rotation.Vertical ? testboard.getHeight() - (ship.getShiptype().getLength() - 1) : testboard.getHeight();
int xmax = ship.getRotation() == Rotation.HORIZONTAL ? testboard.getWidth() - (ship.getShiptype().getLength() - 1) : testboard.getWidth();
int ymax = ship.getRotation() == Rotation.VERTICAL ? testboard.getHeight() - (ship.getShiptype().getLength() - 1) : testboard.getHeight();

// If a ship fails 10 random placements, restart the fleet placement
int attempts = 10;
for (int j = 0; j < attempts; j++) {
// pick a random starting location
ship.setLocation(rng.nextInt(xmax), rng.nextInt(ymax));
int endx = ship.getRotation() == Rotation.Horizontal ? ship.getX() + (ship.getShiptype().getLength() - 1) : ship.getX();
int endy = ship.getRotation() == Rotation.Vertical ? ship.getY() + (ship.getShiptype().getLength() - 1) : ship.getY();
int endx = ship.getRotation() == Rotation.HORIZONTAL ? ship.getX() + (ship.getShiptype().getLength() - 1) : ship.getX();
int endy = ship.getRotation() == Rotation.VERTICAL ? ship.getY() + (ship.getShiptype().getLength() - 1) : ship.getY();

// Test if ship can be placed
boolean canplace = true;
Expand Down Expand Up @@ -222,8 +225,8 @@ protected void placeFleet(Fleet fleet, Board board) throws ShipOutOfBoundsExcept
}

// Get the end coordinates of the ship
int endx = ship.getRotation() == Rotation.Horizontal ? ship.getX() + ship.getShiptype().getLength() - 1 : ship.getX();
int endy = ship.getRotation() == Rotation.Vertical ? ship.getY() + ship.getShiptype().getLength() - 1 : ship.getY();
int endx = ship.getRotation() == Rotation.HORIZONTAL ? ship.getX() + ship.getShiptype().getLength() - 1 : ship.getX();
int endy = ship.getRotation() == Rotation.VERTICAL ? ship.getY() + ship.getShiptype().getLength() - 1 : ship.getY();

// Check if the start coordinates are on the board
if (ship.getX() >= 0 && ship.getX() < board.getWidth() -1 && ship.getY() >= 0 || ship.getY() < board.getHeight() -1) {
Expand Down Expand Up @@ -300,8 +303,12 @@ private void phaseChange() {
this.secondsToNextPhase = this.placementTimeout;
break;
case PLACEMENT_PHASE:
this.getBoards().stream().filter(board -> !this.validateFleet(board.getFleet())).forEach(board ->
this.randomizeFleet(board.getFleet()));
this.getBoards().stream().filter(board -> !this.validateFleet(board.getFleet())).forEach(board -> {
this.randomizeFleet(board.getFleet());
notifySubscribers(new GameMessage(GameMessageType.EVENT,
this.getPlayers().get(this.boards.indexOf(board)).getId(),
"You didn't arrange your fleet in time, so it was randomized for you."));
});
this.phase = Phase.COMBAT;
this.secondsToNextPhase = this.firingTimeout;
break;
Expand Down Expand Up @@ -349,9 +356,11 @@ private void handlePlacement(GameMessage<Fleet> placement) {
Player p = this.getPlayerById(placement.getId());
int pi = this.getPlayerIndex(p);
try {
placement.getBody().getShips().forEach(s -> s.resetCells());
placeFleet(placement.getBody(), this.boards.get(pi));
this.boards.get(pi).setFleet(placement.getBody());
this.hasPlaced.set(pi, true);
notifySubscribers(new GameMessage(GameMessageType.EVENT, placement.getId(), "You have successfully arranged your fleet."));
} catch (ShipOutOfBoundsException | ShipsOverlapException | InvalidFleetsizeException e) {
this.notifySubscribers(new GameMessage<>(GameMessageType.ERROR, placement.getId(), e.getMessage()));
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/edu/dirtybit/battlechat/model/Rotation.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package edu.dirtybit.battlechat.model;

public enum Rotation {
Horizontal, Vertical
HORIZONTAL, VERTICAL
}
8 changes: 4 additions & 4 deletions src/main/java/edu/dirtybit/battlechat/model/Ship.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ public class Ship {
private ArrayList<Point> cells;

public Ship(ShipType shiptype) {
this(0, 0, Rotation.Horizontal, shiptype);
this(0, 0, Rotation.HORIZONTAL, shiptype);
}

public Ship(int x, int y, Rotation rotation, ShipType shiptype) {
this.x = x;
this.y = y;
this.rotation = rotation;
this.shiptype = shiptype;
this.cells = new ArrayList<Point>();
this.cells = new ArrayList<>();
this.resetCells();
}

Expand Down Expand Up @@ -92,13 +92,13 @@ public int getHealth() {
}

public void resetCells() {
this.cells.clear();
this.cells = new ArrayList<>();

int x = this.x;
int y = this.y;
for (int i = 0; i < this.shiptype.getLength(); i++) {
this.cells.add(new Point(x, y));
if (this.rotation == Rotation.Horizontal) {
if (this.rotation == Rotation.HORIZONTAL) {
x++;
} else {
y++;
Expand Down
82 changes: 53 additions & 29 deletions src/main/resources/app/js/app.board.viewmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
appBoardViewModel.myBoard = ko.observableArray();
appBoardViewModel.theirBoard = ko.observableArray();
appBoardViewModel.ships = ko.observableArray();
appBoardViewModel.shipPlacedCount = ko.observable();
appBoardViewModel.canPlaceShips = ko.observable(false);
appBoardViewModel.placementSent = ko.observable(false);

appBoardViewModel.shipsPlaced = ko.computed(function() {
return appBoardViewModel.ships().length == appBoardViewModel.shipPlacedCount();
});

appBoardViewModel.enablePlacementButton = ko.computed(function() {
return !appBoardViewModel.placementSent() && appBoardViewModel.shipsPlaced();
});

function applyMetaData(board) {
for(var i = 0; i < board.length; i++) {
Expand Down Expand Up @@ -31,35 +42,48 @@
}
init = true;
}

function getShipsState(numberOfBoat) {
var shipState = [];
for(var i=0; i<numberOfBoat; i++){
var ship = document.getElementById('ship'+(i+1));
var firstOccupiedCell = document.getElementsByClassName('byship'+(i+1))[0];

//Position
var x = firstOccupiedCell.id.charAt(firstOccupiedCell.id.length-1);
var y = firstOccupiedCell.id.charAt(firstOccupiedCell.id.length-2);

//orientation
var orientation='';
if (ship.classList.contains('horizontal')) orientation = 'horizontal';
else if (ship.classList.contains('vertical')) orientation = 'vertical';

//ShipType
var shipType='';
if (ship.classList.contains('cruiser')) shipType = 'cruiser';
else if (ship.classList.contains('submarine')) shipType = 'submarine';
else if (ship.classList.contains('battleship')) shipType = 'battleship';
else if (ship.classList.contains('destroyer')) shipType = 'destroyer';
else if (ship.classList.contains('carrier')) shipType = 'carrier';

var array = [x,y,orientation,shipType];
shipState.push(array);
}
return shipState;
}

appBoardViewModel.sendFleetPlacement = function() {
var numberOfBoat = appBoardViewModel.ships().length;
var shipState = [];
for(var i=0; i<numberOfBoat; i++){
var ship = document.getElementById('ship' + i);
var firstOccupiedCell = document.getElementsByClassName('byship'+ i)[0];

//Position
var x = firstOccupiedCell.id.charAt(firstOccupiedCell.id.length-1);
var y = firstOccupiedCell.id.charAt(firstOccupiedCell.id.length-2);

//orientation
var orientation='';
if (ship.classList.contains('horizontal')) orientation = 'horizontal';
else if (ship.classList.contains('vertical')) orientation = 'vertical';

//ShipType
var shipType='';
if (ship.classList.contains('cruiser')) shipType = 'cruiser';
else if (ship.classList.contains('submarine')) shipType = 'submarine';
else if (ship.classList.contains('battleship')) shipType = 'battleship';
else if (ship.classList.contains('destroyer')) shipType = 'destroyer';
else if (ship.classList.contains('carrier')) shipType = 'carrier';

var s = {
"x": x,
"y": y,
"rotation": orientation.toUpperCase(),
"shiptype": shipType.toUpperCase()
};
shipState.push(s);
}
var msg = {
messageType: "PLACEMENT",
id: appSocket.id,
body: { "ships": shipState }
};
appSocket.send(msg);
appBoardViewModel.placementSent(true);
return shipState;
};

function clearPlacement() {
$(".ship").remove();
Expand Down
17 changes: 8 additions & 9 deletions src/main/resources/app/js/app.game.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ function swipeLeft() {
};

function shipDrop(ship, dropzone) {
console.log(ship);
console.log(dropzone);
$('#'+ship.id).css('left',0).appendTo($('#'+dropzone.id));

// notify user with occupied cells
Expand All @@ -62,13 +60,13 @@ function shipDrop(ship, dropzone) {
if ($('#'+ship.id).hasClass('odd')){
var middledivnum = parseInt(dropzone.id.slice(-1));
var divoneachsidenum = (length-1)/2;
console.log(divoneachsidenum + ' : divs on each side');
//console.log(divoneachsidenum + ' : divs on each side');

var startingdivnum = middledivnum - divoneachsidenum;
console.log(startingdivnum + ' : starting div num');
//console.log(startingdivnum + ' : starting div num');

var endingdivnum = middledivnum + divoneachsidenum;
console.log(endingdivnum + ' : ending div num');
//console.log(endingdivnum + ' : ending div num');
var d;
for(i=startingdivnum; i<endingdivnum+1; i++){
d = document.getElementById('lsquare'+row+i);
Expand Down Expand Up @@ -177,6 +175,7 @@ function shipDrop(ship, dropzone) {
}
}
ship.classList.add('dropped');
appBoardViewModel.shipPlacedCount($(".dropped").length);
};

//swipe + arrowkeys
Expand Down Expand Up @@ -247,7 +246,7 @@ function removeOccupiedDivsBy (targetId) {
for (var i = 0; i < l; i++) {
occupieddivs[i].classList.remove("occupied");
occupieddivs[i].classList.remove("by"+targetId);
console.log(occupieddivs[i]);
//console.log(occupieddivs[i]);
}
}

Expand All @@ -256,7 +255,7 @@ function removeDroppableFeedback () {
var l = targetdivs.length;
for (var i = 0; i < l; i++) {
targetdivs[i].classList.remove("drop-target");
console.log(targetdivs[i]);
//console.log(targetdivs[i]);
}
}

Expand All @@ -283,7 +282,7 @@ interact('.draggable').draggable({
},
// call this function on every dragend event
onend: function (event) {
console.log(event.target.dropped);
//console.log(event.target.dropped);
if (event.target.classList.contains('dropped')) {
// snap to the start position
//event.target.snap();
Expand Down Expand Up @@ -363,7 +362,7 @@ interact('.square').dropzone({
};
}
}
console.log(dropLeft);
//console.log(dropLeft);
// feedback the possibility of a drop
draggableElement.classList.add('can-drop');

Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/app/js/app.gamestate.viewmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
var lastPhase = "";

function isPhaseChanged(phase) {
if(phase == "PLACEMENT_PHASE" && !appBoardViewModel.canPlaceShips()) {
appBoardViewModel.canPlaceShips(true);
} else if (phase != "PLACEMENT_PHASE") {
appBoardViewModel.canPlaceShips(false);
}
return lastPhase != phase;
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/app/js/app.socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
case "EVENT":
appChatViewModel.handleMessage(msg.body, msg.messageType);
break;
case "ERROR":
appChatViewModel.handleMessage(msg.body, msg.messageType);
break;
case "STATUS":
appGameStateViewModel.handlePhaseData(msg.body);
break;
Expand Down
27 changes: 26 additions & 1 deletion src/main/resources/app/style/gameStyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,29 @@ html, body{
border:2px solid white;
position:absolute;
display:none;
}
}

#lockship{
width:100%;
position:absolute;
top:70vmin;
text-align:center;
}

#sendShipPlacement{
width: 50vh;
margin: 0px auto;
height: 5vh;
color: rgb(51, 51, 51);
display: block;
text-align: center;
font-family: slkscr;
font-size: 22;
border: 2px solid #ccc;
background-color: #404040;
}

#sendShipPlacement:enabled{
color: #ccc;
background-color: #4eafd6;
}
5 changes: 5 additions & 0 deletions src/main/resources/templates/game.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
</div>
</div>
</div>
<div id="lockship" data-bind="visible: appBoardViewModel.canPlaceShips()">
<button id="sendShipPlacement" data-bind="enable: appBoardViewModel.enablePlacementButton()" onclick="appBoardViewModel.sendFleetPlacement()">
Ready
</button>
</div>
</div>
<div id="rightarrow">-&gt;</div>
<div id="leftarrow">&lt;-</div>
Expand Down
Loading

0 comments on commit 8637512

Please sign in to comment.