Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@bleckert/football-simulator

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bleckert/football-simulator - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

2

Commentator.d.ts

@@ -1,2 +0,2 @@

import { GameEvent } from './types/GameEvent';
import type { GameEvent } from './types/GameEvent';
export default class Commentator {

@@ -3,0 +3,0 @@ name: string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Event_1 = require("./enums/Event");
const importantEvents = [
var Event_1 = require("./enums/Event");
var importantEvents = [
Event_1.Event.GameStart,

@@ -15,7 +15,8 @@ Event_1.Event.Kickoff,

];
class Commentator {
constructor(name = 'Mr. Commentator') {
var Commentator = /** @class */ (function () {
function Commentator(name) {
if (name === void 0) { name = 'Mr. Commentator'; }
this.name = name;
}
routeComment(event) {
Commentator.prototype.routeComment = function (event) {
switch (event.event) {

@@ -43,5 +44,5 @@ case Event_1.Event.GameStart:

}
}
comment(event) {
const importantEvent = event.event in importantEvents;
};
Commentator.prototype.comment = function (event) {
var importantEvent = event.event in importantEvents;
if (!importantEvent && Math.random() > 0.5) {

@@ -51,43 +52,44 @@ return null;

return this.routeComment(event);
}
gameStarted(event) {
return `The game between ${event.homeTeam.name} and ${event.awayTeam.name} has started.`;
}
kickoff(event) {
return `${event.data.name} with the kickoff.`;
}
halfTime(event) {
return `It's half time! The score is ${event.gameInfo.homeGoals} - ${event.gameInfo.awayGoals}`;
}
advance(event) {
return `${event.attackingTeam.name} advances with the ball.`;
}
defence(event) {
return `${event.defendingTeam.name} tries to advance but good defence by ${event.attackingTeam.name} that steals the ball.`;
}
rebound(comment, event) {
};
Commentator.prototype.gameStarted = function (event) {
return "The game between " + event.homeTeam.name + " and " + event.awayTeam.name + " has started.";
};
Commentator.prototype.kickoff = function (event) {
return event.data.name + " with the kickoff.";
};
Commentator.prototype.halfTime = function (event) {
return "It's half time! The score is " + event.gameInfo.homeGoals + " - " + event.gameInfo.awayGoals;
};
Commentator.prototype.advance = function (event) {
return event.attackingTeam.name + " advances with the ball.";
};
Commentator.prototype.defence = function (event) {
return event.defendingTeam.name + " tries to advance but good defence by " + event.attackingTeam.name + " that steals the ball.";
};
Commentator.prototype.rebound = function (comment, event) {
if (event.data === event.attackingTeam) {
return `${event.attackingTeam.name} gets the ball back.`;
return event.attackingTeam.name + " gets the ball back.";
}
return [comment, `${event.attackingTeam.name} can take control over the ball.`].join(' ');
}
save(event) {
return this.rebound(`${event.attackingPrimaryPlayer.info.name} tries to score but the goalkeeper saves the ball.`, event);
}
block(event) {
return this.rebound(`${event.attackingPrimaryPlayer.info.name} tries to score but the ball was blocked by the defence.`, event);
}
goal(event) {
return `${event.attackingPrimaryPlayer.info.name} shoots and he scores! ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`;
}
gameEnded(event) {
return [comment, event.attackingTeam.name + " can take control over the ball."].join(' ');
};
Commentator.prototype.save = function (event) {
return this.rebound(event.attackingPrimaryPlayer.info.name + " tries to score but the goalkeeper saves the ball.", event);
};
Commentator.prototype.block = function (event) {
return this.rebound(event.attackingPrimaryPlayer.info.name + " tries to score but the ball was blocked by the defence.", event);
};
Commentator.prototype.goal = function (event) {
return event.attackingPrimaryPlayer.info.name + " shoots and he scores! " + event.gameInfo.homeGoals + "-" + event.gameInfo.awayGoals;
};
Commentator.prototype.gameEnded = function (event) {
if (event.gameInfo.homeGoals > event.gameInfo.awayGoals) {
return `The game has ended! ${event.homeTeam.name} wins ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`;
return "The game has ended! " + event.homeTeam.name + " wins " + event.gameInfo.homeGoals + "-" + event.gameInfo.awayGoals;
}
if (event.gameInfo.homeGoals < event.gameInfo.awayGoals) {
return `The game has ended! ${event.awayTeam.name} takes 3 points on the road! ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`;
return "The game has ended! " + event.awayTeam.name + " takes 3 points on the road! " + event.gameInfo.homeGoals + "-" + event.gameInfo.awayGoals;
}
return `The game ends with a draw! Final score ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`;
}
}
return "The game ends with a draw! Final score " + event.gameInfo.homeGoals + "-" + event.gameInfo.awayGoals;
};
return Commentator;
}());
exports.default = Commentator;

@@ -1,5 +0,5 @@

import { GameEvent } from './types/GameEvent';
import type { GameEvent } from './types/GameEvent';
import { Event } from './enums/Event';
import Team from './Team';
import Player from './Player';
import type Team from './Team';
import type Player from './Player';

@@ -6,0 +6,0 @@ const importantEvents = [

import { Event } from './enums/Event';
import Team from './Team';
import { GameEvent } from './types/GameEvent';
import { GameInfo } from './types/GameInfo';
import type Team from './Team';
import type { GameEvent } from './types/GameEvent';
import type { GameInfo } from './types/GameInfo';
import { FieldArea } from "./enums/FieldArea";
import { Action } from './enums/Action';
import Player from "./Player";
import type Player from "./Player";
import { GoalType } from "./enums/GoalType";

@@ -84,3 +84,3 @@ import { AssistType } from "./enums/AssistType";

handleEvent(event: GameEvent): void;
eventLoop(): IterableIterator<GameEvent>;
eventLoop(): Generator<GameEvent, void, unknown>;
gameEvent(event: Event, data?: any, attackingPrimaryPlayer?: Player | null, attackingSecondaryPlayer?: Player | null, defendingPrimaryPlayer?: Player | null, defendingSecondaryPlayer?: Player | null, goalType?: GoalType | null, assistType?: AssistType | null): GameEvent;

@@ -87,0 +87,0 @@ random(team: Team): number;

"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
const Event_1 = require("./enums/Event");
const FieldArea_1 = require("./enums/FieldArea");
const Action_1 = require("./enums/Action");
const GoalType_1 = require("./enums/GoalType");
const AssistType_1 = require("./enums/AssistType");
class Engine {
constructor(homeTeam, awayTeam) {
var Event_1 = require("./enums/Event");
var FieldArea_1 = require("./enums/FieldArea");
var Action_1 = require("./enums/Action");
var GoalType_1 = require("./enums/GoalType");
var AssistType_1 = require("./enums/AssistType");
var Engine = /** @class */ (function () {
function Engine(homeTeam, awayTeam) {
var _this = this;
/**

@@ -60,13 +88,13 @@ * Has the game started?

this.gameEvents = [];
this.simulate = () => {
if (!this.gameStarted) {
this.start();
this.simulate = function () {
if (!_this.gameStarted) {
_this.start();
}
const event = this.gameLoop.next();
var event = _this.gameLoop.next();
if (event.done) {
return;
}
this.gameEvents.push(event.value);
this.handleEvent(event.value);
this.simulate();
_this.gameEvents.push(event.value);
_this.handleEvent(event.value);
_this.simulate();
};

@@ -82,4 +110,4 @@ this.homeTeam = homeTeam;

}
start() {
const coinflip = Math.floor(Math.random() * 2) == 0;
Engine.prototype.start = function () {
var coinflip = Math.floor(Math.random() * 2) == 0;
this.ballPossession = (coinflip) ? this.homeTeam : this.awayTeam;

@@ -90,18 +118,19 @@ this.startedWithBall = this.ballPossession;

this.gameStarted = true;
}
teamWithoutBall() {
};
Engine.prototype.teamWithoutBall = function () {
return (this.ballPossession === this.homeTeam) ? this.awayTeam : this.homeTeam;
}
rebound() {
};
Engine.prototype.rebound = function () {
return Math.floor(Math.random()) > this.reboundChance;
}
reverseSide(current) {
const map = {
[FieldArea_1.FieldArea.Offense]: FieldArea_1.FieldArea.Defence,
[FieldArea_1.FieldArea.Midfield]: FieldArea_1.FieldArea.Midfield,
[FieldArea_1.FieldArea.Defence]: FieldArea_1.FieldArea.Offense,
};
};
Engine.prototype.reverseSide = function (current) {
var _a;
var map = (_a = {},
_a[FieldArea_1.FieldArea.Offense] = FieldArea_1.FieldArea.Defence,
_a[FieldArea_1.FieldArea.Midfield] = FieldArea_1.FieldArea.Midfield,
_a[FieldArea_1.FieldArea.Defence] = FieldArea_1.FieldArea.Offense,
_a);
return map[current];
}
handleEvent(event) {
};
Engine.prototype.handleEvent = function (event) {
switch (event.event) {

@@ -130,16 +159,37 @@ case Event_1.Event.Goal:

}
}
*eventLoop() {
for (this.gameInfo.matchMinute; this.gameInfo.matchMinute <= this.gameTime; this.gameInfo.matchMinute += 1 / this.eventsPerMinute) {
yield this.simulateEvent();
}
}
gameEvent(event, data = null, attackingPrimaryPlayer = null, attackingSecondaryPlayer = null, defendingPrimaryPlayer = null, defendingSecondaryPlayer = null, goalType = null, assistType = null) {
};
Engine.prototype.eventLoop = function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.gameInfo.matchMinute;
_a.label = 1;
case 1:
if (!(this.gameInfo.matchMinute <= this.gameTime)) return [3 /*break*/, 4];
return [4 /*yield*/, this.simulateEvent()];
case 2:
_a.sent();
_a.label = 3;
case 3:
this.gameInfo.matchMinute += 1 / this.eventsPerMinute;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
Engine.prototype.gameEvent = function (event, data, attackingPrimaryPlayer, attackingSecondaryPlayer, defendingPrimaryPlayer, defendingSecondaryPlayer, goalType, assistType) {
if (data === void 0) { data = null; }
if (attackingPrimaryPlayer === void 0) { attackingPrimaryPlayer = null; }
if (attackingSecondaryPlayer === void 0) { attackingSecondaryPlayer = null; }
if (defendingPrimaryPlayer === void 0) { defendingPrimaryPlayer = null; }
if (defendingSecondaryPlayer === void 0) { defendingSecondaryPlayer = null; }
if (goalType === void 0) { goalType = null; }
if (assistType === void 0) { assistType = null; }
return {
event,
data,
attackingPrimaryPlayer,
attackingSecondaryPlayer,
defendingPrimaryPlayer,
defendingSecondaryPlayer,
event: event,
data: data,
attackingPrimaryPlayer: attackingPrimaryPlayer,
attackingSecondaryPlayer: attackingSecondaryPlayer,
defendingPrimaryPlayer: defendingPrimaryPlayer,
defendingSecondaryPlayer: defendingSecondaryPlayer,
gameInfo: Object.assign({}, this.gameInfo),

@@ -151,10 +201,10 @@ homeTeam: this.homeTeam,

fieldPosition: this.ballPosition,
goalType,
assistType,
goalType: goalType,
assistType: assistType,
};
}
random(team) {
const min = -this.randomEffect;
const max = this.randomEffect;
let random = Math.floor(Math.random() * (max - min + 1) + min);
};
Engine.prototype.random = function (team) {
var min = -this.randomEffect;
var max = this.randomEffect;
var random = Math.floor(Math.random() * (max - min + 1) + min);
if (team === this.homeTeam) {

@@ -164,16 +214,16 @@ random += this.homeTeamAdvantage;

return random;
}
simulateGoalAttempt(attackingTeam, defendingTeam, attacker) {
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
};
Engine.prototype.simulateGoalAttempt = function (attackingTeam, defendingTeam, attacker) {
var defence = defendingTeam.defenceRating() + this.random(defendingTeam);
var attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (attack + (attack * this.extraAttackOnChance) > defence) {
const goalkeeper = defendingTeam.goalkeeperRating() + this.random(defendingTeam);
const attackerRating = attacker.attackRating() + this.random(attackingTeam);
var goalkeeper = defendingTeam.goalkeeperRating() + this.random(defendingTeam);
var attackerRating = attacker.attackRating() + this.random(attackingTeam);
return (attackerRating > goalkeeper) ? Event_1.Event.Goal : Event_1.Event.Save;
}
return Event_1.Event.Block;
}
simulatePossession(attackingTeam, defendingTeam, action) {
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const possession = attackingTeam.possessionRating() + this.random(attackingTeam);
};
Engine.prototype.simulatePossession = function (attackingTeam, defendingTeam, action) {
var defence = defendingTeam.defenceRating() + this.random(defendingTeam);
var possession = attackingTeam.possessionRating() + this.random(attackingTeam);
if (defence > possession) {

@@ -183,11 +233,11 @@ return Event_1.Event.Defence;

return (action === Action_1.Action.Retreat) ? Event_1.Event.Retreat : Event_1.Event.Possession;
}
simulateAction(action, attacker) {
};
Engine.prototype.simulateAction = function (action, attacker) {
if (!this.ballPossession) {
return Event_1.Event.EventLess;
}
const attackingTeam = this.ballPossession;
const defendingTeam = this.teamWithoutBall();
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
var attackingTeam = this.ballPossession;
var defendingTeam = this.teamWithoutBall();
var defence = defendingTeam.defenceRating() + this.random(defendingTeam);
var attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (action === Action_1.Action.Advance) {

@@ -200,9 +250,9 @@ return (attack > defence) ? Event_1.Event.Advance : Event_1.Event.Defence;

return this.simulatePossession(attackingTeam, defendingTeam, action);
}
simulateAssistType(secondaryPlayer) {
const random = Math.random();
const secondaryPlayerAttributes = secondaryPlayer.attributes;
const secondaryPlayerRating = secondaryPlayer.rating();
const shooting = secondaryPlayerRating.shooting;
const passing = secondaryPlayerRating.passing;
};
Engine.prototype.simulateAssistType = function (secondaryPlayer) {
var random = Math.random();
var secondaryPlayerAttributes = secondaryPlayer.attributes;
var secondaryPlayerRating = secondaryPlayer.rating();
var shooting = secondaryPlayerRating.shooting;
var passing = secondaryPlayerRating.passing;
if (shooting > passing && random > 0.5) {

@@ -215,11 +265,11 @@ return (random > 0.5) ? AssistType_1.AssistType.Deflection : AssistType_1.AssistType.Rebound;

return AssistType_1.AssistType.Cross;
}
simulateGoalType(primaryPlayer, secondaryPlayer) {
const assist = Math.random() > 0.5;
};
Engine.prototype.simulateGoalType = function (primaryPlayer, secondaryPlayer) {
var assist = Math.random() > 0.5;
if (!assist) {
return [GoalType_1.GoalType.Shot, null];
}
const primaryPlayerAttributes = primaryPlayer.attributes;
const random = Math.random();
const assistType = this.simulateAssistType(secondaryPlayer);
var primaryPlayerAttributes = primaryPlayer.attributes;
var random = Math.random();
var assistType = this.simulateAssistType(secondaryPlayer);
return [

@@ -229,13 +279,13 @@ (primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType_1.GoalType.Header : [GoalType_1.GoalType.Volley, GoalType_1.GoalType.Shot][Math.floor(Math.random() * 2)],

];
}
halfTime() {
};
Engine.prototype.halfTime = function () {
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam;
this.ballPosition = FieldArea_1.FieldArea.Midfield;
return this.gameEvent(Event_1.Event.HalfTime);
}
gameEnd() {
};
Engine.prototype.gameEnd = function () {
this.gameEnded = true;
return this.gameEvent(Event_1.Event.GameEnd);
}
goal(attackingPrimaryPlayer, attackingSecondaryPlayer) {
};
Engine.prototype.goal = function (attackingPrimaryPlayer, attackingSecondaryPlayer) {
if (this.ballPossession === this.homeTeam) {

@@ -248,4 +298,5 @@ this.gameInfo.homeGoals += 1;

return this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer);
}
simulateEvent() {
};
Engine.prototype.simulateEvent = function () {
var _a;
if (this.gameInfo.matchMinute == this.gameTime / 2)

@@ -257,16 +308,17 @@ return this.halfTime();

return this.gameEvent(Event_1.Event.EventLess);
const attackingPrimaryPlayer = this.ballPossession.attacker(this.ballPosition);
const attackingSecondaryPlayer = this.ballPossession.attacker(this.ballPosition, [attackingPrimaryPlayer]);
const defendingTeam = this.teamWithoutBall();
const defendingPrimaryPlayer = defendingTeam.defender(this.ballPosition);
const action = this.ballPossession.simulateMove(this.ballPosition, this.gameInfo);
let goalType = null;
let assist = null;
const event = this.simulateAction(action, attackingPrimaryPlayer);
var attackingPrimaryPlayer = this.ballPossession.attacker(this.ballPosition);
var attackingSecondaryPlayer = this.ballPossession.attacker(this.ballPosition, [attackingPrimaryPlayer]);
var defendingTeam = this.teamWithoutBall();
var defendingPrimaryPlayer = defendingTeam.defender(this.ballPosition);
var action = this.ballPossession.simulateMove(this.ballPosition, this.gameInfo);
var goalType = null;
var assist = null;
var event = this.simulateAction(action, attackingPrimaryPlayer);
if (event === Event_1.Event.Goal) {
[goalType, assist] = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer);
_a = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer), goalType = _a[0], assist = _a[1];
}
return this.gameEvent(event, null, attackingPrimaryPlayer, attackingSecondaryPlayer, defendingPrimaryPlayer, defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]), goalType, assist);
}
}
};
return Engine;
}());
exports.default = Engine;
import {Event} from './enums/Event';
import Team from './Team';
import {GameEvent} from './types/GameEvent';
import {GameInfo} from './types/GameInfo';
import type Team from './Team';
import type {GameEvent} from './types/GameEvent';
import type {GameInfo} from './types/GameInfo';
import {FieldArea} from "./enums/FieldArea";
import {Action} from './enums/Action';
import Player, {PlayerRating} from "./Player";
import type Player from "./Player";
import type {PlayerRating} from "./Player";
import {GoalType} from "./enums/GoalType";

@@ -9,0 +10,0 @@ import {AssistType} from "./enums/AssistType";

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Action = void 0;
var Action;

@@ -4,0 +5,0 @@ (function (Action) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssistType = void 0;
var AssistType;

@@ -4,0 +5,0 @@ (function (AssistType) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefenceType = void 0;
var DefenceType;

@@ -4,0 +5,0 @@ (function (DefenceType) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Event = void 0;
var Event;

@@ -4,0 +5,0 @@ (function (Event) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FieldArea = void 0;
var FieldArea;

@@ -4,0 +5,0 @@ (function (FieldArea) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoalType = void 0;
var GoalType;

@@ -4,0 +5,0 @@ (function (GoalType) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.attackPositions = exports.midfieldPositions = exports.defencePositions = exports.Position = void 0;
var Position;

@@ -4,0 +5,0 @@ (function (Position) {

/// <reference types="node" />
import Team from './Team';
import { GameEvent } from './types/GameEvent';
import Commentator from './Commentator';
import type Team from './Team';
import type { GameEvent } from './types/GameEvent';
import type Commentator from './Commentator';
import { EventEmitter } from 'events';

@@ -6,0 +6,0 @@ import Engine from './Engine';

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const Engine_1 = __importDefault(require("./Engine"));
const Reporter_1 = __importDefault(require("./Reporter"));
class Game extends events_1.EventEmitter {
constructor(homeTeam, awayTeam, commentator) {
super();
var events_1 = require("events");
var Engine_1 = require("./Engine");
var Reporter_1 = require("./Reporter");
var Game = /** @class */ (function (_super) {
__extends(Game, _super);
function Game(homeTeam, awayTeam, commentator) {
var _this = _super.call(this) || this;
/**
* Milliseconds between each simulation
*/
this.gameSpeed = 500;
_this.gameSpeed = 500;
/**
* Events copy
*/
this.events = [];
this.loop = () => {
const event = this.events.shift();
_this.events = [];
_this.loop = function () {
var event = _this.events.shift();
if (!event) {
this.report();
_this.report();
return;
}
this.emit('comment', {
text: this.commentator.comment(event),
_this.emit('comment', {
text: _this.commentator.comment(event),
gameInfo: event.gameInfo,
});
this.emit('event', event);
setTimeout(this.loop, this.gameSpeed);
_this.emit('event', event);
setTimeout(_this.loop, _this.gameSpeed);
};
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
this.commentator = commentator;
this.engine = new Engine_1.default(this.homeTeam, this.awayTeam);
_this.homeTeam = homeTeam;
_this.awayTeam = awayTeam;
_this.commentator = commentator;
_this.engine = new Engine_1.default(_this.homeTeam, _this.awayTeam);
return _this;
}
start() {
Game.prototype.start = function () {
var _this = this;
this.engine.start();
this.events = this.engine.gameEvents.slice();
this.events.forEach(gameEvent => {
this.emit('comment', {
text: this.commentator.comment(gameEvent),
gameInfo: this.engine.gameInfo,
this.events.forEach(function (gameEvent) {
_this.emit('comment', {
text: _this.commentator.comment(gameEvent),
gameInfo: _this.engine.gameInfo,
});

@@ -50,13 +65,14 @@ });

this.simulate();
}
simulate() {
};
Game.prototype.simulate = function () {
this.engine.simulate();
this.events = this.engine.gameEvents.slice();
this.loop();
}
report() {
const reporter = new Reporter_1.default(this.engine.gameEvents);
};
Game.prototype.report = function () {
var reporter = new Reporter_1.default(this.engine.gameEvents);
this.emit('report', reporter.getReport());
}
}
};
return Game;
}(events_1.EventEmitter));
exports.default = Game;

@@ -1,4 +0,4 @@

import Team from './Team';
import { GameEvent } from './types/GameEvent';
import Commentator from './Commentator';
import type Team from './Team';
import type { GameEvent } from './types/GameEvent';
import type Commentator from './Commentator';
import { EventEmitter } from 'events';

@@ -5,0 +5,0 @@ import Engine from './Engine';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getRandomElement(options) {
const weighted = options.map(([action, weight]) => Array(weight).fill(action)).reduce((c, v) => c.concat(v), []);
var weighted = options.map(function (_a) {
var action = _a[0], weight = _a[1];
return Array(weight).fill(action);
}).reduce(function (c, v) { return c.concat(v); }, []);
return weighted[Math.floor((Math.random() * weighted.length))];
}
exports.default = getRandomElement;
{
"name": "@bleckert/football-simulator",
"version": "0.0.4",
"version": "0.0.5",
"scripts": {

@@ -13,3 +13,3 @@ "start": "ts-node test/index.ts",

"ts-node": "^8.3.0",
"typescript": "^3.5.3"
"typescript": "^4.3.2"
},

@@ -16,0 +16,0 @@ "dependencies": {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Position_1 = require("./enums/Position");
class Player {
constructor(info, biometrics, attributes, position) {
var Position_1 = require("./enums/Position");
var Player = /** @class */ (function () {
function Player(info, biometrics, attributes, position) {
this.info = info;

@@ -11,7 +11,7 @@ this.biometrics = biometrics;

}
ratingAverage() {
const rating = this.rating();
return Object.values(rating).reduce((a, b) => a + b) / Object.values(rating).length;
}
rating() {
Player.prototype.ratingAverage = function () {
var rating = this.rating();
return Object.values(rating).reduce(function (a, b) { return a + b; }) / Object.values(rating).length;
};
Player.prototype.rating = function () {
if (this.position === Position_1.Position.GK) {

@@ -35,8 +35,8 @@ return {

};
}
averageRating(ratings) {
return ratings.reduce((acc, curr) => acc + curr) / ratings.length;
}
defenceRating() {
const rating = this.rating();
};
Player.prototype.averageRating = function (ratings) {
return ratings.reduce(function (acc, curr) { return acc + curr; }) / ratings.length;
};
Player.prototype.defenceRating = function () {
var rating = this.rating();
return this.averageRating([

@@ -47,5 +47,5 @@ rating.defending,

]);
}
possessionRating() {
const rating = this.rating();
};
Player.prototype.possessionRating = function () {
var rating = this.rating();
return this.averageRating([

@@ -56,5 +56,5 @@ rating.dribbling,

]);
}
attackRating() {
const rating = this.rating();
};
Player.prototype.attackRating = function () {
var rating = this.rating();
return this.averageRating([

@@ -67,7 +67,12 @@ rating.dribbling,

]);
}
attributesAverage(...attributes) {
return (attributes.reduce((a, b) => a + b) / attributes.length) / 20 * 100;
}
}
};
Player.prototype.attributesAverage = function () {
var attributes = [];
for (var _i = 0; _i < arguments.length; _i++) {
attributes[_i] = arguments[_i];
}
return (attributes.reduce(function (a, b) { return a + b; }) / attributes.length) / 20 * 100;
};
return Player;
}());
exports.default = Player;

@@ -1,4 +0,4 @@

import { GameEvent } from './types/GameEvent';
import Player from "./Player";
import Team from "./Team";
import type { GameEvent } from './types/GameEvent';
import type Player from "./Player";
import type Team from "./Team";
export default class Reporter {

@@ -5,0 +5,0 @@ gameEvents: GameEvent[];

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
const Event_1 = require("./enums/Event");
class Reporter {
constructor(gameEvents) {
var Event_1 = require("./enums/Event");
var Reporter = /** @class */ (function () {
function Reporter(gameEvents) {
var _this = this;
this.home = {

@@ -19,14 +31,14 @@ goals: 0,

this.scoreSheet = [];
this.registerEvent = (gameEvent) => {
const side = (gameEvent.attackingTeam && gameEvent.attackingTeam.home) ? 'home' : 'away';
this[side].possession += 1;
this.registerEvent = function (gameEvent) {
var side = (gameEvent.attackingTeam && gameEvent.attackingTeam.home) ? 'home' : 'away';
_this[side].possession += 1;
if ([Event_1.Event.Save, Event_1.Event.Goal, Event_1.Event.Block].includes(gameEvent.event)) {
this[side].shots += 1;
_this[side].shots += 1;
}
if ([Event_1.Event.Save, Event_1.Event.Goal].includes(gameEvent.event)) {
this[side].shotsOnGoal += 1;
_this[side].shotsOnGoal += 1;
}
if (gameEvent.event === Event_1.Event.Goal) {
this[side].goals += 1;
this.scoreSheet.push({
_this[side].goals += 1;
_this.scoreSheet.push({
matchMinute: gameEvent.gameInfo.matchMinute,

@@ -41,12 +53,13 @@ goalScorer: gameEvent.attackingPrimaryPlayer,

}
getReport() {
Reporter.prototype.getReport = function () {
this.gameEvents.forEach(this.registerEvent);
const totalPossession = this.home.possession + this.away.possession;
var totalPossession = this.home.possession + this.away.possession;
return {
home: { ...this.home, possession: this.home.possession / totalPossession },
away: { ...this.away, possession: this.away.possession / totalPossession },
home: __assign(__assign({}, this.home), { possession: this.home.possession / totalPossession }),
away: __assign(__assign({}, this.away), { possession: this.away.possession / totalPossession }),
scoreSheet: this.scoreSheet,
};
}
}
};
return Reporter;
}());
exports.default = Reporter;

@@ -1,5 +0,5 @@

import {GameEvent} from './types/GameEvent';
import type {GameEvent} from './types/GameEvent';
import {Event} from './enums/Event';
import Player from "./Player";
import Team from "./Team";
import type Player from "./Player";
import type Team from "./Team";

@@ -6,0 +6,0 @@ export default class Reporter {

@@ -1,4 +0,4 @@

import Player from './Player';
import type Player from './Player';
import { FieldArea } from "./enums/FieldArea";
import { GameInfo } from "./types/GameInfo";
import type { GameInfo } from "./types/GameInfo";
import { Action } from "./enums/Action";

@@ -5,0 +5,0 @@ export interface TeamInterface {

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Position_1 = require("./enums/Position");
const FieldArea_1 = require("./enums/FieldArea");
const Action_1 = require("./enums/Action");
const getRandomElement_1 = __importDefault(require("./lib/getRandomElement"));
function createWeights(attacker = false) {
return {
[FieldArea_1.FieldArea.Defence]: {
var Position_1 = require("./enums/Position");
var FieldArea_1 = require("./enums/FieldArea");
var Action_1 = require("./enums/Action");
var getRandomElement_1 = require("./lib/getRandomElement");
function createWeights(attacker) {
var _a;
if (attacker === void 0) { attacker = false; }
return _a = {},
_a[FieldArea_1.FieldArea.Defence] = {
defenders: (attacker) ? 0.6 : 0.1,

@@ -17,3 +16,3 @@ midfielders: 0.3,

},
[FieldArea_1.FieldArea.Midfield]: {
_a[FieldArea_1.FieldArea.Midfield] = {
defenders: 0.25,

@@ -23,11 +22,11 @@ midfielders: 0.5,

},
[FieldArea_1.FieldArea.Offense]: {
_a[FieldArea_1.FieldArea.Offense] = {
defenders: (attacker) ? 0.1 : 0.6,
midfielders: 0.3,
attackers: (attacker) ? 0.6 : 0.1,
}
};
},
_a;
}
class Team {
constructor(home, name, players) {
var Team = /** @class */ (function () {
function Team(home, name, players) {
this.home = home;

@@ -37,3 +36,3 @@ this.name = name;

}
rating() {
Team.prototype.rating = function () {
return {

@@ -44,58 +43,64 @@ goalkeeping: this.goalkeeperRating(),

};
}
getGoalkeepers() {
return this.players.filter(player => player.position === Position_1.Position.GK);
}
getFieldPlayers(exclude = []) {
return this.players.filter(player => player.position !== Position_1.Position.GK).filter(player => !exclude.length || exclude.indexOf(player) < 0);
}
averageRating(map, players = null) {
const playersList = (players) ? players : this.getFieldPlayers();
return playersList.map(map).reduce((a, b) => a + b) / playersList.length;
}
goalkeeperRating() {
return this.averageRating(player => player.ratingAverage(), this.getGoalkeepers());
}
defenceRating() {
return this.averageRating(player => player.defenceRating());
}
possessionRating() {
return this.averageRating(player => player.possessionRating());
}
attackRating() {
return this.averageRating(player => player.attackRating());
}
simulateMove(ballPosition, gameInfo) {
};
Team.prototype.getGoalkeepers = function () {
return this.players.filter(function (player) { return player.position === Position_1.Position.GK; });
};
Team.prototype.getFieldPlayers = function (exclude) {
if (exclude === void 0) { exclude = []; }
return this.players.filter(function (player) { return player.position !== Position_1.Position.GK; }).filter(function (player) { return !exclude.length || exclude.indexOf(player) < 0; });
};
Team.prototype.averageRating = function (map, players) {
if (players === void 0) { players = null; }
var playersList = (players) ? players : this.getFieldPlayers();
return playersList.map(map).reduce(function (a, b) { return a + b; }) / playersList.length;
};
Team.prototype.goalkeeperRating = function () {
return this.averageRating(function (player) { return player.ratingAverage(); }, this.getGoalkeepers());
};
Team.prototype.defenceRating = function () {
return this.averageRating(function (player) { return player.defenceRating(); });
};
Team.prototype.possessionRating = function () {
return this.averageRating(function (player) { return player.possessionRating(); });
};
Team.prototype.attackRating = function () {
return this.averageRating(function (player) { return player.attackRating(); });
};
Team.prototype.simulateMove = function (ballPosition, gameInfo) {
if (ballPosition === FieldArea_1.FieldArea.Offense) {
const options = [[Action_1.Action.GoalAttempt, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
return getRandomElement_1.default(options);
var options_1 = [[Action_1.Action.GoalAttempt, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
return getRandomElement_1.default(options_1);
}
const options = [[Action_1.Action.Advance, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
var options = [[Action_1.Action.Advance, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
return getRandomElement_1.default(options);
}
getProbablePlayer(fieldPosition, attacker, exclude = []) {
const weights = createWeights(attacker);
const players = [];
this.getFieldPlayers(exclude).forEach(player => {
};
Team.prototype.getProbablePlayer = function (fieldPosition, attacker, exclude) {
if (exclude === void 0) { exclude = []; }
var weights = createWeights(attacker);
var players = [];
this.getFieldPlayers(exclude).forEach(function (player) {
if (Position_1.defencePositions.indexOf(player.position) > -1) {
players.push({ player, weight: weights[fieldPosition].defenders });
players.push({ player: player, weight: weights[fieldPosition].defenders });
}
else if (Position_1.midfieldPositions.indexOf(player.position) > -1) {
players.push({ player, weight: weights[fieldPosition].midfielders });
players.push({ player: player, weight: weights[fieldPosition].midfielders });
}
else {
players.push({ player, weight: weights[fieldPosition].attackers });
players.push({ player: player, weight: weights[fieldPosition].attackers });
}
});
const random = Math.min(Math.random(), 0.6);
const foundPlayers = players.filter(player => player.weight >= random).map(obj => obj.player);
var random = Math.min(Math.random(), 0.6);
var foundPlayers = players.filter(function (player) { return player.weight >= random; }).map(function (obj) { return obj.player; });
return foundPlayers[Math.floor(Math.random() * foundPlayers.length)];
}
attacker(fieldPosition, exclude = []) {
};
Team.prototype.attacker = function (fieldPosition, exclude) {
if (exclude === void 0) { exclude = []; }
return this.getProbablePlayer(fieldPosition, true, exclude);
}
defender(fieldPosition, exclude = []) {
};
Team.prototype.defender = function (fieldPosition, exclude) {
if (exclude === void 0) { exclude = []; }
return this.getProbablePlayer(fieldPosition, false, exclude);
}
}
};
return Team;
}());
exports.default = Team;

@@ -1,5 +0,5 @@

import Player, { PlayerRating } from './Player';
import type Player from './Player';
import { defencePositions, midfieldPositions, Position } from './enums/Position';
import { FieldArea } from "./enums/FieldArea";
import { GameInfo } from "./types/GameInfo";
import type { GameInfo } from "./types/GameInfo";
import { Action } from "./enums/Action";

@@ -6,0 +6,0 @@ import getRandomElement from "./lib/getRandomElement";

@@ -1,8 +0,8 @@

import { Event } from '../enums/Event';
import { GameInfo } from './GameInfo';
import Team from "../Team";
import { FieldArea } from "../enums/FieldArea";
import Player from "../Player";
import { GoalType } from "../enums/GoalType";
import { AssistType } from "../enums/AssistType";
import type { Event } from '../enums/Event';
import type { GameInfo } from './GameInfo';
import type Team from '../Team';
import type { FieldArea } from '../enums/FieldArea';
import type Player from '../Player';
import type { GoalType } from '../enums/GoalType';
import type { AssistType } from '../enums/AssistType';
export interface GameEvent {

@@ -9,0 +9,0 @@ event: Event;

@@ -1,8 +0,8 @@

import { Event } from '../enums/Event';
import { GameInfo } from './GameInfo';
import Team from "../Team";
import { FieldArea } from "../enums/FieldArea";
import Player from "../Player";
import { GoalType } from "../enums/GoalType";
import { AssistType } from "../enums/AssistType";
import type { Event } from '../enums/Event';
import type { GameInfo } from './GameInfo';
import type Team from '../Team';
import type { FieldArea } from '../enums/FieldArea';
import type Player from '../Player';
import type { GoalType } from '../enums/GoalType';
import type { AssistType } from '../enums/AssistType';

@@ -9,0 +9,0 @@ export interface GameEvent {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc