/server/collisions.js~
/server/matrix.js~
/web/input.js~
+/server/health.js~
+/server/robot.js~
FPS: 1000/mspf,
WAIT_TIME: 60000, // 1 minute
MAX_GAMES: 5, // the most games allowed to go on at once, to be tweaked as needed for purposes
+ ROBO_TIME: 120, // time in seconds before filling out with robots
// gamestate
DYING_TIME_IN_FRAMES: 100,
BOARD_RADIUS: 10,
const GameState = require('./gamestate.js');
+const health = require('./health.js');
+
function Game(players) {
this.players = players;
for(var i=0; i<players.length; i++) {
state.id = 0;
for(var i=0; i<this.players.length;i++) {
state.id = i;
- this.players[i].send_data(JSON.stringify(state));
+ this.players[i].send_data(state);
}
// check for life and death
if(dead_ids.length == state.n-1) {
// game over! tell everyone and end the cycle
clearInterval(this.timeout);
+ health.dec();
var sum = dead_ids.reduce((x,y) => x+y);
var winner = state.n*(state.n-1)/2 - sum; // note the minus is bc we start at zero yeah?
for(var i=0; i<this.players.length;i++) {
var tosend = (i==winner) ? 'w' : 'l';
this.players[i].send_data(tosend); // w for winner, l for loser cuz why not?
+ this.players[i].close();
}
}
}
--- /dev/null
+
+const c = require('./constants.js');
+
+var Health = function() {
+ this.game_count = 0;
+}
+
+Health.prototype.inc = function() {
+ this.game_count++;
+}
+Health.prototype.dec = function() {
+ this.game_count--;
+}
+Health.prototype.isOK = function() {
+ return this.game_count >= c.MAX_GAMES;
+}
+
+// testing shows this probably does what I want it to do
+module.exports = new Health();
-const c = require('./constants.js')
+const c = require('./constants.js');
+
+const health = require('./health.js');
const WebSocket = require('ws');
const Player = require('./player.js');
const Game = require('./game.js');
-players = [];
+const Robot = require('./robot.js');
+
+var players = [];
-timeout = null;
+var timeout = null; // for adding robots timer
var manage_incoming = function(ws) {
+ // health check, closes off everything
+ if(health.isOK()) {
+ if(ws.readyState == ws.OPEN) {
+ ws.send("busy");
+ }
+ ws.close(1013,"busy");
+ return;
+ }
+
var new_player = new Player(ws);
players.push(new_player);
if(players.length >= c.NUM_PLAYERS) {
game = new Game(players.slice(0, c.NUM_PLAYERS));
+ health.inc();
game.start(c.MS_PER_FRAME);
- players = players.slice(c.NUM_PLAYERS);
+ players = players.slice(c.NUM_PLAYERS); // just security in case >n connections at once
+ // i think js lack-of-threading makes it impossible for that to happen though
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ else if(timeout == null) {
+ setTimeout(robot_adder, c.ROBO_TIME);
+ }
+}
+
+// okay, in this space, i wanna have the code to check for adding robots and stuff
+var robot_adder = function() {
+ while(players.length < c.NUM_PLAYERS) {
+ players.push(new Robot());
}
+ game = new Game(players.slice()); // array copy
+ health.inc();
+ game.start(c.MS_PER_FRAME);
+ players = [];
}
+//
wss.on('connection', manage_incoming);
function Player(ws) {
this.status = 'x';
this.socket = ws;
- this.id = -1; // id just used for keeping track of deaths and whatnot
+ this.id = -1; // is this used? can i just delete?
var _this = this;
var fn = function(msg) {
_this.listener(msg);
}
Player.prototype.send_data = function(data) {
+ if((typeof data) == 'string')
+ var tosend = data;
+ else
+ var tosend = JSON.stringify(data);
if(this.socket.readyState==this.socket.OPEN) {
- this.socket.send(data);
+ this.socket.send(tosend);
}
}
return stat;
}
+Player.prototype.close = function() {
+ this.socket.close(1000);
+}
module.exports = Player;
--- /dev/null
+
+const c = require('./constants.js');
+
+const Coord = require('./coord.js');
+const field = require('./field.js');
+
+function Robot() {
+ this.status = 'x';
+}
+
+Robot.prototype.close = function() {
+ return;
+}
+
+Robot.prototype.get_status = function() {
+ var stat = this.status;
+ this.status = 'x';
+ return stat;
+}
+
+Robot.prototype.send_data = function(data) {
+ this.standard_ai(data);
+}
+
+Robot.prototype.random_ai = function(data) {
+ // just a random-behaving ai. not pretty
+ this.status = Math.random()>0.5 ? 'u' : 'd';
+}
+Robot.prototype.standard_ai = function(data) {
+ if(typeof data == "string")
+ return;
+ if(data.balls.length == 0)
+ return;
+ // this is where ALL the work needs to get done
+ // i will start with a fairly naive approach, where i just move the paddle to the ball nearest to the region
+ var me = data.id;
+ var eps = field.genAllEndpoints(data.n, data.dead);
+ var my_ep = eps.find(x => x.id == me);
+ if(typeof my_ep == 'undefined') {
+ this.status = 'x';
+ return;
+ }
+ // recall that i strip out superfluous data... this is kinda tricky, just be careful
+ var center = midpoint(my_ep.f, my_ep.s);
+ var nearest = data.balls[0];
+ var bdist2 = center.dist2(nearest);
+ for(var ball of data.balls) {
+ var newdist = center.dist2(ball);
+ if(newdist < bdist2) {
+ nearest = ball;
+ bdist2 = newdist;
+ }
+ }
+ // k now i've got the nearest... just move it in the direction of the nearest endpoint, yeah? yeah!
+ // because the endpoints are given in increasing radians! Just have to do a check that
+ if(nearest.dist2(my_ep.f) > nearest.dist2(my_ep.s)) {
+ // double check which of 'u' or 'd' makes more sense, i think as is is probably fine but...
+ this.status = 'u';
+ }
+ else {
+ this.status = 'd';
+ }
+}
+
+var midpoint = function(a,b) {
+ return new Coord((a.x+b.x/2), (a.y+b.y)/2);
+}
+
+
+module.exports = Robot;
ctx.lineWidth = ctx.lineWidth/5;
- // this is just to have everything go easily for testing
- var othersockets = [];
- for(var i=0; i<c.NUM_PLAYERS -1; i++) {
- othersockets.push(new WebSocket(prefixurl));
- }
-
theSocket = new WebSocket(prefixurl);
theSocket.onmessage = function(e) {
+ if(e.data == "busy") {
+ onBusy();
+ return;
+ }
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// change the 1's to zoom in i think.. todo
theSocket.onclose = function(e) {clearInterval(interval)};
}
+var onBusy = function() {
+ console.log("busy, try again later");
+}
window.addEventListener("DOMContentLoaded", e => main());