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.3 to 0.0.4

lib/getRandomElement.d.ts

4

Commentator.d.ts
import { GameEvent } from './types/GameEvent';
import { Event } from './enums/Event';
export default class Commentator {
static importantEvents: Event[];
name: string;
constructor(name?: string);
routeComment(event: GameEvent): string | null;
comment(event: GameEvent): string | null;

@@ -13,2 +12,3 @@ gameStarted(event: GameEvent): string;

defence(event: GameEvent): string;
rebound(comment: string, event: GameEvent): string;
save(event: GameEvent): string;

@@ -15,0 +15,0 @@ block(event: GameEvent): string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Event_1 = require("./enums/Event");
const importantEvents = [
Event_1.Event.GameStart,
Event_1.Event.Kickoff,
Event_1.Event.HalfTime,
Event_1.Event.Advance,
Event_1.Event.Save,
Event_1.Event.Block,
Event_1.Event.Goal,
Event_1.Event.GameEnd,
Event_1.Event.Injury,
];
class Commentator {

@@ -8,7 +19,3 @@ constructor(name = 'Mr. Commentator') {

}
comment(event) {
const importantEvent = this.constructor.importantEvents.indexOf(event.event) > -1;
if (!importantEvent && Math.random() > 0.5) {
return null;
}
routeComment(event) {
switch (event.event) {

@@ -37,2 +44,9 @@ case Event_1.Event.GameStart:

}
comment(event) {
const importantEvent = event.event in importantEvents;
if (!importantEvent && Math.random() > 0.5) {
return null;
}
return this.routeComment(event);
}
gameStarted(event) {

@@ -53,21 +67,13 @@ return `The game between ${event.homeTeam.name} and ${event.awayTeam.name} has started.`;

}
save(event) {
let comment = `${event.attackingPrimaryPlayer.info.name} tries to score but the goalkeeper saves the ball.`;
rebound(comment, event) {
if (event.data === event.attackingTeam) {
comment += ` ${event.attackingTeam.name} gets the ball back.`;
return `${event.attackingTeam.name} gets the ball back.`;
}
else {
comment += ` ${event.attackingTeam.name} can take control over the ball.`;
}
return comment;
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) {
let comment = `${event.attackingPrimaryPlayer.info.name} tries to score but the ball was blocked by the defence.`;
if (event.data === event.attackingTeam) {
comment += ` ${event.attackingTeam.name} gets the ball back.`;
}
else {
comment += ` ${event.attackingTeam.name} can take control over the ball.`;
}
return comment;
return this.rebound(`${event.attackingPrimaryPlayer.info.name} tries to score but the ball was blocked by the defence.`, event);
}

@@ -81,3 +87,3 @@ goal(event) {

}
else if (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}`;

@@ -88,13 +94,2 @@ }

}
Commentator.importantEvents = [
Event_1.Event.GameStart,
Event_1.Event.Kickoff,
Event_1.Event.HalfTime,
Event_1.Event.Advance,
Event_1.Event.Save,
Event_1.Event.Block,
Event_1.Event.Goal,
Event_1.Event.GameEnd,
Event_1.Event.Injury,
];
exports.default = Commentator;
import { GameEvent } from './types/GameEvent';
import { Event } from './enums/Event';
import Team from "./Team";
import Player from "./Player";
import Team from './Team';
import Player from './Player';
const importantEvents = [
Event.GameStart,
Event.Kickoff,
Event.HalfTime,
Event.Advance,
Event.Save,
Event.Block,
Event.Goal,
Event.GameEnd,
Event.Injury,
];
export default class Commentator {
static importantEvents = [
Event.GameStart,
Event.Kickoff,
Event.HalfTime,
Event.Advance,
Event.Save,
Event.Block,
Event.Goal,
Event.GameEnd,
Event.Injury,
];
name: string;

@@ -25,9 +25,3 @@

comment(event: GameEvent): string | null {
const importantEvent = (this.constructor as typeof Commentator).importantEvents.indexOf(event.event) > -1;
if (!importantEvent && Math.random() > 0.5) {
return null;
}
routeComment(event: GameEvent): string | null {
switch (event.event) {

@@ -57,2 +51,12 @@ case Event.GameStart:

comment(event: GameEvent): string | null {
const importantEvent = event.event in importantEvents;
if (!importantEvent && Math.random() > 0.5) {
return null;
}
return this.routeComment(event);
}
gameStarted(event: GameEvent): string {

@@ -78,24 +82,16 @@ return `The game between ${event.homeTeam.name} and ${event.awayTeam.name} has started.`;

save(event: GameEvent): string {
let comment = `${(event.attackingPrimaryPlayer as Player).info.name} tries to score but the goalkeeper saves the ball.`;
rebound(comment: string, event: GameEvent): string {
if (event.data === event.attackingTeam) {
comment += ` ${event.attackingTeam.name} gets the ball back.`;
} else {
comment += ` ${event.attackingTeam.name} can take control over the ball.`;
return `${event.attackingTeam.name} gets the ball back.`;
}
return comment;
return [comment, `${event.attackingTeam.name} can take control over the ball.`].join(' ');
}
save(event: GameEvent): string {
return this.rebound(`${(event.attackingPrimaryPlayer as Player).info.name} tries to score but the goalkeeper saves the ball.`, event);
}
block(event: GameEvent): string {
let comment = `${(event.attackingPrimaryPlayer as Player).info.name} tries to score but the ball was blocked by the defence.`;
if (event.data === event.attackingTeam) {
comment += ` ${event.attackingTeam.name} gets the ball back.`;
} else {
comment += ` ${event.attackingTeam.name} can take control over the ball.`;
}
return comment;
return this.rebound(`${(event.attackingPrimaryPlayer as Player).info.name} tries to score but the ball was blocked by the defence.`, event);
}

@@ -110,3 +106,5 @@

return `The game has ended! ${event.homeTeam.name} wins ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`;
} else if (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}`;

@@ -113,0 +111,0 @@ }

@@ -81,2 +81,4 @@ import { Event } from './enums/Event';

simulate: () => void;
rebound(): boolean;
reverseSide(current: FieldArea): FieldArea;
handleEvent(event: GameEvent): void;

@@ -86,5 +88,11 @@ eventLoop(): IterableIterator<GameEvent>;

random(team: Team): number;
simulateGoalAttempt(attackingTeam: Team, defendingTeam: Team, attacker: Player): Event;
simulatePossession(attackingTeam: Team, defendingTeam: Team, action: Action): Event;
simulateAction(action: Action, attacker: Player): Event;
simulateAssistType(secondaryPlayer: Player): AssistType | null;
simulateGoalType(primaryPlayer: Player, secondaryPlayer: Player): [GoalType, AssistType | null];
halfTime(): GameEvent;
gameEnd(): GameEvent;
goal(attackingPrimaryPlayer: Player, attackingSecondaryPlayer: Player): [GoalType, AssistType | null];
simulateEvent(): GameEvent;
}

@@ -92,33 +92,37 @@ "use strict";

}
rebound() {
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,
};
return map[current];
}
handleEvent(event) {
if (event.event === Event_1.Event.Goal) {
this.ballPosition = FieldArea_1.FieldArea.Midfield;
this.ballPossession = this.teamWithoutBall();
}
if (event.event === Event_1.Event.Save || event.event === Event_1.Event.Block) {
const random = Math.floor(Math.random());
if (random > this.reboundChance) {
switch (event.event) {
case Event_1.Event.Goal:
this.ballPosition = FieldArea_1.FieldArea.Midfield;
this.ballPossession = this.teamWithoutBall();
this.ballPosition = FieldArea_1.FieldArea.Defence;
}
break;
case Event_1.Event.Save:
case Event_1.Event.Block:
if (!this.rebound()) {
this.ballPossession = this.teamWithoutBall();
this.ballPosition = FieldArea_1.FieldArea.Defence;
}
break;
case Event_1.Event.Advance:
this.ballPosition = Math.min(this.ballPosition + 1, FieldArea_1.FieldArea.Offense);
break;
case Event_1.Event.Retreat:
this.ballPosition = Math.max(this.ballPosition - 1, FieldArea_1.FieldArea.Defence);
break;
case Event_1.Event.Defence:
this.ballPossession = this.teamWithoutBall();
this.ballPosition = this.reverseSide(this.ballPosition);
break;
}
if (event.event === Event_1.Event.Advance) {
if (this.ballPosition !== FieldArea_1.FieldArea.Offense) {
this.ballPosition += 1;
}
}
if (event.event === Event_1.Event.Retreat) {
if (this.ballPosition !== FieldArea_1.FieldArea.Defence) {
this.ballPosition -= 1;
}
}
if (event.event === Event_1.Event.Defence) {
this.ballPossession = this.teamWithoutBall();
if (this.ballPosition === FieldArea_1.FieldArea.Offense) {
this.ballPosition = FieldArea_1.FieldArea.Defence;
}
else if (this.ballPosition === FieldArea_1.FieldArea.Defence) {
this.ballPosition = FieldArea_1.FieldArea.Offense;
}
}
}

@@ -157,2 +161,20 @@ *eventLoop() {

}
simulateGoalAttempt(attackingTeam, defendingTeam, attacker) {
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const 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);
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);
if (defence > possession) {
return Event_1.Event.Defence;
}
return (action === Action_1.Action.Retreat) ? Event_1.Event.Retreat : Event_1.Event.Possession;
}
simulateAction(action, attacker) {

@@ -165,34 +187,26 @@ if (!this.ballPossession) {

const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (action === Action_1.Action.Advance) {
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (attack > defence) {
return Event_1.Event.Advance;
}
return Event_1.Event.Defence;
return (attack > defence) ? Event_1.Event.Advance : Event_1.Event.Defence;
}
if (action === Action_1.Action.GoalAttempt) {
const attack = attacker.attackRating() + this.random(attackingTeam);
if (attack + (attack * this.extraAttackOnChance) > defence) {
const goalkeeper = defendingTeam.goalkeeperRating() + this.random(defendingTeam);
const attackerRating = attacker.attackRating() + this.random(attackingTeam);
if (attackerRating > goalkeeper) {
return Event_1.Event.Goal;
}
return Event_1.Event.Save;
}
return Event_1.Event.Block;
return this.simulateGoalAttempt(attackingTeam, defendingTeam, attacker);
}
const possession = attackingTeam.possessionRating() + this.random(attackingTeam);
if (defence > possession) {
return 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;
if (shooting > passing && random > 0.5) {
return (random > 0.5) ? AssistType_1.AssistType.Deflection : AssistType_1.AssistType.Rebound;
}
if (action === Action_1.Action.Retreat) {
return Event_1.Event.Retreat;
if (secondaryPlayerAttributes.passing > secondaryPlayerAttributes.crossing && random > 0.5) {
return AssistType_1.AssistType.Pass;
}
return Event_1.Event.Possession;
return AssistType_1.AssistType.Cross;
}
simulateGoalType(primaryPlayer, secondaryPlayer) {
const primaryPlayerAttributes = primaryPlayer.attributes;
const secondaryPlayerAttributes = secondaryPlayer.attributes;
const secondaryPlayerRating = secondaryPlayer.rating();
const assist = Math.random() > 0.5;

@@ -202,37 +216,35 @@ if (!assist) {

}
const primaryPlayerAttributes = primaryPlayer.attributes;
const random = Math.random();
let assistType = null;
if (secondaryPlayerRating.shooting > secondaryPlayerRating.passing && random > 0.5) {
assistType = (random > 0.5) ? AssistType_1.AssistType.Deflection : AssistType_1.AssistType.Rebound;
const assistType = this.simulateAssistType(secondaryPlayer);
return [
(primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType_1.GoalType.Header : [GoalType_1.GoalType.Volley, GoalType_1.GoalType.Shot][Math.floor(Math.random() * 2)],
assistType,
];
}
halfTime() {
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam;
this.ballPosition = FieldArea_1.FieldArea.Midfield;
return this.gameEvent(Event_1.Event.HalfTime);
}
gameEnd() {
this.gameEnded = true;
return this.gameEvent(Event_1.Event.GameEnd);
}
goal(attackingPrimaryPlayer, attackingSecondaryPlayer) {
if (this.ballPossession === this.homeTeam) {
this.gameInfo.homeGoals += 1;
}
else {
if (secondaryPlayerAttributes.passing > secondaryPlayerAttributes.crossing && random > 0.5) {
assistType = AssistType_1.AssistType.Pass;
}
else {
assistType = AssistType_1.AssistType.Cross;
}
this.gameInfo.awayGoals += 1;
}
let goalType = null;
if (assistType === AssistType_1.AssistType.Pass) {
goalType = GoalType_1.GoalType.Shot;
}
else {
goalType = (primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType_1.GoalType.Header : GoalType_1.GoalType.Volley;
}
return [goalType, assistType];
return this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer);
}
simulateEvent() {
if (this.gameInfo.matchMinute == this.gameTime / 2) {
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam;
this.ballPosition = FieldArea_1.FieldArea.Midfield;
return this.gameEvent(Event_1.Event.HalfTime);
}
if (this.gameInfo.matchMinute >= this.gameTime) {
this.gameEnded = true;
return this.gameEvent(Event_1.Event.GameEnd);
}
if (!this.ballPossession) {
if (this.gameInfo.matchMinute == this.gameTime / 2)
return this.halfTime();
if (this.gameInfo.matchMinute >= this.gameTime)
return this.gameEnd();
if (!this.ballPossession)
return this.gameEvent(Event_1.Event.EventLess);
}
const attackingPrimaryPlayer = this.ballPossession.attacker(this.ballPosition);

@@ -242,3 +254,2 @@ const attackingSecondaryPlayer = this.ballPossession.attacker(this.ballPosition, [attackingPrimaryPlayer]);

const defendingPrimaryPlayer = defendingTeam.defender(this.ballPosition);
const defendingSecondaryPlayer = defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]);
const action = this.ballPossession.simulateMove(this.ballPosition, this.gameInfo);

@@ -249,13 +260,7 @@ let goalType = null;

if (event === Event_1.Event.Goal) {
[goalType, assist] = this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer);
if (this.ballPossession === this.homeTeam) {
this.gameInfo.homeGoals += 1;
}
else {
this.gameInfo.awayGoals += 1;
}
[goalType, assist] = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer);
}
return this.gameEvent(event, null, attackingPrimaryPlayer, attackingSecondaryPlayer, defendingPrimaryPlayer, defendingSecondaryPlayer, goalType, assist);
return this.gameEvent(event, null, attackingPrimaryPlayer, attackingSecondaryPlayer, defendingPrimaryPlayer, defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]), goalType, assist);
}
}
exports.default = Engine;

