From f40ab3b989566b2ffbb372c8ec0b23dd416e4fce Mon Sep 17 00:00:00 2001 From: Chris Shumate Date: Tue, 14 Apr 2015 17:07:29 -0600 Subject: [PATCH 1/2] separating out connect code from ai logic - initial pass - this can be improved upon but it is a starting place --- connect.js | 53 ++++++++ index.js | 372 +++++++++++++++++++++++------------------------------ 2 files changed, 216 insertions(+), 209 deletions(-) create mode 100644 connect.js diff --git a/connect.js b/connect.js new file mode 100644 index 0000000..a2912fd --- /dev/null +++ b/connect.js @@ -0,0 +1,53 @@ +exports.connect = function(done){ + var port = "8003"; + var url = 'http://localhost:' + port; + var socketio = require('socket.io-client'); + var socket = socketio(url); + var command; //socket to send commands on + var initData; + var selectedPlayer; + + + var connected = false; + + var playerSelection; + if (process.argv[2]) { + playerSelection = parseInt(process.argv[2], 10); + } + + var enemyBases = []; + var myTanks = []; + var allBases = []; + socket.on("init", function(initD) { + if (connected) { + return false; + } + socket.on("disconnect", function() { + //process.exit(1); + }); + connected = true; + initData = initD; + selectedPlayer = initData.players[playerSelection]; + command = socketio(url + "/" + selectedPlayer.namespace); + enemyBases = initData.players.filter(function(p) { + return selectedPlayer.playerColor !== p.playerColor; + }); + allBases = initData.players; + var serverTanks = initData.tanks.filter(function(t) { + return selectedPlayer.playerColor === t.color; + }); + var data={ + serverTanks:serverTanks, + enemyBases:enemyBases, + socket:socket, + command:command, + selectedPlayer:selectedPlayer, + allBases:allBases + }; + + setTimeout(function() { + done(data); + }, 2000); + + }); +}; diff --git a/index.js b/index.js index 9a216ca..d573f72 100644 --- a/index.js +++ b/index.js @@ -1,210 +1,164 @@ -var port = "8003"; -var url = 'http://localhost:' + port; -var socketio = require('socket.io-client'); -var socket = socketio(url); -var command; //socket to send commands on -var initData; -var selectedPlayer; - - -var connected = false; - -var playerSelection; -if (process.argv[2]) { - playerSelection = parseInt(process.argv[2], 10); -} - -var enemyBases = []; -var myTanks = []; -var allBases = []; -socket.on("init", function(initD) { - if (connected) { - return false; - } - socket.on("disconnect", function() { - //process.exit(1); - }); - connected = true; - initData = initD; - selectedPlayer = initData.players[playerSelection]; - command = socketio(url + "/" + selectedPlayer.namespace); - enemyBases = initData.players.filter(function(p) { - return selectedPlayer.playerColor !== p.playerColor; - }); - allBases = initData.players; - var serverTanks = initData.tanks.filter(function(t) { - return selectedPlayer.playerColor === t.color; - }); - for (var i = 0; i < serverTanks.length; i++) { - myTanks.push(new Tank(i)); - } - - setTimeout(function() { - startInterval(); - }, 2000); - -}); - - -/*** AI logic goes after here ***/ - -/** send back to server **/ -function startInterval() { - setInterval(function() { - sendBackCommands(); - }, 500); - - setInterval(function() { - fire(); - }, 500); -} - -function sendBackCommands() { - //add up all calculations - var speed, angleVel, orders; - for (var i = 0; i < myTanks.length; i++) { - speed = myTanks[i].goal.speed * 1; - angleVel = myTanks[i].goal.angleVel * 1; - orders = { - tankNumbers: [myTanks[i].tankNumber], //an array of numbers e.g. [0,1,2,3] - speed: speed, //speed of tank value of -1 to 1, numbers outside of this range will default to -1 or 1, whichever is closer. - angleVel: angleVel //turning speed of tank positive turns right, negative turns left - } - command.emit("move", orders); - } -} - -function fire() { - var orders = { - tankNumbers: [0,1,2,3] - } - command.emit("fire", orders); -} - -/** recieve from server **/ -socket.on("refresh", function(gameState) { - var myTanksNewPosition = gameState.tanks.filter(function(t) { - return selectedPlayer.playerColor === t.color; - }); - - updateMyTanks(myTanksNewPosition); - calculateGoal(); - // if (gameState.boundaries.length > 0) { - // //calculateObstacle(gameState.boundaries); - // } - +var connect = require('./connect.js'); +var app = connect.connect; + + +app(function(data) { + var serverTanks = data.serverTanks; + var allBases = data.allBases; + var socket = data.socket; + var command = data.command; + var selectedPlayer = data.selectedPlayer; + var myTanks = []; + //Create base tank Object with properties + var Tank = function(tankNumber) { + this.tankNumber = tankNumber; + this.tankColor = selectedPlayer.playerColor; + this.position = { + x: 0, + y: 0 + }; + this.angle; + this.goal = { + speed: 0, + angleVel: 0 + }; + this.avoidObstacle = { + speed: 0, + angleVel: 0 + }; + this.target = { + x: 100, + y: 100 + }; + this.hasATarget = false; + }; + //extend Tank with functions + Tank.prototype = { + getTarget: function() { + return this.target; + }, + hasTarget: function() { + return this.hasATarget; + }, + generateTarget: function() { + + //wander between all bases + var randomNumber = Math.floor(Math.random() * 10 % allBases.length); //random num between 0 and enemyBases.length + this.target = allBases[randomNumber].base.position; + + this.hasATarget = true; + return this.target; + }, + missionAccomplished: function() { + this.hasATarget = false; + } + }; + + //assign serverTanks to myTanks array + for (var i = 0; i < serverTanks.length; i++) { + myTanks.push(new Tank(i)); + } + + function startInterval() { + setInterval(function() { + sendBackCommands(); + }, 100); + + setInterval(function() { + fire(); + }, 100); + } + //start sending Commands and Firing. + startInterval(); + + function sendBackCommands() { + //add up all calculations + var speed, angleVel, orders; + for (var i = 0; i < myTanks.length; i++) { + speed = myTanks[i].goal.speed * 1; + angleVel = myTanks[i].goal.angleVel * 1; + orders = { + tankNumbers: [myTanks[i].tankNumber], + speed: speed, + angleVel: angleVel + } + command.emit("move", orders); + } + } + + function fire() { + var orders = { + tankNumbers: [0, 1, 2, 3] + } + command.emit("fire", orders); + } + + socket.on("refresh", function(gameState) { + + var myTanksNewPosition = gameState.tanks.filter(function(t) { + return selectedPlayer.playerColor === t.color; + }); + + updateMyTanks(myTanksNewPosition); + calculateGoal(); + + }); + + function updateMyTanks(myTanksNewPosition) { + for (var i = 0; i < myTanks.length; i++) { + for (var j = 0; j < myTanksNewPosition.length; j++) { + if (myTanks[i].tankNumber === myTanksNewPosition[j].tankNumber) { + myTanks[i].position = myTanksNewPosition[j].position; + myTanks[i].angle = myTanksNewPosition[j].angle; + } + } + } + } + + function calculateGoal() { + var distance = 0; + var angle = 0; + var degrees = 0; + var relativeX = 0; + var relativeY = 0; + + for (var i = 0; i < myTanks.length; i++) { + if (myTanks[i].hasTarget()) { + goal = myTanks[i].getTarget(); + } else { + goal = myTanks[i].generateTarget(); + } + //find distance to goal + distance = round(Math.sqrt(Math.pow((goal.x - myTanks[i].position.x), 2) + Math.pow((goal.y - myTanks[i].position.y), 2)), 4); + + //find angle difference to face goal + relativeX = goal.x - myTanks[i].position.x; + relativeY = goal.y - myTanks[i].position.y; + angle = round(Math.atan2(-(relativeY), relativeX), 4); + degrees = round(angle * (180 / Math.PI), 4); //convert from radians to degrees + degrees = degrees % 360; //(0 to 360)prevent overflow + degrees = -(degrees); // tank degrees ascends clockwise. atan2 ascends counter clockwise. this fixes that difference + + //turn in the direction whichever is closer + if (degrees > myTanks[i].angle) { // + + myTanks[i].goal.angleVel = 1; + } else { // - + myTanks[i].goal.angleVel = -1; + } + + //set speed + if (distance >= 20) { + myTanks[i].goal.speed = 1; + } else { + //myTanks[i].goal.speed = 0; + myTanks[i].missionAccomplished(); + } + } + } + + + //rounds number (value) to specified number of decimals + function round(value, decimals) { + return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals); + } }); - -function updateMyTanks (myTanksNewPosition) { - for (var i = 0; i < myTanks.length; i++) { - for (var j = 0; j < myTanksNewPosition.length; j++) { - if (myTanks[i].tankNumber === myTanksNewPosition[j].tankNumber) { - myTanks[i].position = myTanksNewPosition[j].position; - myTanks[i].angle = myTanksNewPosition[j].angle; - } - } - } -} - -function calculateGoal() { - var distance = 0; - var angle = 0; - var degrees = 0; - var relativeX = 0; - var relativeY = 0; - - for (var i = 0; i < myTanks.length; i++) { - if (myTanks[i].hasTarget()) { - goal = myTanks[i].getTarget(); - } else { - goal = myTanks[i].generateTarget(); - } - //find distance to goal - distance = round(Math.sqrt(Math.pow(( goal.x - myTanks[i].position.x ), 2) + Math.pow(( goal.y - myTanks[i].position.y ), 2)), 4); - - //find angle difference to face goal - relativeX = goal.x - myTanks[i].position.x; - relativeY = goal.y - myTanks[i].position.y; - angle = round(Math.atan2(-(relativeY), relativeX), 4); - degrees = round(angle * (180 / Math.PI), 4); //convert from radians to degrees - degrees = degrees % 360; //(0 to 360)prevent overflow - degrees = -(degrees); // tank degrees ascends clockwise. atan2 ascends counter clockwise. this fixes that difference - - //turn in the direction whichever is closer - if (degrees > myTanks[i].angle) { // + - myTanks[i].goal.angleVel = 1; - } else { // - - myTanks[i].goal.angleVel = -1; - } - - //set speed - if (distance >= 20) { - myTanks[i].goal.speed = 1; - } else { - //myTanks[i].goal.speed = 0; - myTanks[i].missionAccomplished(); - } - } -} - -// function calculateObstacle(obstacles) { - - -// } - - - - - -/*** TANK ***/ -var Tank = function(tankNumber) { - this.tankNumber = tankNumber; - this.tankColor = selectedPlayer.playerColor; - this.position = {x: 0, y: 0}; - this.angle; - this.goal = { - speed: 0, - angleVel: 0 - }; - this.avoidObstacle = { - speed: 0, - angleVel: 0 - }; - this.target = {x: 100, y: 100}; - this.hasATarget = false; -}; - -Tank.prototype = { - getTarget: function() { - return this.target; - }, - hasTarget: function() { - return this.hasATarget; - }, - generateTarget: function() { - /* //wander between enemy bases - var randomNumber = Math.floor(Math.random() * 10 % enemyBases.length); //random num between 0 and enemyBases.length - //var randomNumber = 1; - //console.log(randomNumber, enemyBases[randomNumber].base); - this.target = enemyBases[randomNumber].base.position; - */ - - //wander between all bases - var randomNumber = Math.floor(Math.random() * 10 % allBases.length); //random num between 0 and enemyBases.length - this.target = allBases[randomNumber].base.position; - - this.hasATarget = true; - return this.target; - }, - missionAccomplished: function() { - this.hasATarget = false; - } -}; - - -//rounds number (value) to specified number of decimals -function round(value, decimals) { - return Number(Math.round(value+'e'+decimals)+'e-'+decimals); -} - - From 34542013853a9f2c23e88cbaf198ec37d1647877 Mon Sep 17 00:00:00 2001 From: Chris Shumate Date: Tue, 14 Apr 2015 17:28:17 -0600 Subject: [PATCH 2/2] setting tank.js to setup initail tankobject --- index.js | 28 ++++------------------------ tank.js | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 tank.js diff --git a/index.js b/index.js index d573f72..c34d243 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ var connect = require('./connect.js'); +var Tank = require('./tank.js'); var app = connect.connect; - +Tank = Tank.Tank; app(function(data) { var serverTanks = data.serverTanks; @@ -10,28 +11,7 @@ app(function(data) { var selectedPlayer = data.selectedPlayer; var myTanks = []; //Create base tank Object with properties - var Tank = function(tankNumber) { - this.tankNumber = tankNumber; - this.tankColor = selectedPlayer.playerColor; - this.position = { - x: 0, - y: 0 - }; - this.angle; - this.goal = { - speed: 0, - angleVel: 0 - }; - this.avoidObstacle = { - speed: 0, - angleVel: 0 - }; - this.target = { - x: 100, - y: 100 - }; - this.hasATarget = false; - }; + //extend Tank with functions Tank.prototype = { getTarget: function() { @@ -56,7 +36,7 @@ app(function(data) { //assign serverTanks to myTanks array for (var i = 0; i < serverTanks.length; i++) { - myTanks.push(new Tank(i)); + myTanks.push(new Tank(i,selectedPlayer)); } function startInterval() { diff --git a/tank.js b/tank.js new file mode 100644 index 0000000..2109389 --- /dev/null +++ b/tank.js @@ -0,0 +1,24 @@ +exports.Tank = function(tankNumber, selectedPlayer) { + this.tankNumber = tankNumber; + this.tankColor = selectedPlayer.playerColor; + this.position = { + x: 0, + y: 0 + }; + this.angle; + this.goal = { + speed: 0, + angleVel: 0 + }; + this.avoidObstacle = { + speed: 0, + angleVel: 0 + }; + this.target = { + x: 100, + y: 100 + }; + this.hasATarget = false; +} + +