gallagheraiden / footballsimulationengine Goto Github PK
View Code? Open in Web Editor NEWA node js football simulation module
License: MIT License
A node js football simulation module
License: MIT License
The ball currently moves instantaneously rather than over a given time. This should move over time alongside player movement.
The following process can be completed:
The code base includes a lot of promises and callbacks, and these can be further simplified with async/await. This would increase readability a lot.
There are also further refactoring patterns that could be applied. I would love to lend a hand for this.
@GallagherAiden can you provide a fixture data to get the engine started? The requirements for initiateGame
, with two full teams with correct starting positions and a pitch JSON?
One has to figure out the whole team structure and starting positions only by looking at the README, and as the codebase is growing rapidly, it's hard to keep track.
Currently my code is breaking because I'm missing fitness property from players. It would be great if you could provide an up-to-date fixture json that evolves with the codebase, so the users can take and use them right away.
I simulated serveral matches with two teams.
I found a problem.
For example a match ended 2-0.
If I search in the players stats I found only 1 goal.
I have found that in the function where is set the scorer, the player who made the last touch is in the opposite team.
This is an autogoal?
I have seen that in the function getInterceptTrajectory of file playerMovement.js the variable highNumb is always a integer but somethings it became float and this cause a crash in the row with "new Array()"
There is a notice of this project being on hold pending updates. Any ETA on that?
Expand on the already created test cases:
(node:8693) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'map' of undefined
at resolveDeflection (/Users/aideng/Documents/football/footballsimulationengine/lib/ballMovement.js:387:43)
at resolveBallMovement (/Users/aideng/Documents/football/footballsimulationengine/lib/ballMovement.js:297:24)
at Object.ballKicked (/Users/aideng/Documents/football/footballsimulationengine/lib/ballMovement.js:109:16)
at Object.decideMovement (/Users/aideng/Documents/football/footballsimulationengine/lib/playerMovement.js:177:42)
[ 'Closest Player to ball: Arthur Johnson',
'Closest Player to ball: Emma Smith',
'Slide tackle attempted by: Arthur Johnson',
'Foul against: Emma Smith',
'freekick to: ThisTeam' ]
(node:19569) UnhandledPromiseRejectionWarning: Error: Player Peter Johnson not on the pitch Y: -61
at Object.validatePlayerPositions (/Users/aideng/Documents/football/footballsimulationengine/lib/validate.js:145:13)
at Object.playIteration (/Users/aideng/Documents/football/footballsimulationengine/engine.js:43:12)
at iterateHalf (/Users/aideng/Documents/football/premierLeagueSimulator/completeMatch.js:31:42)
(node:19569) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:19569) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Hello i'm trying this algorithm but i noticed that fouls are most of the times near to 0..
What i'm doing wrong in configuration?
var pitch = {
"pitchWidth": 120,
"pitchHeight": 600
};
var pos_coords = [
[60,0],
[20,60],
[100,60],
[50,50],
[70,50],
[20,200],
[100,200],
[60,150],
[60,250],
[50,290],
[70,300],
];
var pos = [
"GK",
"TS",
"TD",
"DC",
"DC",
"ES",
"ED",
"CC",
"COC",
"ATT",
"ATT"
];
Players are generated for testing purpose with this function
var generatePlayers = function(name, overall) {
overall = parseInt(overall);
var players = new Array();
for (var i = 1;i<= 11; i++) {
players.push({
"name": "Player_" + name + "_" + i,
"position": pos[i-1],
"rating": overall,
"skill": {
"passing": overall,
"shooting": overall,
"tackling": overall,
"saving": overall,
"agility": overall,
"strength": overall,
"penalty_taking": overall,
"jumping": (120+overall)
},
"startPOS": pos_coords[i-1],
"injured": false
});
}
return players;
}
Usually i test it with overall between 60 and 100
But results are like this:
Home
{"goals":2,"shots":6,"corners":8,"freekicks":0,"penalties":0,"fouls":0}
Away:
{"goals":1,"shots":6,"corners":3,"freekicks":0,"penalties":0,"fouls":0}
I'm running without any graphical interface, simulating the whole match through promise loops (waiting resolve of every promise) and starting automatically the second-half
For: 45/60 iterations per half
Thank you
1 How many games did you simulate, and did the results match the normal distribution?
2 How many moves do you think are more cooperative in a game? Can 5000 be?
3 What should I do if I want to change the point on the court to the player's name or image?
Thank you
If the players have the same name the system gets confused. Should use a unique player identity
startPOS actually represents current position e.g. should be currentPOS
relativePOS presents intent e.g. intentPOS
Improve player movement to make the game more interactive.
Either:
At times players are one on one with the keeper but do not shoot and instead pass back to the keeper. This should be rare
new corner process should be:
a. Corner taker kicks randomly into opposition box (or a player in final third)
b. Ball moves over iterations
c. Check interception against player height vs ball height
Defending teams should mark opposition players when in own half
pass matchDetails into injury calls
intentPOS: [ 340, undefined ]
players are running off of the pitch, this should be impossible
Currently a player shoots and scores. The ball movement should play out with a check on if a goal has been scored over instantaneous results
Hey,
great Project! But which impact has the Player Rating?
Have a nice day,
Jappi00
30 years ago there were paid phone line games where a commentator would present the match, and you could press numbers on your phone to either pass, shoot, dribble or tackle the ball depending on the situation. Then the engine would tell you the outcome of your action, and you were trying to win the match.
20 years ago I was playing with an mIRC bot that employed the same logic between two human players — the bot would present the match's important positions, and players would either pass, shoot, dribble or tackle the ball by typing into the channel. The bot then would decide the outcome. We had a lot of fun doing entire leagues, even nominating top scorers and top assists.
Growing up with these, for some time I'm in the search for such an engine that I can turn into a similar game for modern chat applications like Slack, Telegram, Facebook Messenger and even iMessage. footballSimulationEngine looks like a great start. Would you be up for collaboration on such a game? If not, can I fork your engine and use it?
Hello Aiden!
Thanks for the promising work! I have seen that you released 2.0.1 to npm, but it's not available in GitHub. Could you push the changes? I've downloaded the new version from npm and got the changes, but it would be better if you could push your own version.
Sometimes I have see that in the resolveTacke and resolveSlide functions of file lib\actions.js the variable "thatPlayer" is undefined and so after few row the engine goes in error.
I had a fix on them. I have put a check if a player is undefined, exit from the function.
depends on: #11
Check matchDetails - teams - players - actions. If "none" - process actions as normal, otherwise set the action as that provided by the array.
Error: TypeError: Cannot read property 'map' of undefined
at resolveDeflection (/Users/.../footballsimulationengine/lib/ballMovement.js:387:43)
at resolveBallMovement (/Users/.../footballsimulationengine/lib/ballMovement.js:297:24)
at Object.ballPassed (/Users/...l/footballsimulationengine/lib/ballMovement.js:488:16)
at Object.decideMovement (/Users/.../footballsimulationengine/lib/playerMovement.js:183:42)
at Object.playIteration (/Users/.../footballsimulationengine/engine.js:52:31)
at /Users/.../footballsimulationexample/server.js:64:17
passing currently is random:
let targetPlayer = playersInDistance[common.getRandomNumber(0, (playersInDistance.length - 1))]
This is a massive detriment on the game play. Instead a number of changes to be made, some now, some later:
Players might be injured or sent off. The code should handle this.
The ball movement resolution sometimes work great, but most of the time it still teleports to a new location. I suspect it's because of the power applied to the ball — this might need further tuning. Given how small the players can move within an iteration, the ball should slow down significantly.
hi all,
this is not at all an issue but rather me looking for help.
what is actually the difference between startPos, originPos & relativePos?
if I were to update a player's position on the pitch by each single iteration on timer tick, which value should I use?
thanks in advance for your help!
Hello,
I wanted to test with a team perso.
My players go directly to their camps, next to the goalkeeper and nothing happens ... the ball always goes to the bottom right side and nothing happens.
What is my problem?
Thank you
Team 1
{
"name": "no",
"manager": "manager no",
"players": [
{
"name": "Rodrick Helmy",
"position": "GK",
"rating": 77,
"injured": false,
"startPOS": [
60,
0
],
"skill": {
"passing": 81,
"shooting": 68,
"tackling": 68,
"saving": 18,
"agility": 75,
"strength": 84,
"penalty_taking": 68,
"jumping": 180
},
"fitness": 100
},
{
"name": "Antwan Rousselle",
"position": "LB",
"rating": 77,
"injured": false,
"startPOS": [
30,
20
],
"skill": {
"passing": 80,
"shooting": 68,
"tackling": 68,
"saving": 16,
"agility": 74.5,
"strength": 83,
"penalty_taking": 68,
"jumping": 160
},
"fitness": 100
},
{
"name": "Malcom Haessig",
"position": "CB",
"rating": 76,
"injured": false,
"startPOS": [
50,
60
],
"skill": {
"passing": 81,
"shooting": 65,
"tackling": 68,
"saving": 19,
"agility": 75,
"strength": 82,
"penalty_taking": 65,
"jumping": 190
},
"fitness": 100
},
{
"name": "Rico Vornes",
"position": "CB",
"rating": 77,
"injured": false,
"startPOS": [
50,
20
],
"skill": {
"passing": 82,
"shooting": 65,
"tackling": 51,
"saving": 19,
"agility": 81.5,
"strength": 68,
"penalty_taking": 65,
"jumping": 190
},
"fitness": 100
},
{
"name": "Mikel Emberling",
"position": "RB",
"rating": 78,
"injured": false,
"startPOS": [
90,
20
],
"skill": {
"passing": 83,
"shooting": 68,
"tackling": 53,
"saving": 15,
"agility": 81.5,
"strength": 65,
"penalty_taking": 68,
"jumping": 150
},
"fitness": 100
},
{
"name": "Russell Walmer",
"position": "LM",
"rating": 75,
"injured": false,
"startPOS": [
30,
120
],
"skill": {
"passing": 69,
"shooting": 80,
"tackling": 50,
"saving": 17,
"agility": 68,
"strength": 80,
"penalty_taking": 80,
"jumping": 170
},
"fitness": 100
},
{
"name": "Bernardo Balent",
"position": "CAM",
"rating": 74,
"injured": false,
"startPOS": [
50,
140
],
"skill": {
"passing": 68,
"shooting": 52,
"tackling": 54,
"saving": 81,
"agility": 50,
"strength": 66,
"penalty_taking": 52,
"jumping": 181
},
"fitness": 100
},
{
"name": "Isreal Lebaugh",
"position": "CDM",
"rating": 79,
"injured": false,
"startPOS": [
50,
100
],
"skill": {
"passing": 80,
"shooting": 54,
"tackling": 82,
"saving": 15,
"agility": 59,
"strength": 82,
"penalty_taking": 54,
"jumping": 150
},
"fitness": 100
},
{
"name": "Demetrius Colom",
"position": "RM",
"rating": 79,
"injured": false,
"startPOS": [
90,
120
],
"skill": {
"passing": 81,
"shooting": 50,
"tackling": 84,
"saving": 17,
"agility": 58.5,
"strength": 80,
"penalty_taking": 50,
"jumping": 170
},
"fitness": 100
},
{
"name": "Caleb Fukui",
"position": "ST",
"rating": 79,
"injured": false,
"startPOS": [
50,
270
],
"skill": {
"passing": 83,
"shooting": 51,
"tackling": 83,
"saving": 16,
"agility": 59,
"strength": 81,
"penalty_taking": 51,
"jumping": 160
},
"fitness": 100
},
{
"name": "Romeo Pelch",
"position": "ST",
"rating": 76,
"injured": false,
"startPOS": [
50,
280
],
"skill": {
"passing": 81,
"shooting": 67,
"tackling": 68,
"saving": 17,
"agility": 74,
"strength": 82,
"penalty_taking": 67,
"jumping": 170
},
"fitness": 100
}
]
}
{
"name": "no",
"manager": "manager no2",
"players": [
{
"name": "Rory Roya",
"position": "GK",
"rating": 73,
"injured": false,
"startPOS": [
60,
0
],
"skill": {
"passing": 66,
"shooting": 50,
"tackling": 53,
"saving": 82,
"agility": 51.5,
"strength": 65,
"penalty_taking": 50,
"jumping": 182
},
"fitness": 100
},
{
"name": "Isaias Apa",
"position": "LB",
"rating": 79,
"injured": false,
"startPOS": [
30,
20
],
"skill": {
"passing": 83,
"shooting": 52,
"tackling": 83,
"saving": 15,
"agility": 60,
"strength": 80,
"penalty_taking": 52,
"jumping": 150
},
"fitness": 100
},
{
"name": "Irving Stephanie",
"position": "CB",
"rating": 79,
"injured": false,
"startPOS": [
50,
40
],
"skill": {
"passing": 83,
"shooting": 51,
"tackling": 82,
"saving": 16,
"agility": 58.5,
"strength": 81,
"penalty_taking": 51,
"jumping": 160
},
"fitness": 100
},
{
"name": "Cody Ahl",
"position": "CB",
"rating": 81,
"injured": false,
"startPOS": [
50,
20
],
"skill": {
"passing": 84,
"shooting": 52,
"tackling": 84,
"saving": 17,
"agility": 59,
"strength": 83,
"penalty_taking": 52,
"jumping": 170
},
"fitness": 100
},
{
"name": "Ivory Bornmann",
"position": "RB",
"rating": 78,
"injured": false,
"startPOS": [
90,
20
],
"skill": {
"passing": 81,
"shooting": 54,
"tackling": 80,
"saving": 16,
"agility": 58.5,
"strength": 82,
"penalty_taking": 54,
"jumping": 160
},
"fitness": 100
},
{
"name": "Freddie Basco",
"position": "LM",
"rating": 77,
"injured": false,
"startPOS": [
30,
120
],
"skill": {
"passing": 84,
"shooting": 68,
"tackling": 68,
"saving": 16,
"agility": 74.5,
"strength": 80,
"penalty_taking": 68,
"jumping": 160
},
"fitness": 100
},
{
"name": "Milton Carolina",
"position": "CAM",
"rating": 77,
"injured": false,
"startPOS": [
50,
140
],
"skill": {
"passing": 84,
"shooting": 67,
"tackling": 66,
"saving": 15,
"agility": 73,
"strength": 83,
"penalty_taking": 67,
"jumping": 150
},
"fitness": 100
},
{
"name": "Deshawn Rugama",
"position": "CDM",
"rating": 77,
"injured": false,
"startPOS": [
50,
100
],
"skill": {
"passing": 83,
"shooting": 67,
"tackling": 66,
"saving": 16,
"agility": 73,
"strength": 84,
"penalty_taking": 67,
"jumping": 160
},
"fitness": 100
},
{
"name": "Duncan Beske",
"position": "RM",
"rating": 78,
"injured": false,
"startPOS": [
90,
120
],
"skill": {
"passing": 83,
"shooting": 68,
"tackling": 66,
"saving": 17,
"agility": 75,
"strength": 84,
"penalty_taking": 68,
"jumping": 170
},
"fitness": 100
},
{
"name": "Darren Moronta",
"position": "ST",
"rating": 79,
"injured": false,
"startPOS": [
50,
280
],
"skill": {
"passing": 84,
"shooting": 67,
"tackling": 50,
"saving": 15,
"agility": 83.5,
"strength": 65,
"penalty_taking": 67,
"jumping": 150
},
"fitness": 100
},
{
"name": "Thurman Bowcock",
"position": "ST",
"rating": 75,
"injured": false,
"startPOS": [
50,
270
],
"skill": {
"passing": 65,
"shooting": 83,
"tackling": 54,
"saving": 15,
"agility": 68,
"strength": 80,
"penalty_taking": 83,
"jumping": 150
},
"fitness": 100
}
]
}
---- UPDATE ----
I had jumping below 100. I modified but it does not change anything
Own goals end up as a corner rather than an own goal
add "action" to each players json information.
"none" - use the simulator
"action" - replace chosen action with hard coded action
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.