Rename files
This commit is contained in:
parent
5c72a93605
commit
bb6cb3171e
14
README.md
14
README.md
@ -20,13 +20,25 @@ After cloning this repository, run the follow commands to install dependencies a
|
||||
npm start
|
||||
```
|
||||
|
||||
## Bots
|
||||
|
||||
```bash
|
||||
node src/bot/paper-io-bot-mode.js ws://localhost:8081
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
sudo npm install -g browserify uglify-es
|
||||
browserify game-client.js | uglifyjs > public/bundle.js
|
||||
browserify client.js | uglifyjs > public/bundle.js
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This is licensed under MIT. As such, please provide due credit and link back to this repository if possible.
|
||||
|
||||
Original Repo:
|
||||
|
||||
- Author: theKidOfArcrania
|
||||
|
||||
- Link: https://github.com/theKidOfArcrania/BlocklyIO
|
||||
|
@ -1,22 +0,0 @@
|
||||
function Rolling(value, frames) {
|
||||
var lag = 0;
|
||||
if (!frames) frames = 24;
|
||||
this.value = value;
|
||||
Object.defineProperty(this, "lag", {
|
||||
get: function() {
|
||||
return lag;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
this.update = function() {
|
||||
var delta = this.value - lag;
|
||||
var dir = Math.sign(delta);
|
||||
var speed = Math.abs(delta) / frames;
|
||||
var mag = Math.min(Math.abs(speed), Math.abs(delta));
|
||||
|
||||
lag += mag * dir;
|
||||
return lag;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Rolling;
|
391
client.js
391
client.js
@ -1,291 +1,100 @@
|
||||
var core = require("./game-core");
|
||||
var Player = core.Player;
|
||||
var io = require("socket.io-client");
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
var running = false;
|
||||
var user, socket, frame;
|
||||
var players, allPlayers;
|
||||
var kills;
|
||||
var timeout = undefined;
|
||||
var dirty = false;
|
||||
var deadFrames = 0;
|
||||
var requesting = -1; //frame that we are requesting at
|
||||
var frameCache = []; //Frames after our request
|
||||
var allowAnimation = true;
|
||||
var grid = new core.Grid(core.GRID_SIZE, function(row, col, before, after) {
|
||||
invokeRenderer("updateGrid", [row, col, before, after]);
|
||||
});
|
||||
|
||||
var mimiRequestAnimationFrame = window && window.document
|
||||
? window.requestAnimationFrame
|
||||
|| window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame
|
||||
|| window.oRequestAnimationFrame
|
||||
|| window.msRequestAnimationFrame
|
||||
|| function(callback) { window.setTimeout(callback, 1000 / 30) }
|
||||
: function(callback) { window.setTimeout(callback, 1000 / 30) };
|
||||
|
||||
//Public API
|
||||
function connectGame(url, name, callback) {
|
||||
if (running) return; //Prevent multiple runs
|
||||
running = true;
|
||||
user = null;
|
||||
deadFrames = 0;
|
||||
//Socket connection
|
||||
io.j = [];
|
||||
io.sockets = [];
|
||||
socket = io(url, {
|
||||
"forceNew": true,
|
||||
upgrade: false,
|
||||
transports: ["websocket"]
|
||||
});
|
||||
socket.on("connect", function() {
|
||||
console.info("Connected to server.");
|
||||
});
|
||||
socket.on("game", function(data) {
|
||||
if (timeout != undefined) clearTimeout(timeout);
|
||||
//Initialize game.
|
||||
//TODO: display data.gameid --- game id #
|
||||
frame = data.frame;
|
||||
reset();
|
||||
//Load players.
|
||||
data.players.forEach(function(p) {
|
||||
var pl = new Player(grid, p);
|
||||
addPlayer(pl);
|
||||
});
|
||||
user = allPlayers[data.num];
|
||||
if (!user) throw new Error();
|
||||
setUser(user);
|
||||
//Load grid.
|
||||
var gridData = new Uint8Array(data.grid);
|
||||
for (var r = 0; r < grid.size; r++) {
|
||||
for (var c = 0; c < grid.size; c++) {
|
||||
var ind = gridData[r * grid.size + c] - 1;
|
||||
grid.set(r, c, ind === -1 ? null : players[ind]);
|
||||
}
|
||||
}
|
||||
invokeRenderer("paint", []);
|
||||
frame = data.frame;
|
||||
if (requesting !== -1) {
|
||||
//Update those cache frames after we updated game.
|
||||
var minFrame = requesting;
|
||||
requesting = -1;
|
||||
while (frameCache.length > frame - minFrame) processFrame(frameCache[frame - minFrame]);
|
||||
frameCache = [];
|
||||
}
|
||||
});
|
||||
socket.on("notifyFrame", processFrame);
|
||||
socket.on("dead", function() {
|
||||
socket.disconnect(); //In case we didn"t get the disconnect call
|
||||
});
|
||||
socket.on("disconnect", function() {
|
||||
if (!user) return;
|
||||
console.info("Server has disconnected. Creating new game.");
|
||||
socket.disconnect();
|
||||
user.die();
|
||||
dirty = true;
|
||||
paintLoop();
|
||||
running = false;
|
||||
invokeRenderer("disconnect", []);
|
||||
});
|
||||
socket.emit("hello", {
|
||||
name: name,
|
||||
type: 0, //Free-for-all
|
||||
gameid: -1 //Requested game-id, or -1 for anyone
|
||||
}, function(success, msg) {
|
||||
if (success) console.info("Connected to game!");
|
||||
else {
|
||||
console.error("Unable to connect to game: " + msg);
|
||||
running = false;
|
||||
}
|
||||
if (callback) callback(success, msg);
|
||||
});
|
||||
}
|
||||
|
||||
function changeHeading(newHeading) {
|
||||
if (!user || user.dead) return;
|
||||
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^ (user.currentHeading % 2 === 0))) {
|
||||
//user.heading = newHeading;
|
||||
if (socket) {
|
||||
socket.emit("frame", {
|
||||
frame: frame,
|
||||
heading: newHeading
|
||||
}, function(success, msg) {
|
||||
if (!success) console.error(msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
function getOthers() {
|
||||
var ret = [];
|
||||
for (var p of players) {
|
||||
if (p !== user) ret.push(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getPlayers() {
|
||||
return players.slice();
|
||||
}
|
||||
//Private API
|
||||
function addPlayer(player) {
|
||||
if (allPlayers[player.num]) return; //Already added
|
||||
allPlayers[player.num] = players[players.length] = player;
|
||||
invokeRenderer("addPlayer", [player]);
|
||||
return players.length - 1;
|
||||
}
|
||||
|
||||
function invokeRenderer(name, args) {
|
||||
var renderer = exports.renderer;
|
||||
if (renderer && typeof renderer[name] === "function") renderer[name].apply(exports, args);
|
||||
}
|
||||
|
||||
function processFrame(data) {
|
||||
if (timeout != undefined) clearTimeout(timeout);
|
||||
if (requesting !== -1 && requesting < data.frame) {
|
||||
frameCache.push(data);
|
||||
return;
|
||||
}
|
||||
if (data.frame - 1 !== frame) {
|
||||
console.error("Frames don\"t match up!");
|
||||
socket.emit("requestFrame"); //Restore data
|
||||
requesting = data.frame;
|
||||
frameCache.push(data);
|
||||
return;
|
||||
}
|
||||
frame++;
|
||||
if (data.newPlayers) {
|
||||
data.newPlayers.forEach(function(p) {
|
||||
if (p.num === user.num) return;
|
||||
var pl = new Player(grid, p);
|
||||
addPlayer(pl);
|
||||
core.initPlayer(grid, pl);
|
||||
});
|
||||
}
|
||||
var found = new Array(players.length);
|
||||
data.moves.forEach(function(val, i) {
|
||||
var player = allPlayers[val.num];
|
||||
if (!player) return;
|
||||
if (val.left) player.die();
|
||||
found[i] = true;
|
||||
player.heading = val.heading;
|
||||
});
|
||||
for (var i = 0; i < players.length; i++) {
|
||||
//Implicitly leaving game
|
||||
if (!found[i]) {
|
||||
var player = players[i];
|
||||
player && player.die();
|
||||
}
|
||||
}
|
||||
update();
|
||||
var locs = {};
|
||||
for (var i = 0; i < players.length; i++) {
|
||||
var p = players[i];
|
||||
locs[p.num] = [p.posX, p.posY, p.waitLag];
|
||||
}
|
||||
/*
|
||||
socket.emit("verify", {
|
||||
frame: frame,
|
||||
locs: locs
|
||||
}, function(frame, success, adviceFix, msg) {
|
||||
if (!success && requesting === -1) {
|
||||
console.error(frame + ": " + msg);
|
||||
if (adviceFix) socket.emit("requestFrame");
|
||||
}
|
||||
}.bind(this, frame));
|
||||
*/
|
||||
dirty = true;
|
||||
mimiRequestAnimationFrame(function() {
|
||||
paintLoop();
|
||||
});
|
||||
timeout = setTimeout(function() {
|
||||
console.warn("Server has timed-out. Disconnecting.");
|
||||
socket.disconnect();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function paintLoop() {
|
||||
if (!dirty) return;
|
||||
invokeRenderer("paint", []);
|
||||
dirty = false;
|
||||
if (user && user.dead) {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
if (deadFrames === 60) { //One second of frame
|
||||
var before = allowAnimation;
|
||||
allowAnimation = false;
|
||||
update();
|
||||
invokeRenderer("paint", []);
|
||||
allowAnimation = before;
|
||||
user = null;
|
||||
deadFrames = 0;
|
||||
return;
|
||||
}
|
||||
socket.disconnect();
|
||||
deadFrames++;
|
||||
dirty = true;
|
||||
update();
|
||||
mimiRequestAnimationFrame(paintLoop);
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
user = null;
|
||||
grid.reset();
|
||||
players = [];
|
||||
allPlayers = [];
|
||||
kills = 0;
|
||||
invokeRenderer("reset");
|
||||
}
|
||||
|
||||
function setUser(player) {
|
||||
user = player;
|
||||
invokeRenderer("setUser", [player]);
|
||||
}
|
||||
|
||||
function update() {
|
||||
var dead = [];
|
||||
core.updateFrame(grid, players, dead, function addKill(killer, other) {
|
||||
if (players[killer] === user && killer !== other) kills++;
|
||||
});
|
||||
dead.forEach(function(val) {
|
||||
console.log((val.name || "Unnamed") + " is dead");
|
||||
delete allPlayers[val.num];
|
||||
invokeRenderer("removePlayer", [val]);
|
||||
});
|
||||
invokeRenderer("update", [frame]);
|
||||
}
|
||||
//Export stuff
|
||||
var funcs = [connectGame, changeHeading, getOthers, getPlayers, getUser];
|
||||
funcs.forEach(function(f) {
|
||||
exports[f.name] = f;
|
||||
});
|
||||
exports.renderer = null;
|
||||
Object.defineProperties(exports, {
|
||||
allowAnimation: {
|
||||
get: function() {
|
||||
return allowAnimation;
|
||||
},
|
||||
set: function(val) {
|
||||
allowAnimation = !!val;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
grid: {
|
||||
get: function() {
|
||||
return grid;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
kills: {
|
||||
get: function() {
|
||||
return kills;
|
||||
},
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
/* global $ */
|
||||
|
||||
var io = require("socket.io-client");
|
||||
var client = require("./src/game-client");
|
||||
client.allowAnimation = true;
|
||||
client.renderer = require("./src/user-mode");
|
||||
var core = require("./src/core");
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
|
||||
var mimiRequestAnimationFrame = window.requestAnimationFrame
|
||||
|| window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame
|
||||
|| window.oRequestAnimationFrame
|
||||
|| window.msRequestAnimationFrame
|
||||
|| function(callback) { window.setTimeout(callback, 1000 / 30) };
|
||||
|
||||
function run() {
|
||||
var names = "Alice Bob Carol Dave Eve Francis Grace Hans Isabella Jason Kate Louis Margaret Nathan Olivia Paul Queen Richard Susan Thomas Uma Vivian Winnie Xander Yasmine Zach".split(" ");
|
||||
var prefix = "Angry Baby Crazy Diligent Excited Fat Greedy Hungry Interesting Japanese Kind Little Magic Naïve Old Powerful Quiet Rich Superman THU Undefined Valuable Wifeless Xiangbuchulai Young Zombie".split(" ");
|
||||
var name = $("#name").val() || [prefix[Math.floor(Math.random() * prefix.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
|
||||
$("#name").val(name);
|
||||
client.connectGame("//" + window.location.hostname + ":8081", name, function(success, msg) {
|
||||
if (success) {
|
||||
$("#begin").fadeOut(1000);
|
||||
$("#main-ui").fadeIn(1000);
|
||||
}
|
||||
else {
|
||||
var error = $("#error");
|
||||
error.text(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
var error = $("#error");
|
||||
if (!window.WebSocket) {
|
||||
error.text("Your browser does not support WebSockets!");
|
||||
return;
|
||||
}
|
||||
error.text("Loading... Please wait"); //TODO: show loading screen
|
||||
var socket = io("//" + window.location.hostname + ":8081", {
|
||||
forceNew: true,
|
||||
upgrade: false,
|
||||
transports: ["websocket"]
|
||||
});
|
||||
socket.on("connect", function() {
|
||||
socket.emit("pings");
|
||||
});
|
||||
socket.on("pongs", function() {
|
||||
socket.disconnect();
|
||||
error.text("All done, have fun!");
|
||||
$("#name").keypress(function(evt) {
|
||||
if (evt.which === 13) mimiRequestAnimationFrame(run);
|
||||
});
|
||||
$("#start").removeAttr("disabled").click(function(evt) {
|
||||
mimiRequestAnimationFrame(run);
|
||||
});
|
||||
});
|
||||
socket.on("connect_error", function() {
|
||||
error.text("Cannot connect with server. This probably is due to misconfigured proxy server. (Try using a different browser)");
|
||||
});
|
||||
});
|
||||
//Event listeners
|
||||
$(document).keydown(function(e) {
|
||||
var newHeading = -1;
|
||||
switch (e.which) {
|
||||
case 38: newHeading = 0; break; //UP
|
||||
case 87: newHeading = 0; break; //UP (W)
|
||||
case 39: newHeading = 1; break; //RIGHT
|
||||
case 68: newHeading = 1; break; //RIGHT (D)
|
||||
case 40: newHeading = 2; break; //DOWN
|
||||
case 83: newHeading = 2; break; //DOWN (S)
|
||||
case 37: newHeading = 3; break; //LEFT
|
||||
case 65: newHeading = 3; break; //LEFT (A)
|
||||
default: return; //Exit handler for other keys
|
||||
}
|
||||
client.changeHeading(newHeading);
|
||||
//e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).on("touchmove", function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).on("touchstart", function (e1) {
|
||||
var x1 = e1.targetTouches[0].pageX;
|
||||
var y1 = e1.targetTouches[0].pageY;
|
||||
$(document).one("touchend", function (e2) {
|
||||
var x2 = e2.changedTouches[0].pageX;
|
||||
var y2 = e2.changedTouches[0].pageY;
|
||||
var deltaX = x2 - x1;
|
||||
var deltaY = y2 - y1;
|
||||
var newHeading = -1;
|
||||
if (deltaY < 0 && Math.abs(deltaY) > Math.abs(deltaX)) newHeading = 0;
|
||||
else if (deltaX > 0 && Math.abs(deltaY) < deltaX) newHeading = 1;
|
||||
else if (deltaY > 0 && Math.abs(deltaX) < deltaY) newHeading = 2;
|
||||
else if (deltaX < 0 && Math.abs(deltaX) > Math.abs(deltaY)) newHeading = 3;
|
||||
client.changeHeading(newHeading);
|
||||
});
|
||||
});
|
||||
|
102
game-client.js
102
game-client.js
@ -1,102 +0,0 @@
|
||||
/* global $ */
|
||||
|
||||
var client = require("./client");
|
||||
var core = require("./game-core");
|
||||
var io = require("socket.io-client");
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
client.allowAnimation = true;
|
||||
client.renderer = require("./client-modes/user-mode");
|
||||
|
||||
var mimiRequestAnimationFrame = window && window.document
|
||||
? window.requestAnimationFrame
|
||||
|| window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame
|
||||
|| window.oRequestAnimationFrame
|
||||
|| window.msRequestAnimationFrame
|
||||
|| function(callback) { window.setTimeout(callback, 1000 / 30) }
|
||||
: function(callback) { window.setTimeout(callback, 1000 / 30) };
|
||||
|
||||
function run() {
|
||||
var names = "Alice Bob Carol Dave Eve Francis Grace Hans Isabella Jason Kate Louis Margaret Nathan Olivia Paul Queen Richard Susan Thomas Uma Vivian Winnie Xander Yasmine Zach".split(" ");
|
||||
var prefix = "Angry Baby Crazy Diligent Excited Fat Greedy Hungry Interesting Japanese Kind Little Magic Naïve Old Powerful Quiet Rich Superman THU Undefined Valuable Wifeless Xiangbuchulai Young Zombie".split(" ");
|
||||
var name = $("#name").val() || [prefix[Math.floor(Math.random() * prefix.length)], names[Math.floor(Math.random() * names.length)]].join(" ");
|
||||
$("#name").val(name);
|
||||
client.connectGame("//" + window.location.hostname + ":8081", name, function(success, msg) {
|
||||
if (success) {
|
||||
$("#begin").fadeOut(1000);
|
||||
$("#main-ui").fadeIn(1000);
|
||||
}
|
||||
else {
|
||||
var error = $("#error");
|
||||
error.text(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
var error = $("#error");
|
||||
if (!window.WebSocket) {
|
||||
error.text("Your browser does not support WebSockets!");
|
||||
return;
|
||||
}
|
||||
error.text("Loading... Please wait"); //TODO: show loading screen
|
||||
var socket = io("//" + window.location.hostname + ":8081", {
|
||||
forceNew: true,
|
||||
upgrade: false,
|
||||
transports: ["websocket"]
|
||||
});
|
||||
socket.on("connect", function() {
|
||||
socket.emit("pings");
|
||||
});
|
||||
socket.on("pongs", function() {
|
||||
socket.disconnect();
|
||||
error.text("All done, have fun!");
|
||||
$("#name").keypress(function(evt) {
|
||||
if (evt.which === 13) mimiRequestAnimationFrame(run);
|
||||
});
|
||||
$("#start").removeAttr("disabled").click(function(evt) {
|
||||
mimiRequestAnimationFrame(run);
|
||||
});
|
||||
});
|
||||
socket.on("connect_error", function() {
|
||||
error.text("Cannot connect with server. This probably is due to misconfigured proxy server. (Try using a different browser)");
|
||||
});
|
||||
});
|
||||
//Event listeners
|
||||
$(document).keydown(function(e) {
|
||||
var newHeading = -1;
|
||||
switch (e.which) {
|
||||
case 38: newHeading = 0; break; //UP
|
||||
case 87: newHeading = 0; break; //UP (W)
|
||||
case 39: newHeading = 1; break; //RIGHT
|
||||
case 68: newHeading = 1; break; //RIGHT (D)
|
||||
case 40: newHeading = 2; break; //DOWN
|
||||
case 83: newHeading = 2; break; //DOWN (S)
|
||||
case 37: newHeading = 3; break; //LEFT
|
||||
case 65: newHeading = 3; break; //LEFT (A)
|
||||
default: return; //Exit handler for other keys
|
||||
}
|
||||
client.changeHeading(newHeading);
|
||||
//e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).on("touchmove", function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$(document).on("touchstart", function (e1) {
|
||||
var x1 = e1.targetTouches[0].pageX;
|
||||
var y1 = e1.targetTouches[0].pageY;
|
||||
$(document).one("touchend", function (e2) {
|
||||
var x2 = e2.changedTouches[0].pageX;
|
||||
var y2 = e2.changedTouches[0].pageY;
|
||||
var deltaX = x2 - x1;
|
||||
var deltaY = y2 - y1;
|
||||
var newHeading = -1;
|
||||
if (deltaY < 0 && Math.abs(deltaY) > Math.abs(deltaX)) newHeading = 0;
|
||||
else if (deltaX > 0 && Math.abs(deltaY) < deltaX) newHeading = 1;
|
||||
else if (deltaY > 0 && Math.abs(deltaX) < deltaY) newHeading = 2;
|
||||
else if (deltaX < 0 && Math.abs(deltaX) > Math.abs(deltaY)) newHeading = 3;
|
||||
client.changeHeading(newHeading);
|
||||
});
|
||||
});
|
File diff suppressed because one or more lines are too long
@ -18,9 +18,10 @@ var server = http.createServer(function onRequest(req, res) {
|
||||
// Listen
|
||||
server.listen(port, hostname);
|
||||
server = http.createServer();
|
||||
|
||||
var io = require("socket.io")(server);
|
||||
io.set("transports", ["websocket"]);
|
||||
var Game = require("./game-server.js");
|
||||
var Game = require("./src/game-server.js");
|
||||
var games = [new Game()];
|
||||
io.on("connection", function(socket) {
|
||||
socket.on("hello", function(data, fn) {
|
||||
|
@ -1,20 +1,15 @@
|
||||
if (process.argv.length < 3) {
|
||||
console.log("Usage: node game-client-bot.js <socket-url> [<name>]")
|
||||
console.log("Usage: node bot-mode.js <socket-url> [<name>]")
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var oldlog = console.log;
|
||||
console.log = function(msg) {
|
||||
return oldlog(`[${new Date()}] ${msg}`);
|
||||
}
|
||||
|
||||
//TODO: add a land claiming algo (with coefficient parameters)
|
||||
//TODO: add weight to the max land area and last land area, and also the number
|
||||
//of kills
|
||||
//TODO: genetic gene pooling
|
||||
|
||||
var core = require("../game-core");
|
||||
var client = require("../client");
|
||||
var core = require("../core");
|
||||
var client = require("../game-client");
|
||||
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
@ -26,7 +21,7 @@ var THRESHOLD = 10;
|
||||
var startFrame = -1;
|
||||
var endFrame = -1;
|
||||
var coeffs = [0.6164220147940495, -2.519369747858328, 0.9198978109542851, -1.2158956330674564, -3.072901620397528, 5, 4];
|
||||
var grid, others, user, playerPortion;
|
||||
var grid, others, user, playerPortion = {};
|
||||
var DIST_TYPES = {
|
||||
land: {
|
||||
check: function(loc) {
|
||||
@ -64,6 +59,10 @@ var DIST_TYPES = {
|
||||
}
|
||||
};
|
||||
|
||||
function log(msg) {
|
||||
return console.log(`[${new Date()}] ${msg}`);
|
||||
}
|
||||
|
||||
function generateLandDirections() {
|
||||
function mod(x) {
|
||||
x %= 4;
|
||||
@ -188,7 +187,7 @@ function printGrid() {
|
||||
str += chars.get(r, c);
|
||||
}
|
||||
}
|
||||
console.log(str);
|
||||
log(str);
|
||||
}
|
||||
|
||||
function update(frame) {
|
||||
@ -211,7 +210,7 @@ function update(frame) {
|
||||
weight += point;
|
||||
str += distType + ": " + point + ", ";
|
||||
}
|
||||
//console.log(str);
|
||||
//log(str);
|
||||
weights[d] = weight;
|
||||
}
|
||||
|
||||
@ -232,7 +231,7 @@ function update(frame) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
//console.log(weights)
|
||||
//log(weights)
|
||||
//Choose a random direction from the weighted list
|
||||
var choice = Math.random() * total;
|
||||
var d = 0;
|
||||
@ -255,9 +254,9 @@ client.renderer = {
|
||||
disconnect: function() {
|
||||
var dt = (endFrame - startFrame);
|
||||
startFrame = -1;
|
||||
console.log("I died... (survived for " + dt + " frames.)");
|
||||
console.log("I killed " + client.kills + " player(s).");
|
||||
console.log("Coefficients: " + coeffs);
|
||||
log("I died... (survived for " + dt + " frames.)");
|
||||
log("I killed " + client.kills + " player(s).");
|
||||
log("Coefficients: " + coeffs);
|
||||
|
||||
var mutation = Math.min(10, Math.pow(2, calcFavorability(params)));
|
||||
for (var i = 0; i < coeffs.length; i++) {
|
@ -1,15 +1,10 @@
|
||||
if (process.argv.length < 3) {
|
||||
console.log("Usage: node game-client-bot.js <socket-url> [<name>]")
|
||||
console.log("Usage: node paper-io-bot-mode.js <socket-url> [<name>]")
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var oldlog = console.log;
|
||||
console.log = function(msg) {
|
||||
return oldlog(`[${new Date()}] ${msg}`);
|
||||
}
|
||||
|
||||
var core = require("../game-core");
|
||||
var client = require("../client");
|
||||
var core = require("../core");
|
||||
var client = require("../game-client");
|
||||
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
@ -19,6 +14,10 @@ var startFrame = -1;
|
||||
var endFrame = -1;
|
||||
var grid, others, user, playerPortion = {}, claim = [];
|
||||
|
||||
function log(msg) {
|
||||
return console.log(`[${new Date()}] ${msg}`);
|
||||
}
|
||||
|
||||
function mod(x) {
|
||||
x %= 4;
|
||||
if (x < 0) x += 4;
|
||||
@ -189,8 +188,8 @@ client.renderer = {
|
||||
var dt = (endFrame - startFrame);
|
||||
startFrame = -1;
|
||||
|
||||
console.log("I died... (survived for " + dt + " frames.)");
|
||||
console.log("I killed " + client.kills + " player(s).");
|
||||
log("I died... (survived for " + dt + " frames.)");
|
||||
log("I killed " + client.kills + " player(s).");
|
||||
connect();
|
||||
},
|
||||
removePlayer: function(player) {
|
@ -1,4 +1,4 @@
|
||||
var core = require("./game-core");
|
||||
var core = require("./core");
|
||||
var consts = require("./game-consts");
|
||||
|
||||
exports.Color = require("./color");
|
296
src/game-client.js
Normal file
296
src/game-client.js
Normal file
@ -0,0 +1,296 @@
|
||||
var io = require("socket.io-client");
|
||||
var core = require("./core");
|
||||
var Player = core.Player;
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
var running = false;
|
||||
var user, socket, frame;
|
||||
var players, allPlayers;
|
||||
var kills;
|
||||
var timeout = undefined;
|
||||
var dirty = false;
|
||||
var deadFrames = 0;
|
||||
var requesting = -1; //frame that we are requesting at
|
||||
var frameCache = []; //Frames after our request
|
||||
var allowAnimation = true;
|
||||
var grid = new core.Grid(core.GRID_SIZE, function(row, col, before, after) {
|
||||
invokeRenderer("updateGrid", [row, col, before, after]);
|
||||
});
|
||||
|
||||
var mimiRequestAnimationFrame;
|
||||
|
||||
try {
|
||||
if (window && window.document) {
|
||||
mimiRequestAnimationFrame = window.requestAnimationFrame
|
||||
|| window.webkitRequestAnimationFrame
|
||||
|| window.mozRequestAnimationFrame
|
||||
|| window.oRequestAnimationFrame
|
||||
|| window.msRequestAnimationFrame
|
||||
|| function(callback) { window.setTimeout(callback, 1000 / 30) };
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
mimiRequestAnimationFrame = function(callback) { setTimeout(callback, 1000 / 30) };
|
||||
}
|
||||
|
||||
//Public API
|
||||
function connectGame(url, name, callback) {
|
||||
if (running) return; //Prevent multiple runs
|
||||
running = true;
|
||||
user = null;
|
||||
deadFrames = 0;
|
||||
//Socket connection
|
||||
io.j = [];
|
||||
io.sockets = [];
|
||||
socket = io(url, {
|
||||
"forceNew": true,
|
||||
upgrade: false,
|
||||
transports: ["websocket"]
|
||||
});
|
||||
socket.on("connect", function() {
|
||||
console.info("Connected to server.");
|
||||
});
|
||||
socket.on("game", function(data) {
|
||||
if (timeout != undefined) clearTimeout(timeout);
|
||||
//Initialize game.
|
||||
//TODO: display data.gameid --- game id #
|
||||
frame = data.frame;
|
||||
reset();
|
||||
//Load players.
|
||||
data.players.forEach(function(p) {
|
||||
var pl = new Player(grid, p);
|
||||
addPlayer(pl);
|
||||
});
|
||||
user = allPlayers[data.num];
|
||||
if (!user) throw new Error();
|
||||
setUser(user);
|
||||
//Load grid.
|
||||
var gridData = new Uint8Array(data.grid);
|
||||
for (var r = 0; r < grid.size; r++) {
|
||||
for (var c = 0; c < grid.size; c++) {
|
||||
var ind = gridData[r * grid.size + c] - 1;
|
||||
grid.set(r, c, ind === -1 ? null : players[ind]);
|
||||
}
|
||||
}
|
||||
invokeRenderer("paint", []);
|
||||
frame = data.frame;
|
||||
if (requesting !== -1) {
|
||||
//Update those cache frames after we updated game.
|
||||
var minFrame = requesting;
|
||||
requesting = -1;
|
||||
while (frameCache.length > frame - minFrame) processFrame(frameCache[frame - minFrame]);
|
||||
frameCache = [];
|
||||
}
|
||||
});
|
||||
socket.on("notifyFrame", processFrame);
|
||||
socket.on("dead", function() {
|
||||
socket.disconnect(); //In case we didn"t get the disconnect call
|
||||
});
|
||||
socket.on("disconnect", function() {
|
||||
if (!user) return;
|
||||
console.info("Server has disconnected. Creating new game.");
|
||||
socket.disconnect();
|
||||
user.die();
|
||||
dirty = true;
|
||||
paintLoop();
|
||||
running = false;
|
||||
invokeRenderer("disconnect", []);
|
||||
});
|
||||
socket.emit("hello", {
|
||||
name: name,
|
||||
type: 0, //Free-for-all
|
||||
gameid: -1 //Requested game-id, or -1 for anyone
|
||||
}, function(success, msg) {
|
||||
if (success) console.info("Connected to game!");
|
||||
else {
|
||||
console.error("Unable to connect to game: " + msg);
|
||||
running = false;
|
||||
}
|
||||
if (callback) callback(success, msg);
|
||||
});
|
||||
}
|
||||
|
||||
function changeHeading(newHeading) {
|
||||
if (!user || user.dead) return;
|
||||
if (newHeading === user.currentHeading || ((newHeading % 2 === 0) ^ (user.currentHeading % 2 === 0))) {
|
||||
//user.heading = newHeading;
|
||||
if (socket) {
|
||||
socket.emit("frame", {
|
||||
frame: frame,
|
||||
heading: newHeading
|
||||
}, function(success, msg) {
|
||||
if (!success) console.error(msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
function getOthers() {
|
||||
var ret = [];
|
||||
for (var p of players) {
|
||||
if (p !== user) ret.push(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getPlayers() {
|
||||
return players.slice();
|
||||
}
|
||||
//Private API
|
||||
function addPlayer(player) {
|
||||
if (allPlayers[player.num]) return; //Already added
|
||||
allPlayers[player.num] = players[players.length] = player;
|
||||
invokeRenderer("addPlayer", [player]);
|
||||
return players.length - 1;
|
||||
}
|
||||
|
||||
function invokeRenderer(name, args) {
|
||||
var renderer = exports.renderer;
|
||||
if (renderer && typeof renderer[name] === "function") renderer[name].apply(exports, args);
|
||||
}
|
||||
|
||||
function processFrame(data) {
|
||||
if (timeout != undefined) clearTimeout(timeout);
|
||||
if (requesting !== -1 && requesting < data.frame) {
|
||||
frameCache.push(data);
|
||||
return;
|
||||
}
|
||||
if (data.frame - 1 !== frame) {
|
||||
console.error("Frames don\"t match up!");
|
||||
socket.emit("requestFrame"); //Restore data
|
||||
requesting = data.frame;
|
||||
frameCache.push(data);
|
||||
return;
|
||||
}
|
||||
frame++;
|
||||
if (data.newPlayers) {
|
||||
data.newPlayers.forEach(function(p) {
|
||||
if (p.num === user.num) return;
|
||||
var pl = new Player(grid, p);
|
||||
addPlayer(pl);
|
||||
core.initPlayer(grid, pl);
|
||||
});
|
||||
}
|
||||
var found = new Array(players.length);
|
||||
data.moves.forEach(function(val, i) {
|
||||
var player = allPlayers[val.num];
|
||||
if (!player) return;
|
||||
if (val.left) player.die();
|
||||
found[i] = true;
|
||||
player.heading = val.heading;
|
||||
});
|
||||
for (var i = 0; i < players.length; i++) {
|
||||
//Implicitly leaving game
|
||||
if (!found[i]) {
|
||||
var player = players[i];
|
||||
player && player.die();
|
||||
}
|
||||
}
|
||||
update();
|
||||
var locs = {};
|
||||
for (var i = 0; i < players.length; i++) {
|
||||
var p = players[i];
|
||||
locs[p.num] = [p.posX, p.posY, p.waitLag];
|
||||
}
|
||||
/*
|
||||
socket.emit("verify", {
|
||||
frame: frame,
|
||||
locs: locs
|
||||
}, function(frame, success, adviceFix, msg) {
|
||||
if (!success && requesting === -1) {
|
||||
console.error(frame + ": " + msg);
|
||||
if (adviceFix) socket.emit("requestFrame");
|
||||
}
|
||||
}.bind(this, frame));
|
||||
*/
|
||||
dirty = true;
|
||||
mimiRequestAnimationFrame(paintLoop);
|
||||
timeout = setTimeout(function() {
|
||||
console.warn("Server has timed-out. Disconnecting.");
|
||||
socket.disconnect();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function paintLoop() {
|
||||
if (!dirty) return;
|
||||
invokeRenderer("paint", []);
|
||||
dirty = false;
|
||||
if (user && user.dead) {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
if (deadFrames === 60) { //One second of frame
|
||||
var before = allowAnimation;
|
||||
allowAnimation = false;
|
||||
update();
|
||||
invokeRenderer("paint", []);
|
||||
allowAnimation = before;
|
||||
user = null;
|
||||
deadFrames = 0;
|
||||
return;
|
||||
}
|
||||
socket.disconnect();
|
||||
deadFrames++;
|
||||
dirty = true;
|
||||
update();
|
||||
mimiRequestAnimationFrame(paintLoop);
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
user = null;
|
||||
grid.reset();
|
||||
players = [];
|
||||
allPlayers = [];
|
||||
kills = 0;
|
||||
invokeRenderer("reset");
|
||||
}
|
||||
|
||||
function setUser(player) {
|
||||
user = player;
|
||||
invokeRenderer("setUser", [player]);
|
||||
}
|
||||
|
||||
function update() {
|
||||
var dead = [];
|
||||
core.updateFrame(grid, players, dead, function addKill(killer, other) {
|
||||
if (players[killer] === user && killer !== other) kills++;
|
||||
});
|
||||
dead.forEach(function(val) {
|
||||
console.log((val.name || "Unnamed") + " is dead");
|
||||
delete allPlayers[val.num];
|
||||
invokeRenderer("removePlayer", [val]);
|
||||
});
|
||||
invokeRenderer("update", [frame]);
|
||||
}
|
||||
//Export stuff
|
||||
var funcs = [connectGame, changeHeading, getOthers, getPlayers, getUser];
|
||||
funcs.forEach(function(f) {
|
||||
exports[f.name] = f;
|
||||
});
|
||||
exports.renderer = null;
|
||||
Object.defineProperties(exports, {
|
||||
allowAnimation: {
|
||||
get: function() {
|
||||
return allowAnimation;
|
||||
},
|
||||
set: function(val) {
|
||||
allowAnimation = !!val;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
grid: {
|
||||
get: function() {
|
||||
return grid;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
kills: {
|
||||
get: function() {
|
||||
return kills;
|
||||
},
|
||||
enumerable: true
|
||||
}
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
var core = require("./game-core");
|
||||
var core = require("./core");
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
var MAX_PLAYERS = core.MAX_PLAYERS;
|
@ -1,8 +1,7 @@
|
||||
/* global $ */
|
||||
|
||||
var core = require("../game-core");
|
||||
var client = require("../client");
|
||||
var Rolling = require("./rolling");
|
||||
var core = require("./core");
|
||||
var client = require("./game-client");
|
||||
|
||||
var GRID_SIZE = core.GRID_SIZE;
|
||||
var CELL_WIDTH = core.CELL_WIDTH;
|
||||
@ -320,6 +319,27 @@ function getBounceOffset(frame) {
|
||||
}
|
||||
}
|
||||
|
||||
function Rolling(value, frames) {
|
||||
var lag = 0;
|
||||
if (!frames) frames = 24;
|
||||
this.value = value;
|
||||
Object.defineProperty(this, "lag", {
|
||||
get: function() {
|
||||
return lag;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
this.update = function() {
|
||||
var delta = this.value - lag;
|
||||
var dir = Math.sign(delta);
|
||||
var speed = Math.abs(delta) / frames;
|
||||
var mag = Math.min(Math.abs(speed), Math.abs(delta));
|
||||
|
||||
lag += mag * dir;
|
||||
return lag;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = {
|
||||
addPlayer: function(player) {
|
||||
playerPortion[player.num] = 0;
|
Loading…
Reference in New Issue
Block a user