@@ -1,10 +0,10 @@

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

@@ -138,37 +138,44 @@ export default class Engine {

handleEvent(event: GameEvent) {
if (event.event === Event.Goal) {
this.ballPosition = FieldArea.Midfield;
this.ballPossession = this.teamWithoutBall();
}
rebound(): boolean {
return Math.floor(Math.random()) > this.reboundChance;
}
if (event.event === Event.Save || event.event === Event.Block) {
const random = Math.floor(Math.random());
reverseSide(current: FieldArea): FieldArea {
const map = {
[FieldArea.Offense]: FieldArea.Defence,
[FieldArea.Midfield]: FieldArea.Midfield,
[FieldArea.Defence]: FieldArea.Offense,
};
if (random > this.reboundChance) {
return map[current];
}
handleEvent(event: GameEvent) {
switch (event.event) {
case Event.Goal:
this.ballPosition = FieldArea.Midfield;
this.ballPossession = this.teamWithoutBall();
this.ballPosition = FieldArea.Defence;
}
}
if (event.event === Event.Advance) {
if (this.ballPosition !== FieldArea.Offense) {
this.ballPosition += 1;
}
}
break;
case Event.Save:
case Event.Block:
if (!this.rebound()) {
this.ballPossession = this.teamWithoutBall();
this.ballPosition = FieldArea.Defence;
}
if (event.event === Event.Retreat) {
if (this.ballPosition !== FieldArea.Defence) {
this.ballPosition -= 1;
}
}
break;
case Event.Advance:
this.ballPosition = Math.min(this.ballPosition + 1, FieldArea.Offense);
if (event.event === Event.Defence) {
this.ballPossession = this.teamWithoutBall();
break;
case Event.Retreat:
this.ballPosition = Math.max(this.ballPosition - 1, FieldArea.Defence);
if (this.ballPosition === FieldArea.Offense) {
this.ballPosition = FieldArea.Defence;
} else if (this.ballPosition === FieldArea.Defence) {
this.ballPosition = FieldArea.Offense;
}
break;
case Event.Defence:
this.ballPossession = this.teamWithoutBall();
this.ballPosition = this.reverseSide(this.ballPosition);
break;
}

@@ -223,2 +230,27 @@ }

simulateGoalAttempt(attackingTeam: Team, defendingTeam: Team, attacker: Player): Event {
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const 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);
return (attackerRating > goalkeeper) ? Event.Goal : Event.Save;
}
return Event.Block;
}
simulatePossession(attackingTeam: Team, defendingTeam: Team, action: Action): Event {
const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const possession = attackingTeam.possessionRating() + this.random(attackingTeam);
if (defence > possession) {
return Event.Defence;
}
return (action === Action.Retreat) ? Event.Retreat : Event.Possession;
}
simulateAction(action: Action, attacker: Player): Event {

@@ -232,47 +264,34 @@ if (!this.ballPossession) {

const defence = defendingTeam.defenceRating() + this.random(defendingTeam);
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (action === Action.Advance) {
const attack = attackingTeam.attackRating() + this.random(attackingTeam);
if (attack > defence) {
return Event.Advance;
}
return Event.Defence;
return (attack > defence) ? Event.Advance : Event.Defence;
}
if (action === Action.GoalAttempt) {
const attack = attacker.attackRating() + this.random(attackingTeam);
return this.simulateGoalAttempt(attackingTeam, defendingTeam, attacker);
}
if (attack + (attack * this.extraAttackOnChance) > defence) {
const goalkeeper = defendingTeam.goalkeeperRating() + this.random(defendingTeam);
const attackerRating = attacker.attackRating() + this.random(attackingTeam);
return this.simulatePossession(attackingTeam, defendingTeam, action);
}
if (attackerRating > goalkeeper) {
return Event.Goal;
}
simulateAssistType(secondaryPlayer: Player): AssistType | null {
const random = Math.random();
const secondaryPlayerAttributes = secondaryPlayer.attributes;
const secondaryPlayerRating = secondaryPlayer.rating();
const shooting = (secondaryPlayerRating as PlayerRating).shooting;
const passing = (secondaryPlayerRating as PlayerRating).passing;
return Event.Save;
}
return Event.Block;
if (shooting > passing && random > 0.5) {
return (random > 0.5) ? AssistType.Deflection : AssistType.Rebound;
}
const possession = attackingTeam.possessionRating() + this.random(attackingTeam);
if (defence > possession) {
return Event.Defence;
if (secondaryPlayerAttributes.passing > secondaryPlayerAttributes.crossing && random > 0.5) {
return AssistType.Pass;
}
if (action === Action.Retreat) {
return Event.Retreat;
}
return Event.Possession;
return AssistType.Cross;
}
simulateGoalType(primaryPlayer: Player, secondaryPlayer: Player): [GoalType, AssistType | null] {
const primaryPlayerAttributes = primaryPlayer.attributes;
const secondaryPlayerAttributes = secondaryPlayer.attributes;
const secondaryPlayerRating = secondaryPlayer.rating();
const assist = Math.random() > 0.5;

@@ -284,44 +303,40 @@

const primaryPlayerAttributes = primaryPlayer.attributes;
const random = Math.random();
let assistType = null;
const assistType = this.simulateAssistType(secondaryPlayer);
if ((secondaryPlayerRating as PlayerRating).shooting > (secondaryPlayerRating as PlayerRating).passing && random > 0.5) {
assistType = (random > 0.5) ? AssistType.Deflection : AssistType.Rebound;
} else {
if (secondaryPlayerAttributes.passing > secondaryPlayerAttributes.crossing && random > 0.5) {
assistType = AssistType.Pass;
} else {
assistType = AssistType.Cross;
}
}
return [
(primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType.Header : [GoalType.Volley, GoalType.Shot][Math.floor(Math.random() * 2)],
assistType,
];
}
let goalType = null;
halfTime(): GameEvent {
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam;
this.ballPosition = FieldArea.Midfield;
if (assistType === AssistType.Pass) {
goalType = GoalType.Shot;
return this.gameEvent(Event.HalfTime);
}
gameEnd(): GameEvent {
this.gameEnded = true;
return this.gameEvent(Event.GameEnd);
}
goal(attackingPrimaryPlayer: Player, attackingSecondaryPlayer: Player): [GoalType, AssistType | null] {
if (this.ballPossession === this.homeTeam) {
this.gameInfo.homeGoals += 1;
} else {
goalType = (primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType.Header : GoalType.Volley;
this.gameInfo.awayGoals += 1;
}
return [goalType, assistType];
return this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer);
}
simulateEvent(): GameEvent {
if (this.gameInfo.matchMinute == this.gameTime / 2) {
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam;
this.ballPosition = FieldArea.Midfield;
if (this.gameInfo.matchMinute == this.gameTime / 2) return this.halfTime();
if (this.gameInfo.matchMinute >= this.gameTime) return this.gameEnd();
if (!this.ballPossession) return this.gameEvent(Event.EventLess);
return this.gameEvent(Event.HalfTime);
}
if (this.gameInfo.matchMinute >= this.gameTime) {
this.gameEnded = true;
return this.gameEvent(Event.GameEnd);
}
if (!this.ballPossession) {
return this.gameEvent(Event.EventLess);
}
const attackingPrimaryPlayer = this.ballPossession.attacker(this.ballPosition);

@@ -331,19 +346,9 @@ const attackingSecondaryPlayer = this.ballPossession.attacker(this.ballPosition, [attackingPrimaryPlayer]);

const defendingPrimaryPlayer = defendingTeam.defender(this.ballPosition);
const defendingSecondaryPlayer = defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]);
const action = this.ballPossession.simulateMove(this.ballPosition, this.gameInfo);
let goalType = null;
let assist = null;
const event = this.simulateAction(
action,
attackingPrimaryPlayer,
);
const event = this.simulateAction(action, attackingPrimaryPlayer);
if (event === Event.Goal) {
[goalType, assist] = this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer);
if (this.ballPossession === this.homeTeam) {
this.gameInfo.homeGoals += 1;
} else {
this.gameInfo.awayGoals += 1;
}
[goalType, assist] = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer);
}

@@ -357,3 +362,3 @@

defendingPrimaryPlayer,
defendingSecondaryPlayer,
defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]),
goalType,

