Skip to content

Commit 0a4bd42

Browse files
committed
Dynamic leaderboard
Tiny improvements
1 parent 7fe281f commit 0a4bd42

17 files changed

+85
-37
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
docs
22
docs/*
3+
assets
4+
assets/*

README.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22

33
PUBG (original [PUBG](https://www.playbattlegrounds.com), sorry for using your abbreviation, we just want to train our programming skills in this little game for coders and haven't plans to publish it on Steam in the future) is an automatic environment (actually battleground) where several alrogithms fight in the real time.
44

5-
Each algorithm controls a creature (which can be bull, rhino, slugs etc.) with an aim to grab bullets and hurt other creatures with it. By killing enemies your creature increases it's IQ, the smartest creatures lists in the leaderboard.
5+
Each algorithm controls a creature (which can be bull, rhino, slug etc.) with an aim to grab bullets and hurt other creatures with it. By killing enemies your creature increases it's IQ, the smartest creatures lists in the leaderboard. Take a look at running PUBG [here](http://appcraft.pro/pubg/).
6+
7+
[![pubg](http://appcraft.pro/pubg/assets/animated_sample.gif)](http://appcraft.pro/pubg/)
8+
9+
## How it can be used
10+
11+
1. If you're learning programming you can use PUBG to train your projection (from abstract thoughts to certain commands) skill.
12+
13+
2. If you works in a team you can organize weekly battles and give pizza, beer or iPhone X to a winner.
14+
15+
3. If you're a teacher you can use PUBG as a small lab to demonstrate basic algorithms and applied samples of programming knowledge. It's much more interesting to make a brain for a creature rather than to draw a parabola on a screen (in most cases).
616

717
## Fast start
818

battleground.js

+35-28
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ function battleGround() {
7474
noBulletsCounter = 0,
7575
bulletsGeneratorFrequency = 0,
7676
shells = { steel: 0, poisoned: 1, rubber: 2, ice: 3 },
77+
fullLeaderboard = false,
78+
leaderboardCounter = 0,
7779
bulletColors = [
7880
{ fill: "#FFF000", stroke: "#BEB320" },
7981
{ fill: "#42FF00", stroke: "#299E00" },
@@ -99,7 +101,8 @@ function battleGround() {
99101
dangerousBulletSpeed = 5,
100102
maxBulletsOnGround = 20,
101103
summonInterval = 10,
102-
noBulletsInterval = 50;
104+
fullLeaderboardInterval = 50,
105+
noBulletsInterval = 40;
103106

104107
// Create an engine
105108
let engine = Engine.create(),
@@ -169,25 +172,11 @@ function battleGround() {
169172
payload: null
170173
};
171174

172-
function rainbow(numOfSteps, step) {
173-
let r, g, b,
174-
h = step / numOfSteps,
175-
i = ~~(h * 6),
176-
f = h * 6 - i,
177-
q = 1 - f;
178-
switch(i % 6) {
179-
case 0: r = 1; g = f; b = 0; break;
180-
case 1: r = q; g = 1; b = 0; break;
181-
case 2: r = 0; g = 1; b = f; break;
182-
case 3: r = 0; g = q; b = 1; break;
183-
case 4: r = f; g = 0; b = 1; break;
184-
case 5: r = 1; g = 0; b = q; break;
185-
}
186-
let c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
187-
let sh = Math.floor(step / 6) * -25;
188-
if (sh < -120) sh = -120;
189-
if (sh < 0) c = Common.shadeColor(c, sh)
190-
return (c);
175+
function rainbow() {
176+
let h = randomInt(0, 359),
177+
s = randomInt(50, 99),
178+
l = randomInt(45, 65);
179+
return `hsl(${h},${s}%,${l}%)`;
191180
}
192181

193182
// Try to load config
@@ -205,7 +194,7 @@ function battleGround() {
205194
}
206195

207196
let loadedBrainsCount = 0;
208-
bulletsGeneratorFrequency = 105 - maxAliveCreatures * bulletsGeneratorFrequencyPerCreature
197+
bulletsGeneratorFrequency = 95 - maxAliveCreatures * bulletsGeneratorFrequencyPerCreature
209198
if (bulletsGeneratorFrequency < 20) bulletsGeneratorFrequency = 20;
210199

211200
function sourceLoaded() {
@@ -228,7 +217,7 @@ function battleGround() {
228217
brain.name = code.name.length > 10 ? code.name.substr(0, 10) : code.name;
229218
brain.kind = code.kind;
230219
brain.code = code;
231-
brain.color = rainbow(sources.length, i);
220+
brain.color = rainbow();
232221

233222
let iq = localStorage.getItem(brain.id);
234223
if (iq) brain.iq = parseInt(iq);
@@ -255,22 +244,31 @@ function battleGround() {
255244

256245
function updateLeaderboard() {
257246
let table = document.getElementById("leaderboard"),
258-
rows = table.rows.length - 1;
247+
rowsCount = table.rows.length - 1,
248+
aliveCount = 0;
259249

260250
// Sort by IQ
261251
let items = [];
262252
brains.forEach(b => {
263253
items.push({ name: `${b.name} (${b.author})`.toUpperCase(), kills: b.kills, iq: b.iq, alive: b.alive, color: b.color, deaths: b.deaths });
254+
if (b.alive) aliveCount++;
264255
});
265256
items.sort(function(a, b) {
266257
return a.iq > b.iq ? -1 : a.iq < b.iq ? 1 : 0;
267258
});
268259

260+
// Remove unnecessary rows if needed
261+
if (!fullLeaderboard && rowsCount > aliveCount) {
262+
for (let i = 0; i < rowsCount - aliveCount; i++) table.deleteRow(table.rows.length - 1);
263+
rowsCount = table.rows.length - 1;
264+
}
265+
266+
let r = 1;
269267
for (let i = 0; i < items.length; i++) {
270268
let item = items[i],
271-
row,
272-
r = i + 1;
273-
if (rows < r) {
269+
row;
270+
if (!item.alive && !fullLeaderboard) continue;
271+
if (rowsCount < r) {
274272
row = table.insertRow(r);
275273
for (let j = 0; j < 5; j++) {
276274
let cell = row.insertCell(j);
@@ -279,7 +277,7 @@ function battleGround() {
279277
} else {
280278
row = table.rows[r];
281279
}
282-
row.cells[0].innerHTML = `${r}`;
280+
row.cells[0].innerHTML = `${i + 1}`;
283281
row.cells[1].innerHTML = item.name;
284282
row.cells[2].innerHTML = `${item.kills}`;
285283
row.cells[3].innerHTML = `${item.deaths}`;
@@ -294,6 +292,7 @@ function battleGround() {
294292
row.style.webkitTextStroke = null;
295293
row.classList.add("dead");
296294
}
295+
r++;
297296
}
298297
}
299298

@@ -594,6 +593,12 @@ function battleGround() {
594593
if (loopCounter < 0) return;
595594
loopCounter = -1;
596595

596+
if (leaderboardCounter > 0 && --leaderboardCounter < 1) {
597+
leaderboardCounter = 0;
598+
fullLeaderboard = false;
599+
updateLeaderboard();
600+
}
601+
597602
bulletsGeneratorCounter++;
598603
if (bullets.length > 0) noBulletsCounter = 0;
599604
if (++noBulletsCounter >= noBulletsInterval) {
@@ -806,7 +811,7 @@ function battleGround() {
806811
blts = creature.bullets,
807812
pos = body.position;
808813
brain.deaths++;
809-
brain.alive = false;
814+
brain.alive = false;
810815
creature.brain = null;
811816
body.label = null;
812817
Matter.Composite.remove(world, body);
@@ -816,6 +821,8 @@ function battleGround() {
816821
}
817822

818823
calculateIQForVictimAndKiller(brain, shooter ? shooter.brain : null);
824+
leaderboardCounter = fullLeaderboardInterval;
825+
fullLeaderboard = true;
819826
updateLeaderboard();
820827
}
821828
else {

brains/br_bulletbull.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ br_bulletbull = {
66

77
author: "Urist",
88

9+
description: "The spinning one. BULLetBULL gathers enough bullets, then goes to the arena center and starts spinning like a balerina of death until some poor soul appears in his line of sight.",
10+
911
thinkAboutIt: function(self, enemies, bullets, objects, events) {
1012

1113
if (typeof readyToFire == "undefined") {

brains/br_derzkyi.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ br_derzkyi = {
77

88
author: 'НЕИЗВЕСТЕН',
99

10+
description: "Cool russian guy from neighborhood 😎👊🤘",
11+
1012
bot: {},
1113

1214
message: null,

brains/br_dexter.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ br_dexter = {
22
name: "MoreGun",
33
kind: kinds.splitpus,
44
author: "Sad108",
5+
description: "The revengeful one. His parents were brutally murdered. Killer was never found. Now Dexter Moregun is looking for the most infamous murderers to brutally murder them.",
56

67
fatherPlumber: null,
78
dexterMessage: null,

brains/br_edmund.js

+9
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ br_edmund = {
133133
/* 10 chars max, displayed with name of the algorithm on the leaderboard. */
134134
author: "Amoneron",
135135

