Skip to content

Commit

Permalink
Merge pull request #93 from miniature-tiger/miniature-tiger-patch-86
Browse files Browse the repository at this point in the history
Automated ship movement - searching for resources
  • Loading branch information
miniature-tiger committed Aug 6, 2018
2 parents f117420 + 028381f commit 9be9e8c
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 30 deletions.
94 changes: 84 additions & 10 deletions automove.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ let computer = {

telescopeHarbour: [],

telescopeResources: [],

bestDestination: [],

maxDistanceTiles: [],

minCostTiles: [],
Expand Down Expand Up @@ -101,9 +105,9 @@ let computer = {
if(workFlow == 1) {console.log('Damaged ship - decide move: '+ (Date.now() - launchTime)); }

computer.targetHarbour = pirates.findTarget('All', 'harbour');
if(workFlow == 1) {console.log('targetHarbour', computer.targetHarbour);}
if(arrayFlow == 1) {console.log('targetHarbour', computer.targetHarbour);}
computer.telescopeHarbour = pirates.useTelescope('All', 'harbour', maxMove);
if(workFlow == 1) {console.log('telescopeHarbour', computer.telescopeHarbour);}
if(arrayFlow == 1) {console.log('telescopeHarbour', computer.telescopeHarbour);}

if (computer.targetHarbour.length > 0) {
// 1 - Move to safe harbour within wind range
Expand Down Expand Up @@ -137,12 +141,26 @@ let computer = {
// Deciding move for undamaged ships (damageStatus is 5 for healthy ships)
} else if (pieceMovement.movementArray.start.pieces.damageStatus == 5) {
if(workFlow == 1) {console.log('Good ship - decide move: '+ (Date.now() - launchTime)); }
// Move maximum distance at minimum wind cost
if(workFlow == 1) {console.log('Finds max distance move at minimum cost: ' + (Date.now() - launchTime)); }
computer.maxDistanceTiles = pirates.maxPathDistance();
computer.minCostTiles = pirates.minArray(computer.maxDistanceTiles, 'moveCost');
computer.computerShipsTurn[computer.computerShipsTurnCount].end.row = computer.minCostTiles[0].row;
computer.computerShipsTurn[computer.computerShipsTurnCount].end.col = computer.minCostTiles[0].col;

computer.telescopeResources = pirates.useTelescope('All', 'resourceHarbour', row);
if(arrayFlow == 1) {console.log('telescopeResources', computer.telescopeResources);}

computer.bestDestination = computer.rankDestinations(computer.telescopeResources);

if (computer.bestDestination.length > 0) {
lastTile = pirates.findLastActive(pieceMovement.findPath[computer.bestDestination[0].row][computer.bestDestination[0].col].path, 0);
computer.computerShipsTurn[computer.computerShipsTurnCount].end.row = pieceMovement.findPath[computer.bestDestination[0].row][computer.bestDestination[0].col].path[lastTile].fromRow;
computer.computerShipsTurn[computer.computerShipsTurnCount].end.col = pieceMovement.findPath[computer.bestDestination[0].row][computer.bestDestination[0].col].path[lastTile].fromCol;

} else {
// Move maximum distance at minimum wind cost - should not be required if
if(workFlow == 1) {console.log('Finds max distance move at minimum cost: ' + (Date.now() - launchTime)); }
computer.maxDistanceTiles = pirates.maxPathDistance();
computer.minCostTiles = pirates.minArray(computer.maxDistanceTiles, 'moveCost');
console.log('computer.maxDistanceTiles', computer.maxDistanceTiles)
computer.computerShipsTurn[computer.computerShipsTurnCount].end.row = computer.minCostTiles[0].row;
computer.computerShipsTurn[computer.computerShipsTurnCount].end.col = computer.minCostTiles[0].col;
}

// Catching move for ships under repair (damageStatus between 0 and 5)
} else {
Expand Down Expand Up @@ -191,7 +209,6 @@ let computer = {

// Check whether there are resources to be claimed
for (var k = 0; k < computer.computerShipsTurn.length; k+=1) {

for (var i = -1; i < 2; i+=1) {
if(computer.computerShipsTurn[k].end.row+i >=0 && computer.computerShipsTurn[k].end.row+i <row) {
for (var j = -1; j < 2; j+=1) {
Expand All @@ -218,7 +235,7 @@ let computer = {

// Decide whether a resource should be claimed - simple version of decision for first implementation
for (var l = 0; l < claimableResources.length; l+=1) {
// Need to check whether player has already claimed this resource in this loop - can happen that claimableResource includes 2 or 3 of same resource type
// Need to check whether player has already claimed this resource in this loop - can happen that claimableResource includes 2 or 3 of same resource type
if (stockDashboard.pieceTotals[teamPosition].pieces[claimableResources[l].type].quantity == 0) {
// Claim resource (already checked that have resource in construction of claimable resource)
resourceManagement.claimResource(claimableResources[l].row, claimableResources[l].col, gameManagement.turn);
Expand All @@ -229,6 +246,63 @@ let computer = {
}
},

// Method to rank potential map destinations for move choice related to Resources
// ------------------------------------------------------------------------------
// TO DO: add / subtract points for (a) Nearness to next good option (b) Closeness to pirates ships
// Also need to consider moving off route for lesser detination if its on the way to best destination
rankDestinations: function(movesToRate) {
// Team position of piece information array required to check if resource pieces already held
let teamPosition = stockDashboard.pieceTotals.findIndex(fI => fI.team == gameManagement.turn);
let maxPoints = 0;
let bestMove = [];

// Loops through all potential map moves and adds points to rate them
for (var i = 0; i < movesToRate.length; i+=1) {
movesToRate[i].points = 0;
if(movesToRate[i].pathStop[0] == 'none' || movesToRate[i].activeStatus != 'active') {
for (var j = 0; j < movesToRate[i].type.length; j+=1) {
// Virgin islands are worth visiting - and a better option if they can be reached in one turn
if(movesToRate[i].type[j] == 'virgin') {
if(movesToRate[i].activeStatus == 'active') {
movesToRate[i].points += 3;
} else {
movesToRate[i].points += 1;
}
// Revealed pieces that are needed are more valuable options than virgin islands which may be desert or duplicate pieces
} else if (stockDashboard.pieceTotals[teamPosition].pieces[movesToRate[i].type[j]].quantity == 0) {
if(movesToRate[i].activeStatus == 'active') {
movesToRate[i].points += 6;
} else {
movesToRate[i].points += 4;
}
} else {
// no points
}
}

// Points for destinations at greater distance are reduced by estimated number of moves to get there
let moveCostDivisor = 1;
if (movesToRate[i].activeStatus == 'active') {
// moveCostDivisor = 1;
} else {
moveCostDivisor = movesToRate[i].moveCost/maxMove;
}
movesToRate[i].points = Number((movesToRate[i].points / moveCostDivisor).toFixed(2));

// Array built up of highest scoring options
if (movesToRate[i].points > maxPoints) {
maxPoints = movesToRate[i].points
bestMove = [movesToRate[i]];
} else if (movesToRate[i].points == maxPoints && movesToRate[i].points > 0) {
bestMove.push(movesToRate[i]);
}
}
}

if(arrayFlow == 1) {console.log('bestMove', bestMove);}
return bestMove;
},


// LAST BRACKET OF OBJECT
}
2 changes: 1 addition & 1 deletion main.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ function boardHandler(event) {
}

// Loading of a ship
} else if (((pieceMovement.movementArray.start.pieces.category == 'Resources' && pieceMovement.movementArray.start.pieces.type != 'desert') || pieceMovement.movementArray.start.pieces.category == 'Settlements') && pieceMovement.movementArray[startEnd].pieces.team == gameManagement.turn) {
} else if (((pieceMovement.movementArray.start.pieces.category == 'Resources' && pieceMovement.movementArray.start.pieces.type != 'desert') || pieceMovement.movementArray.start.pieces.category == 'Settlements') && pieceMovement.movementArray[startEnd].pieces.team == gameManagement.turn) {
if (pieceMovement.shipAvailable(pieceMovement.movementArray.start.pieces.goods) == 'compatible') {
if (pieceMovement.movementArray.start.pieces.stock > 0) {
startEnd = 'end';
Expand Down
52 changes: 42 additions & 10 deletions movement.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ let pieceMovement = {
if(localStartCol+j >=0 && localStartCol+j <col) {
// Checks if tile is found. If so runs activeTiles to search for potential tiles to activate around it.
// Does not check tiles if pathStop is active (pathStop prevents ships moving through harbours or other ships)
if ((this.findPath[localStartRow+i][localStartCol+j].pathStatus == true) && (this.findPath[localStartRow+i][localStartCol+j].pathStop.type == 'none' || k == 0)) {
if ((this.findPath[localStartRow+i][localStartCol+j].pathStatus == true) && (this.findPath[localStartRow+i][localStartCol+j].pathStop.type[0] == 'none' || k == 0)) {
//Keep useful for debugging - console.log('run: ' + k);
//Keep useful for debugging - console.log('starting from: row: ' + (localStartRow+i) + ' col: ' + (localStartCol+j) + ' prior cost: ' + this.findPath[localStartRow+i][localStartCol+j].moveCost);
this.activeTiles(localStartRow+i, localStartCol+j, this.findPath[localStartRow+i][localStartCol+j].moveCost, localMaxMove, displayActive, k, localDamagedStatus);
Expand All @@ -80,7 +80,7 @@ let pieceMovement = {
for (var i = 0; i < col; i++) {
let localMoveRow = [];
for (var j = 0; j < row; j++) {
localMoveRow[j] = {pathStatus: false, activeStatus: 'inactive', moveCost: 0, distance: 0, target: {type: 'none', team: 'none'}, harbour: {type: 'none', team: 'none'}, pathStop: {type: 'none', team: 'none'}, path: [{fromRow: +localStartRow , fromCol: +localStartCol}]};
localMoveRow[j] = {pathStatus: false, activeStatus: 'inactive', moveCost: 0, distance: 0, target: {type: ['none'], team: 'none'}, resourceHarbour: {type: ['none'], team: 'none'}, harbour: {type: ['none'], team: 'none'}, pathStop: {type: ['none'], team: 'none'}, path: [{fromRow: +localStartRow , fromCol: +localStartCol}]};
}
this.findPath[i] = localMoveRow;
}
Expand Down Expand Up @@ -131,7 +131,7 @@ let pieceMovement = {
// Keep useful for debugging - console.log('already active logic is used:');
//console.log('change to active tile - pre:', localStartRow+i, localStartCol+j, this.findPath[localStartRow+i][localStartCol+j], 'from ' + localStartRow + '-' + localStartCol, this.findPath[localStartRow][localStartCol]);
// Update the cost, add the inherited path from the previous moved-to tile, push the path for the new tile
this.findPath[localStartRow+i][localStartCol+j].moveCost = tileCumulMoveCost;
this.findPath[localStartRow+i][localStartCol+j].moveCost = Number(tileCumulMoveCost.toFixed(2));
this.findPath[localStartRow+i][localStartCol+j].path = this.findPath[localStartRow][localStartCol].path.slice(0);
this.findPath[localStartRow+i][localStartCol+j].path.push({fromRow: +(localStartRow+i) , fromCol: +(localStartCol+j)});
this.findPath[localStartRow+i][localStartCol+j].distance = this.findPath[localStartRow+i][localStartCol+j].path.length-1;
Expand All @@ -149,7 +149,7 @@ let pieceMovement = {
}
}
// Update the cost, add the inherited path from the previous moved-to tile, push the path for the new tile
this.findPath[localStartRow+i][localStartCol+j].moveCost = tileCumulMoveCost;
this.findPath[localStartRow+i][localStartCol+j].moveCost = Number(tileCumulMoveCost.toFixed(2));

this.findPath[localStartRow+i][localStartCol+j].path = this.findPath[localStartRow][localStartCol].path.slice(0);
this.findPath[localStartRow+i][localStartCol+j].path.push({fromRow: +(localStartRow+i) , fromCol: +(localStartCol+j)});
Expand Down Expand Up @@ -190,20 +190,52 @@ let pieceMovement = {
for (var j = 0; j < row; j++) {
// Target transport ships for pirate attack
if (gameBoard.boardArray[i][j].pieces.category == 'Transport' && gameBoard.boardArray[i][j].pieces.team != 'Pirate' && gameBoard.boardArray[i][j].pieces.damageStatus == 5) {
this.findPath[i][j].target = {type: gameBoard.boardArray[i][j].pieces.type, team: gameBoard.boardArray[i][j].pieces.team};
this.findPath[i][j].target = {type: [gameBoard.boardArray[i][j].pieces.type], team: gameBoard.boardArray[i][j].pieces.team};
}
// Unclaimed resources and virgin islands harbour
if ( (gameBoard.boardArray[i][j].terrain == 'land' && !gameBoard.boardArray[i][j].pieces.populatedSquare) ||
(gameBoard.boardArray[i][j].pieces.category == 'Resources' && gameBoard.boardArray[i][j].pieces.type != 'desert' && gameBoard.boardArray[i][j].pieces.team == 'Unclaimed') ) {
// Single tile search around the island
for (var k = -1; k < 2; k+=1) {
if(i + k >=0 && i + k <row) {
for (var l = -1; l < 2; l+=1) {
if(j + l >=0 && j + l <col) {
// Reduces search to exclude diagonals
if(k == 0 || l == 0) {
if(gameBoard.boardArray[i+k][j+l].terrain == 'sea') {
if(this.findPath[i+k][j+l].resourceHarbour.type[0] == 'none') {
if (gameBoard.boardArray[i][j].pieces.category == 'Resources' && gameBoard.boardArray[i][j].pieces.type != 'desert' && gameBoard.boardArray[i][j].pieces.team == 'Unclaimed') {
this.findPath[i+k][j+l].resourceHarbour.type[0] = gameBoard.boardArray[i][j].pieces.type;
} else {
this.findPath[i+k][j+l].resourceHarbour.type[0] = 'virgin';
}
} else {
if (gameBoard.boardArray[i][j].pieces.category == 'Resources' && gameBoard.boardArray[i][j].pieces.type != 'desert' && gameBoard.boardArray[i][j].pieces.team == 'Unclaimed') {
this.findPath[i+k][j+l].resourceHarbour.type.push(gameBoard.boardArray[i][j].pieces.type);
} else {
this.findPath[i+k][j+l].resourceHarbour.type.push('virgin');
}
}
}
}
}
}
}
}
}
// Safe harbour for ship repair or hiding
if (gameBoard.boardArray[i][j].subTerrain == 'harbour') {
this.findPath[i][j].harbour = {type: gameBoard.boardArray[i][j].subTerrain, team: 'none'};
this.findPath[i][j].harbour = {type: [gameBoard.boardArray[i][j].subTerrain], team: 'none'};
}
// Tiles where path must end
if (gameBoard.boardArray[i][j].pieces.category == 'Transport') {
this.findPath[i][j].pathStop = {type: gameBoard.boardArray[i][j].pieces.type, team: gameBoard.boardArray[i][j].pieces.team};
this.findPath[i][j].pathStop = {type: [gameBoard.boardArray[i][j].pieces.type], team: gameBoard.boardArray[i][j].pieces.team};
} else if (gameBoard.boardArray[i][j].subTerrain == 'harbour') {
this.findPath[i][j].pathStop = {type: gameBoard.boardArray[i][j].subTerrain, team: 'none'};
this.findPath[i][j].pathStop = {type: [gameBoard.boardArray[i][j].subTerrain], team: 'none'};
}
}
}
if(arrayFlow == 1) {console.log('findPath', this.findPath);}
},

// Sets the "cost" of each move in relation to the wind direction
Expand All @@ -227,6 +259,7 @@ let pieceMovement = {
moveCostResult = 0.8;
}
return moveCostResult;

},

// Method to deactivate tiles after a piece has moved
Expand Down Expand Up @@ -600,8 +633,7 @@ let pieceMovement = {
let endCannon = 0;
if (pirates.conflictArray.conflict == true) {
if(workFlow == 1) {console.log('Ship conflict - battle: ' + (Date.now() - launchTime)); }
console.log(pirates.conflictArray);
console.log(startDirection);
if(arrayFlow == 1) {console.log('conflictArray', pirates.conflictArray);}
// Obtains ID and element of pirates
IDPirate = 'tile' + Number(pirates.conflictArray.pirate.row*1000 + pirates.conflictArray.pirate.col);
let piratePiece = document.getElementById(IDPirate);
Expand Down
Loading

0 comments on commit 9be9e8c

Please sign in to comment.