Code Monkey home page Code Monkey logo

footballsimulationengine's People

Contributors

aidengallagher avatar dashersw avatar dependabot[bot] avatar gallagheraiden avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

footballsimulationengine's Issues

Ball moves instantaneously

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:

  1. Take the calculated ball movement from "ballMovement.js"
  2. create a function to determine ball position over the number of iterations required for the ball to get there (e.g. ball moving 230 space may need 5 iterations to get there)
  3. add a third, height dimension the ball positions
  4. use ball height position when determining deflection and interception along iterations (these functions should already exist - function resolveBallMovement.
  5. Add ball movement to the "ball" object in the returned match details:
    from:
    ball:
    { position: [ 0, 0 ],
    withPlayer: true,
    Player: 'Fred Johnson',
    withTeam: 'Team10',
    direction: 'wait' },
    to
    ball:
    { position: [ 0, 0, 0 ],
    withPlayer: true,
    Player: 'Fred Johnson',
    withTeam: 'Team10',
    direction: 'wait',
    destinationPos: [120, 100, 0 ],
    allMovementPos: [ [30, 33, 35], [60, 66, 100], [90, 80, 65], [105, 90, 25], [120, 100, 0 ] ]
    },
  6. each iteration - move the ball, reevaluate for deflection, shorten the "allMovementPos" array until empty
  7. continue normal game play

Modernizing source code

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.

Provide full fixture data

@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.

AutoGoal

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?

highNumb somethings is float

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()"

Complete Test Cases

Expand on the already created test cases:

  1. Unit test each function individually
  2. Error case validation tests
  3. test positions for set pieces

Error setting ball position after deflection

(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)

Players not on pitch after free kick setup

[ '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.

In the most of the matches fouls are near to 0

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

great program

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

Players don't move with much intent

Improve player movement to make the game more interactive.
Either:

  • PreMap a players intended route (like with ballIterations[]) to an intended location and check if any conflict to that path is found each turn.
  • improve the ‘action’ selector to choose to run more often for players with the ball, whilst also setting movement to be more fixed towards an open space upfield (intended position) with players moving more fluidly.

improve corner taking

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

Player Rating

Hey,

great Project! But which impact has the Player Rating?

Have a nice day,
Jappi00

Text-based, interactive football game based on footballSimulationEngine

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?

Open source version 2

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.

Player variable undefined

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.

set provided actions if not "none"

depends on: #11

Check matchDetails - teams - players - actions. If "none" - process actions as normal, otherwise set the action as that provided by the array.

Not returning a ball position when resolving deflections

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

Improve Passing

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:

  1. Weight probability of target player based on proximity
  2. Weight probability of target player based on direction of opposition goal

Slow down ball

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.

Difference Between Player's startPos, originPos & relativePos

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!

Make it impossible for players to get "stuck"

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
    }
  ]
}

capture d ecran 2019-02-04 a 11 25 22

---- UPDATE ----
I had jumping below 100. I modified but it does not change anything

Add Greater Shooting sophistication

  1. calculate chance of scoring in current position
  2. make 'judgement' have an impact on decisions
  3. choosing to shoot becomes more likely in higher probability situations

Add player actions to the players json

add "action" to each players json information.

"none" - use the simulator
"action" - replace chosen action with hard coded action

  • should also validate the action is a valid action.

Corner Improvements

  • Corner positions should be inside the box except maybe 1 or 2 players near the ball
  • Corner takers should be more likely to select Cross as their 'action' in actions.js
  • There should be a delay in intent positions being applied during corners of maybe 10 iterations?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.