@bleckert/football-simulator
Advanced tools
Comparing version 0.0.5 to 0.0.6
@@ -1,39 +0,37 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Event_1 = require("./enums/Event"); | ||
var 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, | ||
import { Event } from './enums/Event'; | ||
const importantEvents = [ | ||
Event.GameStart, | ||
Event.Kickoff, | ||
Event.HalfTime, | ||
Event.Advance, | ||
Event.Save, | ||
Event.Block, | ||
Event.Goal, | ||
Event.GameEnd, | ||
Event.Injury, | ||
]; | ||
var Commentator = /** @class */ (function () { | ||
function Commentator(name) { | ||
if (name === void 0) { name = 'Mr. Commentator'; } | ||
export default class Commentator { | ||
name; | ||
constructor(name = 'Mr. Commentator') { | ||
this.name = name; | ||
} | ||
Commentator.prototype.routeComment = function (event) { | ||
routeComment(event) { | ||
switch (event.event) { | ||
case Event_1.Event.GameStart: | ||
case Event.GameStart: | ||
return this.gameStarted(event); | ||
case Event_1.Event.Kickoff: | ||
case Event.Kickoff: | ||
return this.kickoff(event); | ||
case Event_1.Event.HalfTime: | ||
case Event.HalfTime: | ||
return this.halfTime(event); | ||
case Event_1.Event.Advance: | ||
case Event.Advance: | ||
return this.advance(event); | ||
case Event_1.Event.Defence: | ||
case Event.Defence: | ||
return this.defence(event); | ||
case Event_1.Event.Save: | ||
case Event.Save: | ||
return this.save(event); | ||
case Event_1.Event.Block: | ||
case Event.Block: | ||
return this.block(event); | ||
case Event_1.Event.Goal: | ||
case Event.Goal: | ||
return this.goal(event); | ||
case Event_1.Event.GameEnd: | ||
case Event.GameEnd: | ||
return this.gameEnded(event); | ||
@@ -43,5 +41,5 @@ default: | ||
} | ||
}; | ||
Commentator.prototype.comment = function (event) { | ||
var importantEvent = event.event in importantEvents; | ||
} | ||
comment(event) { | ||
const importantEvent = event.event in importantEvents; | ||
if (!importantEvent && Math.random() > 0.5) { | ||
@@ -51,44 +49,42 @@ return null; | ||
return this.routeComment(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) { | ||
} | ||
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) { | ||
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(' '); | ||
}; | ||
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) { | ||
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) { | ||
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 Commentator; | ||
}()); | ||
exports.default = Commentator; | ||
return `The game ends with a draw! Final score ${event.gameInfo.homeGoals}-${event.gameInfo.awayGoals}`; | ||
} | ||
} |
433
Engine.js
@@ -1,100 +0,74 @@ | ||
"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 }); | ||
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; | ||
/** | ||
* Has the game started? | ||
*/ | ||
this.gameStarted = false; | ||
/** | ||
* Has the game ended? | ||
*/ | ||
this.gameEnded = false; | ||
/** | ||
* Number of minutes for a full game | ||
*/ | ||
this.gameTime = 90; | ||
/** | ||
* Number of events per minutes. This decides how eventful the game should be, | ||
* how many actions can take place within a minute. | ||
*/ | ||
this.eventsPerMinute = 1; | ||
/** | ||
* Extra rating points for home team attributes | ||
*/ | ||
this.homeTeamAdvantage = 2; | ||
/** | ||
* All attributes are randomized on each simulation using | ||
* a positive or negative version of this value | ||
*/ | ||
this.randomEffect = 25; | ||
/** | ||
* Chance (0 to 1) to get the ball back after goal attempt. | ||
*/ | ||
this.reboundChance = 0.1; | ||
/** | ||
* Increase attack attributes on goal chance | ||
*/ | ||
this.extraAttackOnChance = 0.05; | ||
/** | ||
* Current team with possession. | ||
*/ | ||
this.ballPossession = null; | ||
/** | ||
* The team that started with the ball. | ||
*/ | ||
this.startedWithBall = null; | ||
/** | ||
* FieldArea enum describing the current ball position. | ||
*/ | ||
this.ballPosition = FieldArea_1.FieldArea.Midfield; | ||
/** | ||
* Array containing all simulations | ||
*/ | ||
this.gameEvents = []; | ||
this.simulate = function () { | ||
if (!_this.gameStarted) { | ||
_this.start(); | ||
} | ||
var event = _this.gameLoop.next(); | ||
if (event.done) { | ||
return; | ||
} | ||
_this.gameEvents.push(event.value); | ||
_this.handleEvent(event.value); | ||
_this.simulate(); | ||
}; | ||
import { Event } from './enums/Event'; | ||
import { FieldArea } from "./enums/FieldArea"; | ||
import { Action } from './enums/Action'; | ||
import { GoalType } from "./enums/GoalType"; | ||
import { AssistType } from "./enums/AssistType"; | ||
export default class Engine { | ||
/** | ||
* Has the game started? | ||
*/ | ||
gameStarted = false; | ||
/** | ||
* Has the game ended? | ||
*/ | ||
gameEnded = false; | ||
/** | ||
* Number of minutes for a full game | ||
*/ | ||
gameTime = 90; | ||
/** | ||
* Number of events per minutes. This decides how eventful the game should be, | ||
* how many actions can take place within a minute. | ||
*/ | ||
eventsPerMinute = 1; | ||
/** | ||
* Extra rating points for home team attributes | ||
*/ | ||
homeTeamAdvantage = 2; | ||
/** | ||
* All attributes are randomized on each simulation using | ||
* a positive or negative version of this value | ||
*/ | ||
randomEffect = 25; | ||
/** | ||
* Chance (0 to 1) to get the ball back after goal attempt. | ||
*/ | ||
reboundChance = 0.1; | ||
/** | ||
* Increase attack attributes on goal chance | ||
*/ | ||
extraAttackOnChance = 0.05; | ||
/** | ||
* Current team with possession. | ||
*/ | ||
ballPossession = null; | ||
/** | ||
* The team that started with the ball. | ||
*/ | ||
startedWithBall = null; | ||
/** | ||
* FieldArea enum describing the current ball position. | ||
*/ | ||
ballPosition = FieldArea.Midfield; | ||
/** | ||
* Game info object describing the current state of the game | ||
*/ | ||
gameInfo; | ||
/** | ||
* Array containing all simulations | ||
*/ | ||
gameEvents = []; | ||
/** | ||
* The game loop | ||
*/ | ||
gameLoop; | ||
/** | ||
* The home team | ||
*/ | ||
homeTeam; | ||
/** | ||
* The away team | ||
*/ | ||
awayTeam; | ||
constructor(homeTeam, awayTeam) { | ||
this.homeTeam = homeTeam; | ||
@@ -109,45 +83,56 @@ this.awayTeam = awayTeam; | ||
} | ||
Engine.prototype.start = function () { | ||
var coinflip = Math.floor(Math.random() * 2) == 0; | ||
start() { | ||
const coinflip = Math.floor(Math.random() * 2) == 0; | ||
this.ballPossession = (coinflip) ? this.homeTeam : this.awayTeam; | ||
this.startedWithBall = this.ballPossession; | ||
this.gameEvents.push(this.gameEvent(Event_1.Event.GameStart, this.ballPossession)); | ||
this.gameEvents.push(this.gameEvent(Event_1.Event.Kickoff, this.ballPossession)); | ||
this.gameEvents.push(this.gameEvent(Event.GameStart, this.ballPossession)); | ||
this.gameEvents.push(this.gameEvent(Event.Kickoff, this.ballPossession)); | ||
this.gameStarted = true; | ||
}; | ||
Engine.prototype.teamWithoutBall = function () { | ||
} | ||
teamWithoutBall() { | ||
return (this.ballPossession === this.homeTeam) ? this.awayTeam : this.homeTeam; | ||
} | ||
simulate = () => { | ||
if (!this.gameStarted) { | ||
this.start(); | ||
} | ||
const event = this.gameLoop.next(); | ||
if (event.done) { | ||
return; | ||
} | ||
this.gameEvents.push(event.value); | ||
this.handleEvent(event.value); | ||
this.simulate(); | ||
}; | ||
Engine.prototype.rebound = function () { | ||
rebound() { | ||
return Math.floor(Math.random()) > this.reboundChance; | ||
}; | ||
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); | ||
} | ||
reverseSide(current) { | ||
const map = { | ||
[FieldArea.Offense]: FieldArea.Defence, | ||
[FieldArea.Midfield]: FieldArea.Midfield, | ||
[FieldArea.Defence]: FieldArea.Offense, | ||
}; | ||
return map[current]; | ||
}; | ||
Engine.prototype.handleEvent = function (event) { | ||
} | ||
handleEvent(event) { | ||
switch (event.event) { | ||
case Event_1.Event.Goal: | ||
this.ballPosition = FieldArea_1.FieldArea.Midfield; | ||
case Event.Goal: | ||
this.ballPosition = FieldArea.Midfield; | ||
this.ballPossession = this.teamWithoutBall(); | ||
break; | ||
case Event_1.Event.Save: | ||
case Event_1.Event.Block: | ||
case Event.Save: | ||
case Event.Block: | ||
if (!this.rebound()) { | ||
this.ballPossession = this.teamWithoutBall(); | ||
this.ballPosition = FieldArea_1.FieldArea.Defence; | ||
this.ballPosition = FieldArea.Defence; | ||
} | ||
break; | ||
case Event_1.Event.Advance: | ||
this.ballPosition = Math.min(this.ballPosition + 1, FieldArea_1.FieldArea.Offense); | ||
case Event.Advance: | ||
this.ballPosition = Math.min(this.ballPosition + 1, FieldArea.Offense); | ||
break; | ||
case Event_1.Event.Retreat: | ||
this.ballPosition = Math.max(this.ballPosition - 1, FieldArea_1.FieldArea.Defence); | ||
case Event.Retreat: | ||
this.ballPosition = Math.max(this.ballPosition - 1, FieldArea.Defence); | ||
break; | ||
case Event_1.Event.Defence: | ||
case Event.Defence: | ||
this.ballPossession = this.teamWithoutBall(); | ||
@@ -157,37 +142,16 @@ this.ballPosition = this.reverseSide(this.ballPosition); | ||
} | ||
}; | ||
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; } | ||
} | ||
*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) { | ||
return { | ||
event: event, | ||
data: data, | ||
attackingPrimaryPlayer: attackingPrimaryPlayer, | ||
attackingSecondaryPlayer: attackingSecondaryPlayer, | ||
defendingPrimaryPlayer: defendingPrimaryPlayer, | ||
defendingSecondaryPlayer: defendingSecondaryPlayer, | ||
event, | ||
data, | ||
attackingPrimaryPlayer, | ||
attackingSecondaryPlayer, | ||
defendingPrimaryPlayer, | ||
defendingSecondaryPlayer, | ||
gameInfo: Object.assign({}, this.gameInfo), | ||
@@ -199,10 +163,10 @@ homeTeam: this.homeTeam, | ||
fieldPosition: this.ballPosition, | ||
goalType: goalType, | ||
assistType: assistType, | ||
goalType, | ||
assistType, | ||
}; | ||
}; | ||
Engine.prototype.random = function (team) { | ||
var min = -this.randomEffect; | ||
var max = this.randomEffect; | ||
var random = Math.floor(Math.random() * (max - min + 1) + min); | ||
} | ||
random(team) { | ||
const min = -this.randomEffect; | ||
const max = this.randomEffect; | ||
let random = Math.floor(Math.random() * (max - min + 1) + min); | ||
if (team === this.homeTeam) { | ||
@@ -212,74 +176,74 @@ random += this.homeTeamAdvantage; | ||
return random; | ||
}; | ||
Engine.prototype.simulateGoalAttempt = function (attackingTeam, defendingTeam, attacker) { | ||
var defence = defendingTeam.defenceRating() + this.random(defendingTeam); | ||
var attack = attackingTeam.attackRating() + this.random(attackingTeam); | ||
} | ||
simulateGoalAttempt(attackingTeam, defendingTeam, attacker) { | ||
const defence = defendingTeam.defenceRating() + this.random(defendingTeam); | ||
const attack = attackingTeam.attackRating() + this.random(attackingTeam); | ||
if (attack + (attack * this.extraAttackOnChance) > defence) { | ||
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; | ||
const goalkeeper = defendingTeam.goalkeeperRating() + this.random(defendingTeam); | ||
const attackerRating = attacker.attackRating() + this.random(attackingTeam); | ||
return (attackerRating > goalkeeper) ? Event.Goal : Event.Save; | ||
} | ||
return Event_1.Event.Block; | ||
}; | ||
Engine.prototype.simulatePossession = function (attackingTeam, defendingTeam, action) { | ||
var defence = defendingTeam.defenceRating() + this.random(defendingTeam); | ||
var possession = attackingTeam.possessionRating() + this.random(attackingTeam); | ||
return 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 Event.Defence; | ||
} | ||
return (action === Action_1.Action.Retreat) ? Event_1.Event.Retreat : Event_1.Event.Possession; | ||
}; | ||
Engine.prototype.simulateAction = function (action, attacker) { | ||
return (action === Action.Retreat) ? Event.Retreat : Event.Possession; | ||
} | ||
simulateAction(action, attacker) { | ||
if (!this.ballPossession) { | ||
return Event_1.Event.EventLess; | ||
return Event.EventLess; | ||
} | ||
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) { | ||
return (attack > defence) ? Event_1.Event.Advance : Event_1.Event.Defence; | ||
const attackingTeam = this.ballPossession; | ||
const defendingTeam = this.teamWithoutBall(); | ||
const defence = defendingTeam.defenceRating() + this.random(defendingTeam); | ||
const attack = attackingTeam.attackRating() + this.random(attackingTeam); | ||
if (action === Action.Advance) { | ||
return (attack > defence) ? Event.Advance : Event.Defence; | ||
} | ||
if (action === Action_1.Action.GoalAttempt) { | ||
if (action === Action.GoalAttempt) { | ||
return this.simulateGoalAttempt(attackingTeam, defendingTeam, attacker); | ||
} | ||
return this.simulatePossession(attackingTeam, defendingTeam, action); | ||
}; | ||
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; | ||
} | ||
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; | ||
return (random > 0.5) ? AssistType.Deflection : AssistType.Rebound; | ||
} | ||
if (secondaryPlayerAttributes.passing > secondaryPlayerAttributes.crossing && random > 0.5) { | ||
return AssistType_1.AssistType.Pass; | ||
return AssistType.Pass; | ||
} | ||
return AssistType_1.AssistType.Cross; | ||
}; | ||
Engine.prototype.simulateGoalType = function (primaryPlayer, secondaryPlayer) { | ||
var assist = Math.random() > 0.5; | ||
return AssistType.Cross; | ||
} | ||
simulateGoalType(primaryPlayer, secondaryPlayer) { | ||
const assist = Math.random() > 0.5; | ||
if (!assist) { | ||
return [GoalType_1.GoalType.Shot, null]; | ||
return [GoalType.Shot, null]; | ||
} | ||
var primaryPlayerAttributes = primaryPlayer.attributes; | ||
var random = Math.random(); | ||
var assistType = this.simulateAssistType(secondaryPlayer); | ||
const primaryPlayerAttributes = primaryPlayer.attributes; | ||
const random = Math.random(); | ||
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)], | ||
(primaryPlayerAttributes.heading > primaryPlayerAttributes.finishing && random > 0.5) ? GoalType.Header : [GoalType.Volley, GoalType.Shot][Math.floor(Math.random() * 2)], | ||
assistType, | ||
]; | ||
}; | ||
Engine.prototype.halfTime = function () { | ||
} | ||
halfTime() { | ||
this.ballPossession = this.startedWithBall === this.homeTeam ? this.awayTeam : this.homeTeam; | ||
this.ballPosition = FieldArea_1.FieldArea.Midfield; | ||
return this.gameEvent(Event_1.Event.HalfTime); | ||
}; | ||
Engine.prototype.gameEnd = function () { | ||
this.ballPosition = FieldArea.Midfield; | ||
return this.gameEvent(Event.HalfTime); | ||
} | ||
gameEnd() { | ||
this.gameEnded = true; | ||
return this.gameEvent(Event_1.Event.GameEnd); | ||
}; | ||
Engine.prototype.goal = function (attackingPrimaryPlayer, attackingSecondaryPlayer) { | ||
return this.gameEvent(Event.GameEnd); | ||
} | ||
goal(attackingPrimaryPlayer, attackingSecondaryPlayer) { | ||
if (this.ballPossession === this.homeTeam) { | ||
@@ -292,5 +256,4 @@ this.gameInfo.homeGoals += 1; | ||
return this.simulateGoalType(attackingPrimaryPlayer, attackingSecondaryPlayer); | ||
}; | ||
Engine.prototype.simulateEvent = function () { | ||
var _a; | ||
} | ||
simulateEvent() { | ||
if (this.gameInfo.matchMinute == this.gameTime / 2) | ||
@@ -301,18 +264,16 @@ return this.halfTime(); | ||
if (!this.ballPossession) | ||
return this.gameEvent(Event_1.Event.EventLess); | ||
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) { | ||
_a = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer), goalType = _a[0], assist = _a[1]; | ||
return this.gameEvent(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); | ||
if (event === Event.Goal) { | ||
[goalType, assist] = this.goal(attackingPrimaryPlayer, attackingSecondaryPlayer); | ||
} | ||
return this.gameEvent(event, null, attackingPrimaryPlayer, attackingSecondaryPlayer, defendingPrimaryPlayer, defendingTeam.defender(this.ballPosition, [defendingPrimaryPlayer]), goalType, assist); | ||
}; | ||
return Engine; | ||
}()); | ||
exports.default = Engine; | ||
} | ||
} |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Action = void 0; | ||
var Action; | ||
export var Action; | ||
(function (Action) { | ||
@@ -10,2 +7,2 @@ Action[Action["Advance"] = 0] = "Advance"; | ||
Action[Action["GoalAttempt"] = 3] = "GoalAttempt"; | ||
})(Action = exports.Action || (exports.Action = {})); | ||
})(Action || (Action = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AssistType = void 0; | ||
var AssistType; | ||
export var AssistType; | ||
(function (AssistType) { | ||
@@ -10,2 +7,2 @@ AssistType[AssistType["Pass"] = 0] = "Pass"; | ||
AssistType[AssistType["Deflection"] = 3] = "Deflection"; | ||
})(AssistType = exports.AssistType || (exports.AssistType = {})); | ||
})(AssistType || (AssistType = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DefenceType = void 0; | ||
var DefenceType; | ||
export var DefenceType; | ||
(function (DefenceType) { | ||
@@ -9,2 +6,2 @@ DefenceType[DefenceType["SlideTackle"] = 0] = "SlideTackle"; | ||
DefenceType[DefenceType["AirDuel"] = 2] = "AirDuel"; | ||
})(DefenceType = exports.DefenceType || (exports.DefenceType = {})); | ||
})(DefenceType || (DefenceType = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Event = void 0; | ||
var Event; | ||
export var Event; | ||
(function (Event) { | ||
@@ -22,2 +19,2 @@ Event[Event["GameStart"] = 0] = "GameStart"; | ||
Event[Event["FreeKick"] = 15] = "FreeKick"; | ||
})(Event = exports.Event || (exports.Event = {})); | ||
})(Event || (Event = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FieldArea = void 0; | ||
var FieldArea; | ||
export var FieldArea; | ||
(function (FieldArea) { | ||
@@ -9,2 +6,2 @@ FieldArea[FieldArea["Defence"] = 0] = "Defence"; | ||
FieldArea[FieldArea["Offense"] = 2] = "Offense"; | ||
})(FieldArea = exports.FieldArea || (exports.FieldArea = {})); | ||
})(FieldArea || (FieldArea = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.GoalType = void 0; | ||
var GoalType; | ||
export var GoalType; | ||
(function (GoalType) { | ||
@@ -9,2 +6,2 @@ GoalType[GoalType["Shot"] = 0] = "Shot"; | ||
GoalType[GoalType["Header"] = 2] = "Header"; | ||
})(GoalType = exports.GoalType || (exports.GoalType = {})); | ||
})(GoalType || (GoalType = {})); |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.attackPositions = exports.midfieldPositions = exports.defencePositions = exports.Position = void 0; | ||
var Position; | ||
export var Position; | ||
(function (Position) { | ||
@@ -31,4 +28,4 @@ Position[Position["GK"] = 0] = "GK"; | ||
Position[Position["ST"] = 24] = "ST"; | ||
})(Position = exports.Position || (exports.Position = {})); | ||
exports.defencePositions = [ | ||
})(Position || (Position = {})); | ||
export const defencePositions = [ | ||
Position.LB, | ||
@@ -41,3 +38,3 @@ Position.LCB, | ||
]; | ||
exports.midfieldPositions = [ | ||
export const midfieldPositions = [ | ||
Position.LDM, | ||
@@ -53,3 +50,3 @@ Position.DM, | ||
]; | ||
exports.attackPositions = [ | ||
export const attackPositions = [ | ||
Position.LW, | ||
@@ -56,0 +53,0 @@ Position.LCOM, |
122
Game.js
@@ -1,60 +0,43 @@ | ||
"use strict"; | ||
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 }); | ||
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; | ||
/** | ||
* Events copy | ||
*/ | ||
_this.events = []; | ||
_this.loop = function () { | ||
var event = _this.events.shift(); | ||
if (!event) { | ||
_this.report(); | ||
return; | ||
} | ||
_this.emit('comment', { | ||
text: _this.commentator.comment(event), | ||
gameInfo: event.gameInfo, | ||
}); | ||
_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); | ||
return _this; | ||
import { EventEmitter } from 'events'; | ||
import Engine from './Engine'; | ||
import Reporter from './Reporter'; | ||
export default class Game extends EventEmitter { | ||
/** | ||
* Milliseconds between each simulation | ||
*/ | ||
gameSpeed = 500; | ||
/** | ||
* Engine | ||
*/ | ||
engine; | ||
/** | ||
* The home team | ||
*/ | ||
homeTeam; | ||
/** | ||
* The away team | ||
*/ | ||
awayTeam; | ||
/** | ||
* The commentator | ||
*/ | ||
commentator; | ||
/** | ||
* Events copy | ||
*/ | ||
events = []; | ||
constructor(homeTeam, awayTeam, commentator) { | ||
super(); | ||
this.homeTeam = homeTeam; | ||
this.awayTeam = awayTeam; | ||
this.commentator = commentator; | ||
this.engine = new Engine(this.homeTeam, this.awayTeam); | ||
} | ||
Game.prototype.start = function () { | ||
var _this = this; | ||
start() { | ||
this.engine.start(); | ||
this.events = this.engine.gameEvents.slice(); | ||
this.events.forEach(function (gameEvent) { | ||
_this.emit('comment', { | ||
text: _this.commentator.comment(gameEvent), | ||
gameInfo: _this.engine.gameInfo, | ||
this.events.forEach(gameEvent => { | ||
this.emit('comment', { | ||
text: this.commentator.comment(gameEvent), | ||
gameInfo: this.engine.gameInfo, | ||
}); | ||
@@ -65,14 +48,25 @@ }); | ||
this.simulate(); | ||
}; | ||
Game.prototype.simulate = function () { | ||
} | ||
simulate() { | ||
this.engine.simulate(); | ||
this.events = this.engine.gameEvents.slice(); | ||
this.loop(); | ||
} | ||
loop = () => { | ||
const event = this.events.shift(); | ||
if (!event) { | ||
this.report(); | ||
return; | ||
} | ||
this.emit('comment', { | ||
text: this.commentator.comment(event), | ||
gameInfo: event.gameInfo, | ||
}); | ||
this.emit('event', event); | ||
setTimeout(this.loop, this.gameSpeed); | ||
}; | ||
Game.prototype.report = function () { | ||
var reporter = new Reporter_1.default(this.engine.gameEvents); | ||
report() { | ||
const reporter = new Reporter(this.engine.gameEvents); | ||
this.emit('report', reporter.getReport()); | ||
}; | ||
return Game; | ||
}(events_1.EventEmitter)); | ||
exports.default = Game; | ||
} | ||
} |
@@ -1,10 +0,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function getRandomElement(options) { | ||
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); }, []); | ||
export default function getRandomElement(options) { | ||
const weighted = options.map(([action, weight]) => Array(weight).fill(action)).reduce((c, v) => c.concat(v), []); | ||
return weighted[Math.floor((Math.random() * weighted.length))]; | ||
} | ||
exports.default = getRandomElement; |
{ | ||
"name": "@bleckert/football-simulator", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "start": "ts-node test/index.ts", |
@@ -1,6 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Position_1 = require("./enums/Position"); | ||
var Player = /** @class */ (function () { | ||
function Player(info, biometrics, attributes, position) { | ||
import { Position } from './enums/Position'; | ||
export default class Player { | ||
info; | ||
biometrics; | ||
attributes; | ||
position; | ||
constructor(info, biometrics, attributes, position) { | ||
this.info = info; | ||
@@ -11,8 +13,8 @@ this.biometrics = biometrics; | ||
} | ||
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) { | ||
ratingAverage() { | ||
const rating = this.rating(); | ||
return Object.values(rating).reduce((a, b) => a + b) / Object.values(rating).length; | ||
} | ||
rating() { | ||
if (this.position === Position.GK) { | ||
return { | ||
@@ -35,8 +37,8 @@ diving: this.attributesAverage(this.attributes.agility, this.attributes.balance, this.attributes.naturalFitness, this.attributes.strength), | ||
}; | ||
}; | ||
Player.prototype.averageRating = function (ratings) { | ||
return ratings.reduce(function (acc, curr) { return acc + curr; }) / ratings.length; | ||
}; | ||
Player.prototype.defenceRating = function () { | ||
var rating = this.rating(); | ||
} | ||
averageRating(ratings) { | ||
return ratings.reduce((acc, curr) => acc + curr) / ratings.length; | ||
} | ||
defenceRating() { | ||
const rating = this.rating(); | ||
return this.averageRating([ | ||
@@ -47,5 +49,5 @@ rating.defending, | ||
]); | ||
}; | ||
Player.prototype.possessionRating = function () { | ||
var rating = this.rating(); | ||
} | ||
possessionRating() { | ||
const rating = this.rating(); | ||
return this.averageRating([ | ||
@@ -56,5 +58,5 @@ rating.dribbling, | ||
]); | ||
}; | ||
Player.prototype.attackRating = function () { | ||
var rating = this.rating(); | ||
} | ||
attackRating() { | ||
const rating = this.rating(); | ||
return this.averageRating([ | ||
@@ -67,12 +69,6 @@ rating.dribbling, | ||
]); | ||
}; | ||
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; | ||
} | ||
attributesAverage(...attributes) { | ||
return (attributes.reduce((a, b) => a + b) / attributes.length) / 20 * 100; | ||
} | ||
} |
@@ -1,63 +0,48 @@ | ||
"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; | ||
import { Event } from './enums/Event'; | ||
export default class Reporter { | ||
gameEvents; | ||
home = { | ||
goals: 0, | ||
possession: 0, | ||
shots: 0, | ||
shotsOnGoal: 0, | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Event_1 = require("./enums/Event"); | ||
var Reporter = /** @class */ (function () { | ||
function Reporter(gameEvents) { | ||
var _this = this; | ||
this.home = { | ||
goals: 0, | ||
possession: 0, | ||
shots: 0, | ||
shotsOnGoal: 0, | ||
}; | ||
this.away = { | ||
goals: 0, | ||
possession: 0, | ||
shots: 0, | ||
shotsOnGoal: 0, | ||
}; | ||
this.scoreSheet = []; | ||
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; | ||
} | ||
if ([Event_1.Event.Save, Event_1.Event.Goal].includes(gameEvent.event)) { | ||
_this[side].shotsOnGoal += 1; | ||
} | ||
if (gameEvent.event === Event_1.Event.Goal) { | ||
_this[side].goals += 1; | ||
_this.scoreSheet.push({ | ||
matchMinute: gameEvent.gameInfo.matchMinute, | ||
goalScorer: gameEvent.attackingPrimaryPlayer, | ||
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer : false, | ||
team: gameEvent.attackingTeam, | ||
}); | ||
} | ||
}; | ||
away = { | ||
goals: 0, | ||
possession: 0, | ||
shots: 0, | ||
shotsOnGoal: 0, | ||
}; | ||
scoreSheet = []; | ||
constructor(gameEvents) { | ||
this.gameEvents = gameEvents; | ||
} | ||
Reporter.prototype.getReport = function () { | ||
registerEvent = (gameEvent) => { | ||
const side = (gameEvent.attackingTeam && gameEvent.attackingTeam.home) ? 'home' : 'away'; | ||
this[side].possession += 1; | ||
if ([Event.Save, Event.Goal, Event.Block].includes(gameEvent.event)) { | ||
this[side].shots += 1; | ||
} | ||
if ([Event.Save, Event.Goal].includes(gameEvent.event)) { | ||
this[side].shotsOnGoal += 1; | ||
} | ||
if (gameEvent.event === Event.Goal) { | ||
this[side].goals += 1; | ||
this.scoreSheet.push({ | ||
matchMinute: gameEvent.gameInfo.matchMinute, | ||
goalScorer: gameEvent.attackingPrimaryPlayer, | ||
assist: (gameEvent.assistType && gameEvent.attackingSecondaryPlayer) ? gameEvent.attackingSecondaryPlayer : false, | ||
team: gameEvent.attackingTeam, | ||
}); | ||
} | ||
}; | ||
getReport() { | ||
this.gameEvents.forEach(this.registerEvent); | ||
var totalPossession = this.home.possession + this.away.possession; | ||
const totalPossession = this.home.possession + this.away.possession; | ||
return { | ||
home: __assign(__assign({}, this.home), { possession: this.home.possession / totalPossession }), | ||
away: __assign(__assign({}, this.away), { possession: this.away.possession / totalPossession }), | ||
home: { ...this.home, possession: this.home.possession / totalPossession }, | ||
away: { ...this.away, possession: this.away.possession / totalPossession }, | ||
scoreSheet: this.scoreSheet, | ||
}; | ||
}; | ||
return Reporter; | ||
}()); | ||
exports.default = Reporter; | ||
} | ||
} |
136
Team.js
@@ -1,12 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
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] = { | ||
import { defencePositions, midfieldPositions, Position } from './enums/Position'; | ||
import { FieldArea } from "./enums/FieldArea"; | ||
import { Action } from "./enums/Action"; | ||
import getRandomElement from "./lib/getRandomElement"; | ||
function createWeights(attacker = false) { | ||
return { | ||
[FieldArea.Defence]: { | ||
defenders: (attacker) ? 0.6 : 0.1, | ||
@@ -16,3 +12,3 @@ midfielders: 0.3, | ||
}, | ||
_a[FieldArea_1.FieldArea.Midfield] = { | ||
[FieldArea.Midfield]: { | ||
defenders: 0.25, | ||
@@ -22,11 +18,14 @@ midfielders: 0.5, | ||
}, | ||
_a[FieldArea_1.FieldArea.Offense] = { | ||
[FieldArea.Offense]: { | ||
defenders: (attacker) ? 0.1 : 0.6, | ||
midfielders: 0.3, | ||
attackers: (attacker) ? 0.6 : 0.1, | ||
}, | ||
_a; | ||
} | ||
}; | ||
} | ||
var Team = /** @class */ (function () { | ||
function Team(home, name, players) { | ||
export default class Team { | ||
players; | ||
home; | ||
name; | ||
constructor(home, name, players) { | ||
this.home = home; | ||
@@ -36,3 +35,3 @@ this.name = name; | ||
} | ||
Team.prototype.rating = function () { | ||
rating() { | ||
return { | ||
@@ -43,64 +42,57 @@ goalkeeping: this.goalkeeperRating(), | ||
}; | ||
}; | ||
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) { | ||
var options_1 = [[Action_1.Action.GoalAttempt, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]]; | ||
return getRandomElement_1.default(options_1); | ||
} | ||
getGoalkeepers() { | ||
return this.players.filter(player => player.position === Position.GK); | ||
} | ||
getFieldPlayers(exclude = []) { | ||
return this.players.filter(player => player.position !== 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) { | ||
if (ballPosition === FieldArea.Offense) { | ||
const options = [[Action.GoalAttempt, 50], [Action.Stay, 35], [Action.Retreat, 15]]; | ||
return getRandomElement(options); | ||
} | ||
var options = [[Action_1.Action.Advance, 50], [Action_1.Action.Stay, 35], [Action_1.Action.Retreat, 15]]; | ||
return getRandomElement_1.default(options); | ||
}; | ||
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: player, weight: weights[fieldPosition].defenders }); | ||
const options = [[Action.Advance, 50], [Action.Stay, 35], [Action.Retreat, 15]]; | ||
return getRandomElement(options); | ||
} | ||
getProbablePlayer(fieldPosition, attacker, exclude = []) { | ||
const weights = createWeights(attacker); | ||
const players = []; | ||
this.getFieldPlayers(exclude).forEach(player => { | ||
if (defencePositions.indexOf(player.position) > -1) { | ||
players.push({ player, weight: weights[fieldPosition].defenders }); | ||
} | ||
else if (Position_1.midfieldPositions.indexOf(player.position) > -1) { | ||
players.push({ player: player, weight: weights[fieldPosition].midfielders }); | ||
else if (midfieldPositions.indexOf(player.position) > -1) { | ||
players.push({ player, weight: weights[fieldPosition].midfielders }); | ||
} | ||
else { | ||
players.push({ player: player, weight: weights[fieldPosition].attackers }); | ||
players.push({ player, weight: weights[fieldPosition].attackers }); | ||
} | ||
}); | ||
var random = Math.min(Math.random(), 0.6); | ||
var foundPlayers = players.filter(function (player) { return player.weight >= random; }).map(function (obj) { return obj.player; }); | ||
const random = Math.min(Math.random(), 0.6); | ||
const foundPlayers = players.filter(player => player.weight >= random).map(obj => obj.player); | ||
return foundPlayers[Math.floor(Math.random() * foundPlayers.length)]; | ||
}; | ||
Team.prototype.attacker = function (fieldPosition, exclude) { | ||
if (exclude === void 0) { exclude = []; } | ||
} | ||
attacker(fieldPosition, exclude = []) { | ||
return this.getProbablePlayer(fieldPosition, true, exclude); | ||
}; | ||
Team.prototype.defender = function (fieldPosition, exclude) { | ||
if (exclude === void 0) { exclude = []; } | ||
} | ||
defender(fieldPosition, exclude = []) { | ||
return this.getProbablePlayer(fieldPosition, false, exclude); | ||
}; | ||
return Team; | ||
}()); | ||
exports.default = Team; | ||
} | ||
} |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; |
74579
2178