136+
/**
137+
* Describe what logic you implemented in this brain
138+
* so other users can understand your genius thoughts.
139+
* It's not used in the game directly, rather
140+
* leaderboards (http://appcraft.pro/pubg/docs/en/leaderboard.html)
141+
* takes brain's description from this variable.
142+
* */
143+
description: "The basic algorithm for writing your bots",
144+
136145
/**
137146
* Loop function called by runner.
138147
*

brains/br_enigma.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ br_enigma = {
44
name: "Enigma",
55
kind: kinds.miner,
66
author: "BigData",
7+
description: "Infobot. He keeps his opponents informed about the weather in different cities all over the world and broadcasts actual bitcoins course",
78

89
thinkAboutIt: function(self, enemies, bullets, objects, events) {
910

@@ -47,8 +48,9 @@ br_enigma = {
4748
let message = null;
4849
if (++this.messageCounter > this.messageInterval && Math.random() < 0.9) {
4950
this.messageCounter = 0;
50-
if (this.messages.length > 0) {
51-
message = this.messages[randomInt(0, this.messages.length - 1)];
51+
if (this.messages.length > 1) {
52+
if (Math.random() < 0.2) message = this.messages[0]; // BTC > USD rate
53+
else message = this.messages[randomInt(1, this.messages.length - 1)];
5254
}
5355
}
5456

@@ -125,8 +127,10 @@ br_enigma = {
125127
this.jsonRequest("https://api.coindesk.com/v1/bpi/currentprice.json", (data) => {
126128
if (data.target.status === 200) {
127129
let info = data.target.response,
128-
msg = `1 BTC = $${info.bpi.USD.rate}`;
129-
this.messages.push(msg);
130+
btc = info.bpi.USD.rate,
131+
pos = btc.indexOf(".");
132+
if (pos >= 0) btc = btc.substr(0, pos)
133+
this.messages.unshift(`1 BTC = $${btc}`);
130134
}
131135
});
132136

brains/br_helltrain.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ br_helltrain = {
44
name: 'Helltrain',
55
kind: kinds.miner,
66
author: 'Devil',
7+
description: "Demon from Hell.",
78

89
bot: {},
910
message: null,

brains/br_mindblast.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ br_mindblast = {
44
name: 'Mindblast',
55
kind: kinds.splitpus,
66
author: 'Analytic',
7+
description: "Shrewd bot. Finds the creature that has the biggest IQ scores and kills it immediatelly.",
78

89
bot: {},
910
message: null,

brains/br_niloultet.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ br_niloultet = {
77

88
author: 'Andrey',
99

10+
description: "Tactical bot. He controls selected sector.",
11+
1012
bot: {},
1113

1214
onPosition: true,

brains/br_pacifist.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ br_pacifist = {
44
name: "Pacifist",
55
kind: kinds.moose,
66
author: "Sonya",
7+
description: "Make love, not war ☮︎ Bot with a hard destiny: he does not accept any type of violence, so the main purpose of his life is to consume the bullets before others will get them",
78

89
thinkAboutIt: function(self, enemies, bullets, objects, events) {
910

brains/br_rathorn.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ br_rathorn = {
66

77
author: "BlackPeter",
88

9+
description: "The sleazy one. Waits for his opponents to run out of health just to deliver the final blow. Master of hit&run and runaway arts.",
10+
911
thinkAboutIt: function(self, enemies, bullets, objects, events) {
1012

1113
const corners = [{x: 70, y: ground.height - 70}, {x: 70, y: 70}, {x: ground.width - 70, y: 70}, {x: ground.width - 70, y: ground.height - 70}];
@@ -40,7 +42,6 @@ br_rathorn = {
4042

4143
events.forEach(event => {
4244
if (event.type == 1) {
43-
console.log(event);
4445
if (event.payload[0].id == self.id) {
4546
ratMessage = "Easy kill, " + event.payload[1].name;
4647
}
@@ -304,10 +305,9 @@ br_rathorn = {
304305
}
305306
}
306307
})
307-
//Kill the bitch
308+
308309
if (e != 0) {
309310
enemy = e;
310-
console.log(enemy.lives);
311311
let backlash = Math.PI / 50.0;
312312
let directionAngle = angleBetween(self, e);
313313
if (distanceBetween(self, enemy) < 150) {

brains/br_reptile.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ br_reptile = {
77

88
author: 'vaskebjørn',
99

10+
description: "This bot is very tricky, do not joke with him. Hiding, dodging and smashing others.",
11+
1012
bot: {},
1113

1214
findBulletTimestamp: null,

brains/br_utilizator.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ br_utilizator = {
77

88
author: 'macMini',
99

10+
description: "Smart bot hunting only for the target with the biggest amount of bullets.",
11+
1012
bot: {},
1113

1214
message: null,

brains/br_yssysin.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ br_yssysin = {
77

88
author: 'X-Ray',
99

10+
description: "Indiscriminate bot. He selects a random target and pursues it till death.",
11+
1012
bot: {},
1113

1214
message: null,

extra/style.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ body, a {
22
margin: 0px;
33
color: white;
44
font-family: Verdana, Geneva, Tahoma, sans-serif;
5-
font-size: 75%;
5+
font-size: 80%;
66
font-weight: 600;
77
-webkit-text-stroke: 0.5px rgb(70, 70, 70);
88
overflow: hidden;

0 commit comments

Comments
 (0)