@@ -360,0 +365,0 @@ assist,

@@ -32,3 +32,3 @@ /// <reference types="node" />

events: GameEvent[];
constructor(homeTeam: Team, awayTeam: Team);
constructor(homeTeam: Team, awayTeam: Team, commentator: Commentator);
start(): void;

@@ -35,0 +35,0 @@ simulate(): void;

@@ -6,3 +6,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const Commentator_1 = __importDefault(require("./Commentator"));
const events_1 = require("events");

@@ -12,3 +11,3 @@ const Engine_1 = __importDefault(require("./Engine"));

class Game extends events_1.EventEmitter {
constructor(homeTeam, awayTeam) {
constructor(homeTeam, awayTeam, commentator) {
super();

@@ -38,3 +37,3 @@ /**

this.awayTeam = awayTeam;
this.commentator = new Commentator_1.default();
this.commentator = commentator;
this.engine = new Engine_1.default(this.homeTeam, this.awayTeam);

@@ -41,0 +40,0 @@ }

@@ -39,3 +39,3 @@ import Team from './Team';

constructor(homeTeam: Team, awayTeam: Team) {
constructor(homeTeam: Team, awayTeam: Team, commentator: Commentator) {
super();

@@ -45,3 +45,3 @@

this.awayTeam = awayTeam;
this.commentator = new Commentator();
this.commentator = commentator;
this.engine = new Engine(this.homeTeam, this.awayTeam);

@@ -48,0 +48,0 @@ }

{
"name": "@bleckert/football-simulator",
"version": "0.0.3",
"version": "0.0.4",
"scripts": {

@@ -16,4 +16,5 @@ "start": "ts-node test/index.ts",

"dependencies": {
"events": "^3.3.0",
"ws": "^7.1.2"
}
}

@@ -95,4 +95,7 @@ import { Position } from './enums/Position';

rating(): PlayerRating | GoalkeeperRating;
averageRating(ratings: number[]): number;
defenceRating(): number;
possessionRating(): number;
attackRating(): number;
attributesAverage(...attributes: number[]): number;
}

@@ -35,9 +35,30 @@ "use strict";

}
averageRating(ratings) {
return ratings.reduce((acc, curr) => acc + curr) / ratings.length;
}
defenceRating() {
const rating = this.rating();
return this.averageRating([
rating.defending,
rating.physique,
rating.pace,
]);
}
possessionRating() {
const rating = this.rating();
return this.averageRating([
rating.dribbling,
rating.passing,
rating.physique,
]);
}
attackRating() {
const rating = this.rating();
return (rating.dribbling
+ rating.pace
+ rating.passing
+ rating.shooting
+ rating.physique) / 5;
return this.averageRating([
rating.dribbling,
rating.pace,
rating.passing,
rating.shooting,
rating.physique,
]);
}

@@ -44,0 +65,0 @@ attributesAverage(...attributes) {

@@ -229,12 +229,36 @@ import {Position} from './enums/Position';

averageRating(ratings: number[]): number {
return ratings.reduce((acc, curr) => acc + curr) / ratings.length;
}
defenceRating(): number {
const rating = this.rating();
return this.averageRating([
(rating as PlayerRating).defending,
(rating as PlayerRating).physique,
(rating as PlayerRating).pace,
]);
}
possessionRating(): number {
const rating = this.rating();
return this.averageRating([
(rating as PlayerRating).dribbling,
(rating as PlayerRating).passing,
(rating as PlayerRating).physique,
]);
}
attackRating(): number {
const rating = this.rating();
return (
(rating as PlayerRating).dribbling
+ (rating as PlayerRating).pace
+ (rating as PlayerRating).passing
+ (rating as PlayerRating).shooting
+ (rating as PlayerRating).physique
) / 5;
return this.averageRating([
(rating as PlayerRating).dribbling,
(rating as PlayerRating).pace,
(rating as PlayerRating).passing,
(rating as PlayerRating).shooting,
(rating as PlayerRating).physique,
]);
}

@@ -241,0 +265,0 @@

import { GameEvent } from './types/GameEvent';
import Player from "./Player";
import Team from "./Team";
export default class Reporter {
gameEvents: GameEvent[];
home: {
goals: number;
possession: number;
shots: number;
shotsOnGoal: number;
};
away: {
goals: number;
possession: number;
shots: number;
shotsOnGoal: number;
};
scoreSheet: {
matchMinute: number;
goalScorer: Player | null;
assist: Player | false;
team: Team;
}[];
constructor(gameEvents: GameEvent[]);
registerEvent: (gameEvent: GameEvent) => void;
getReport(): {
homeGoals: number;
awayGoals: number;
homePossession: number;
awayPossession: number;
homeShots: number;
homeShotsOnGoal: number;
awayShots: number;
awayShotsOnGoal: number;
home: {
possession: number;
goals: number;
shots: number;
shotsOnGoal: number;
};
away: {
possession: number;
goals: number;
shots: number;
shotsOnGoal: number;
};
scoreSheet: {
matchMinute: number;
goalScorer: string | null;
assist: string | false;
team: string;
goalScorer: Player | null;
assist: false | Player;
team: Team;
}[];
};
}

@@ -6,65 +6,43 @@ "use strict";

constructor(gameEvents) {
this.gameEvents = gameEvents;
}
getReport() {
let homeGoals = 0;
let awayGoals = 0;
let homePossession = 0;
let awayPossession = 0;
let homeShots = 0;
let awayShots = 0;
let homeShotsOnGoal = 0;
let awayShotsOnGoal = 0;
const scoreSheet = [];
this.gameEvents.forEach(gameEvent => {
if (gameEvent.attackingTeam && gameEvent.attackingTeam.home) {
homePossession += 1;
this.home = {
goals: 0,
possession: 0,
shots: 0,
shotsOnGoal: 0,
};
this.away = {
goals: 0,
possession: 0,
shots: 0,
shotsOnGoal: 0,
};
this.scoreSheet = [];
this.registerEvent = (gameEvent) => {
const 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;
}
else {
awayPossession += 1;
if ([Event_1.Event.Save, Event_1.Event.Goal].includes(gameEvent.event)) {
this[side].shotsOnGoal += 1;
}
if (gameEvent.event === Event_1.Event.Goal || gameEvent.event === Event_1.Event.Save) {
if (gameEvent.attackingTeam.home) {
homeShots += 1;
homeShotsOnGoal += 1;
}
else {
awayShots += 1;
awayShotsOnGoal += 1;
}
}
if (gameEvent.event === Event_1.Event.Block) {
if (gameEvent.attackingTeam.home) {
homeShots += 1;
}
else {
awayShots += 1;
}
}
if (gameEvent.event === Event_1.Event.Goal) {
if (gameEvent.attackingTeam.home) {
homeGoals += 1;
}
else {
awayGoals += 1;
}
scoreSheet.push({
this[side].goals += 1;
this.scoreSheet.push({
matchMinute: gameEvent.gameInfo.matchMinute,
goalScorer: (gameEvent.attackingPrimaryPlayer) ? `${gameEvent.attackingPrimaryPlayer.info.number}. ${gameEvent.attackingPrimaryPlayer.info.name}` : null,
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer.info.name : false,
team: gameEvent.attackingTeam.name,
goalScorer: gameEvent.attackingPrimaryPlayer,
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer : false,
team: gameEvent.attackingTeam,
});
}
});
const totalPossession = homePossession + awayPossession;
};
this.gameEvents = gameEvents;
}
getReport() {
this.gameEvents.forEach(this.registerEvent);
const totalPossession = this.home.possession + this.away.possession;
return {
homeGoals,
awayGoals,
homePossession: homePossession / totalPossession,
awayPossession: awayPossession / totalPossession,
homeShots,
homeShotsOnGoal,
awayShots,
awayShotsOnGoal,
scoreSheet,
home: { ...this.home, possession: this.home.possession / totalPossession },
away: { ...this.away, possession: this.away.possession / totalPossession },
scoreSheet: this.scoreSheet,
};

@@ -71,0 +49,0 @@ }

@@ -1,7 +0,24 @@

import { GameEvent } from './types/GameEvent';
import { Event } from './enums/Event';
import {GameEvent} from './types/GameEvent';
import {Event} from './enums/Event';
import Player from "./Player";
import Team from "./Team";
export default class Reporter {
gameEvents: GameEvent[];
home = {
goals: 0,
possession: 0,
shots: 0,
shotsOnGoal: 0,
};
away = {
goals: 0,
possession: 0,
shots: 0,
shotsOnGoal: 0,
};
scoreSheet: { matchMinute: number, goalScorer: Player | null, assist: Player | false, team: Team }[] = [];
constructor(gameEvents: GameEvent[]) {

@@ -11,68 +28,38 @@ this.gameEvents = gameEvents;

getReport() {
let homeGoals = 0;
let awayGoals = 0;
let homePossession = 0;
let awayPossession = 0;
let homeShots = 0;
let awayShots = 0;
let homeShotsOnGoal = 0;
let awayShotsOnGoal = 0;
const scoreSheet: { matchMinute: number, goalScorer: string | null, assist: string | false, team: string }[] = [];
registerEvent = (gameEvent: GameEvent): void => {
const side = (gameEvent.attackingTeam && gameEvent.attackingTeam.home) ? 'home' : 'away';
this.gameEvents.forEach(gameEvent => {
if (gameEvent.attackingTeam && gameEvent.attackingTeam.home) {
homePossession += 1;
} else {
awayPossession += 1;
}
this[side].possession += 1;
if (gameEvent.event === Event.Goal || gameEvent.event === Event.Save) {
if (gameEvent.attackingTeam.home) {
homeShots += 1;
homeShotsOnGoal += 1;
} else {
awayShots += 1;
awayShotsOnGoal += 1;
}
}
if ([Event.Save, Event.Goal, Event.Block].includes(gameEvent.event)) {
this[side].shots += 1;
}
if (gameEvent.event === Event.Block) {
if (gameEvent.attackingTeam.home) {
homeShots += 1;
} else {
awayShots += 1;
}
}
if ([Event.Save, Event.Goal].includes(gameEvent.event)) {
this[side].shotsOnGoal += 1;
}
if (gameEvent.event === Event.Goal) {
if (gameEvent.attackingTeam.home) {
homeGoals += 1;
} else {
awayGoals += 1;
}
if (gameEvent.event === Event.Goal) {
this[side].goals += 1;
scoreSheet.push({
matchMinute: gameEvent.gameInfo.matchMinute,
goalScorer: (gameEvent.attackingPrimaryPlayer) ? `${gameEvent.attackingPrimaryPlayer.info.number}. ${gameEvent.attackingPrimaryPlayer.info.name}` : null,
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer.info.name : false,
team: gameEvent.attackingTeam.name,
});
}
});
this.scoreSheet.push({
matchMinute: gameEvent.gameInfo.matchMinute,
goalScorer: gameEvent.attackingPrimaryPlayer,
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer : false,
team: gameEvent.attackingTeam,
});
}
};
const totalPossession = homePossession + awayPossession;
getReport() {
this.gameEvents.forEach(this.registerEvent);
const totalPossession = this.home.possession + this.away.possession;
return {
homeGoals,
awayGoals,
homePossession: homePossession / totalPossession,
awayPossession: awayPossession / totalPossession,
homeShots,
homeShotsOnGoal,
awayShots,
awayShotsOnGoal,
scoreSheet,
home: { ...this.home, possession: this.home.possession / totalPossession },
away: { ...this.away, possession: this.away.possession / totalPossession },
scoreSheet: this.scoreSheet,
};
}
}

@@ -8,9 +8,2 @@ import Player from './Player';

}
interface Weights {
[x: number]: {
defenders: number;
midfielders: number;
attackers: number;
};
}
export default class Team implements TeamInterface {

@@ -28,2 +21,3 @@ players: Player[];

getFieldPlayers(exclude?: Player[]): Player[];
averageRating(map: (player: Player) => number, players?: Player[] | null): number;
goalkeeperRating(): number;

@@ -34,6 +28,5 @@ defenceRating(): number;

simulateMove(ballPosition: FieldArea, gameInfo: GameInfo): Action;
getProbablePlayer(fieldPosition: FieldArea, weights: Weights, exclude?: Player[]): Player;
getProbablePlayer(fieldPosition: FieldArea, attacker: boolean, exclude?: Player[]): Player;
attacker(fieldPosition: FieldArea, exclude?: Player[]): Player;
defender(fieldPosition: FieldArea, exclude?: Player[]): Player;
}
export {};
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -6,2 +9,22 @@ const Position_1 = require("./enums/Position");

const Action_1 = require("./enums/Action");
const getRandomElement_1 = __importDefault(require("./lib/getRandomElement"));
function createWeights(attacker = false) {
return {
[FieldArea_1.FieldArea.Defence]: {
defenders: (attacker) ? 0.6 : 0.1,
midfielders: 0.3,
attackers: (attacker) ? 0.1 : 0.6,
},
[FieldArea_1.FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea_1.FieldArea.Offense]: {
defenders: (attacker) ? 0.1 : 0.6,
midfielders: 0.3,
attackers: (attacker) ? 0.6 : 0.1,
}
};
}
class Team {

@@ -26,51 +49,28 @@ constructor(home, name, players) {

}
averageRating(map, players = null) {
const playersList = (players) ? players : this.getFieldPlayers();
return playersList.map(map).reduce((a, b) => a + b) / playersList.length;
}
goalkeeperRating() {
const goalkeepers = this.getGoalkeepers();
if (!goalkeepers.length) {
return 0;
}
return goalkeepers.map(player => player.ratingAverage()).reduce((a, b) => a + b) / goalkeepers.length;
return this.averageRating(player => player.ratingAverage(), this.getGoalkeepers());
}
defenceRating() {
const players = this.getFieldPlayers();
return players.map(player => {
const rating = player.rating();
return (rating.defending
+ rating.physique
+ rating.pace) / 3;
}).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.defenceRating());
}
possessionRating() {
const players = this.getFieldPlayers();
return players.map(player => {
const rating = player.rating();
return (rating.dribbling
+ rating.passing
+ rating.physique) / 3;
}).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.possessionRating());
}
attackRating() {
const players = this.getFieldPlayers();
return players.map(player => player.attackRating()).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.attackRating());
}
simulateMove(ballPosition, gameInfo) {
const random = Math.floor(Math.random() * 11);
if (ballPosition === FieldArea_1.FieldArea.Offense) {
if (random > 5) {
return Action_1.Action.GoalAttempt;
}
if (random > 3) {
return Action_1.Action.Stay;
}
return Action_1.Action.Retreat;
const options = [[Action_1.Action.GoalAttempt, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
return getRandomElement_1.default(options);
}
if (random > 6) {
return Action_1.Action.Advance;
}
if (random > 3) {
return Action_1.Action.Stay;
}
return Action_1.Action.Retreat;
const options = [[Action_1.Action.Advance, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]];
return getRandomElement_1.default(options);
}
getProbablePlayer(fieldPosition, weights, exclude = []) {
getProbablePlayer(fieldPosition, attacker, exclude = []) {
const weights = createWeights(attacker);
const players = [];

@@ -93,42 +93,8 @@ this.getFieldPlayers(exclude).forEach(player => {

attacker(fieldPosition, exclude = []) {
const weights = {
[FieldArea_1.FieldArea.Defence]: {
defenders: 0.6,
midfielders: 0.3,
attackers: 0.1,
},
[FieldArea_1.FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea_1.FieldArea.Offense]: {
defenders: 0.1,
midfielders: 0.3,
attackers: 0.6,
}
};
return this.getProbablePlayer(fieldPosition, weights, exclude);
return this.getProbablePlayer(fieldPosition, true, exclude);
}
defender(fieldPosition, exclude = []) {
const weights = {
[FieldArea_1.FieldArea.Defence]: {
defenders: 0.1,
midfielders: 0.3,
attackers: 0.6,
},
[FieldArea_1.FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea_1.FieldArea.Offense]: {
defenders: 0.6,
midfielders: 0.3,
attackers: 0.1,
}
};
return this.getProbablePlayer(fieldPosition, weights, exclude);
return this.getProbablePlayer(fieldPosition, false, exclude);
}
}
exports.default = Team;

@@ -1,6 +0,7 @@

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

@@ -19,2 +20,22 @@ export interface TeamInterface {

function createWeights(attacker = false): Weights {
return {
[FieldArea.Defence]: {
defenders: (attacker) ? 0.6 : 0.1,
midfielders: 0.3,
attackers: (attacker) ? 0.1 : 0.6,
},
[FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea.Offense]: {
defenders: (attacker) ? 0.1 : 0.6,
midfielders: 0.3,
attackers: (attacker) ? 0.6 : 0.1,
}
};
}
export default class Team implements TeamInterface {

@@ -47,73 +68,37 @@ players: Player[];

averageRating(map: (player: Player) => number, players: Player[]|null = null): number {
const playersList = (players) ? players : this.getFieldPlayers();
return playersList.map(map).reduce((a, b) => a + b) / playersList.length;
}
goalkeeperRating(): number {
const goalkeepers = this.getGoalkeepers();
if (!goalkeepers.length) {
return 0;
}
return goalkeepers.map(player => player.ratingAverage()).reduce((a, b) => a + b) / goalkeepers.length;
return this.averageRating(player => player.ratingAverage(), this.getGoalkeepers());
}
defenceRating(): number {
const players = this.getFieldPlayers();
return players.map(player => {
const rating = player.rating();
return (
(rating as PlayerRating).defending
+ (rating as PlayerRating).physique
+ (rating as PlayerRating).pace
) / 3;
}).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.defenceRating());
}
possessionRating(): number {
const players = this.getFieldPlayers();
return players.map(player => {
const rating = player.rating();
return (
(rating as PlayerRating).dribbling
+ (rating as PlayerRating).passing
+ (rating as PlayerRating).physique
) / 3;
}).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.possessionRating());
}
attackRating(): number {
const players = this.getFieldPlayers();
return players.map(player => player.attackRating()).reduce((a, b) => a + b) / players.length;
return this.averageRating(player => player.attackRating());
}
simulateMove(ballPosition: FieldArea, gameInfo: GameInfo): Action {
const random = Math.floor(Math.random() * 11);
if (ballPosition === FieldArea.Offense) {
if (random > 5) {
return Action.GoalAttempt;
}
const options = [[Action.GoalAttempt, 50], [Action.Stay, 35], [Action.Retreat, 15]];
if (random > 3) {
return Action.Stay;
}
return Action.Retreat;
return getRandomElement(options);
}
if (random > 6) {
return Action.Advance;
}
const options = [[Action.Advance, 50], [Action.Stay, 35], [Action.Retreat, 15]];
if (random > 3) {
return Action.Stay;
}
return Action.Retreat;
return getRandomElement(options);
}
getProbablePlayer(fieldPosition: FieldArea, weights: Weights, exclude: Player[] = []): Player {
getProbablePlayer(fieldPosition: FieldArea, attacker: boolean, exclude: Player[] = []): Player {
const weights = createWeights(attacker);
const players: { weight: number, player: Player }[] = [];

@@ -138,44 +123,8 @@

attacker(fieldPosition: FieldArea, exclude: Player[] = []): Player {
const weights: Weights = {
[FieldArea.Defence]: {
defenders: 0.6,
midfielders: 0.3,
attackers: 0.1,
},
[FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea.Offense]: {
defenders: 0.1,
midfielders: 0.3,
attackers: 0.6,
}
};
return this.getProbablePlayer(fieldPosition, weights, exclude);
return this.getProbablePlayer(fieldPosition, true, exclude);
}
defender(fieldPosition: FieldArea, exclude: Player[] = []): Player {
const weights = {
[FieldArea.Defence]: {
defenders: 0.1,
midfielders: 0.3,
attackers: 0.6,
},
[FieldArea.Midfield]: {
defenders: 0.25,
midfielders: 0.5,
attackers: 0.25,
},
[FieldArea.Offense]: {
defenders: 0.6,
midfielders: 0.3,
attackers: 0.1,
}
};
return this.getProbablePlayer(fieldPosition, weights, exclude);
return this.getProbablePlayer(fieldPosition, false, exclude);
}
}
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