Showing posts with label soccer simulator. Show all posts
Showing posts with label soccer simulator. Show all posts

Sunday, 11 August 2019

Football Simulation Engine v3

2 Years ago I published my first node package module (npm) in npmjs to allow football match results to be simulated. Yesterday I uploaded the latest version FootballSimulationEngine-v3.0.1 which can be installed by running:
          npm install footballsimulationengine

What's New?

startPOS and relativePOS have changed

The biggest - and breaking - change was to update the arrays used to track where players currently are on the pitch (startPOS) and where players are moving towards (relativePOS). These were not very descriptive and resulted in several GitHub issues so they have been changed to better reflect what they do. "startPOS" is now "currentPOS", "relativePOS" is now "intentPOS".

"currentPOS": [340,0],
"fitness": 100,
"injured": false,
"originPOS": [340,0],
"intentPOS": [340,0],

Tests tests tests

I have been reading more and more about the importance of tests and clean code, in fact its been prominent on this blog:
As described, I have added lots and lots of tests into the code making it more readable, easier to make code changes, has led to variables and functions being named more accurately. The result is 143 passing (199ms) tests and roughly 55% test coverage.
55.88% Statements 1401/2507
44.32% Branches 655/1478
82.13% Functions 170/207
53.14% Lines 1227/2309



Penalty Position - Corner and Freekicks

Players no longer form an arbitary collection of bodies at a set location for freekicks and corners, instead they now gather in the penalty box which is a defined dimension on the pitch. This makes corner taking more realistic and improves goal opportunities from corners.

Identifiers

Previously, the current ball holder and the team they were playing were matched against their names for certain logic. i.e. can the player kick the ball? First, we need to know if that player has the ball. Now each match, player and team are given an identification number during initiation. 

{
"matchID": "78883930303030001",
"kickOffTeam": {
"teamID": "78883930303030002",
"name": "ThisTeam",
"rating": 88,
"players": [
{
"playerID": "78883930303030100",
 

Red Cards

Players who get red cards will no longer be part of the playing action. This is shown by current position being set to ['NP', 'NP'] which means 'Not Playing'. If the current position is set the player will not be targeted for passing and will not make any movements.

Skill Rating Utilization

Player skills are better utilised including to make shots on or off target depending on their skill against a random number generation i.e. players with shooting skill of 40 will be less likely to shoot on target than players with shooting skill of 70. This is also applied for saving shots that are in the box with the skills of the goalkeeper determining if the ball is 'saved' or not when in reach. 

Future iterations will take this further for more sophistication. If you have any thoughts for how to do this be sure to raise an issue in GitHub.

Player Stats Improvements

Player statistics from during the game have been greatly improved with statistics for fouls, passes, shots and tackles. This will improve reporting of player information. 

If there are others that can/should be added, raise an issue in GitHub.
'goals': 0,
'shots': {
'total': 0,
'on': 0,
'off': 0
},
'cards': {
'yellow': 0,
'red': 0
},
'passes': {
'total': 0,
'on': 0,
'off': 0
},
'tackles': {
'total': 0,
'on': 0,
'off': 0,
'fouls': 0
}

Conclusion

There are still some improvements to be made, to player movement (which still isn't quite there), passing statistics, intelligence of decisions being made and whole lotta tests to be added. I'll be blogging soon about how I've used this latest version to simulate the 2019/2020 season to showcase how the engine can be used to simulate a season for a football manager game.

Let me know what you think, either in the comments, or by raising an issue on Github or emailing me on aiden.g@live.co.uk! Happy footballing!

Tuesday, 30 January 2018

Football Match - Using football simulation engine

I recently created a football simulation engine for npm which I talked about here.

I also posted a youtube video of me demonstrating the code, and after some interest I thought I would upload the helper code I used in order to visualise the match!

You can access the github page here: https://github.com/GallagherAiden/footballsimulationexample



Here's the read me:
# Football Simulation Example

## Install
1. Download the project onto your system ({dir})
2. cd {dir}
3. run ``npm install``
---
## Run the Game
1. load your team into the {dir}/teams directory (you can use an existing team as an example)
2. in '{dir}/server.js' change either
```
readFile("teams/team1.json").then(function (team1) {
```
to your newly created .json file i.e.
```
readFile("teams/myTeam.json").then(function (team1) {
```
3. Set the pitch size by changing the ``pitchWidth`` and ``pitchHeight`` in '{dir}/server.js'
*Note: Any changes will need changes made to the start positions of the players*
4. run ``npm start``
5. Go To ``http://localhost:1442/match.html``
---
## Playing A Match
1. Press ``start match``
- This starts a new match where the pitch size is displayed on the screen and the players are in their correct positions.
2. Press ``play match``
- This runs '10' iterations, moving the players and give iteration logs for each iteration.
i.e. `Iteration 50: Closest Player to ball: Louise Johnson,Closest Player to ball: Aiden Smith`
3. Press ``play match`` until the iterations reach 5,000
- We can make this quicker by changing the number of iterations per "play" in {dir}/public/js/match.js
```
function getMatch() {
var iterations = 10;
for (i = 0; i < iterations; i++) {
movePlayers("/movePlayers");
}
}
```
to
```
function getMatch() {
var iterations = X;
for (i = 0; i < iterations; i++) {
movePlayers("/movePlayers");
}
}
```
where X is the number of iterations to do at a time.
4. Press ``start second half``
- This flips the players to opposite sides
5. Press ``play match`` until the iterations reach 10,000
6. Record the results

Game Example Results:
Match 1 - Team1: 5 - 3 :Team2  (same json)
Match 2 - Team1: 3 - 4 :Team2  (same json)
Match 3 - Team1: 9 - 2 :Team2  (same json)
Match 4 - Team1: 2 - 5  :Team2  (team2 higher skills)
Match 5 - Team1: 0 - 7  :Team2  (team2 higher skills)
Match 6 - Team1: 8 - 1 :Team2  (team1 higher skills)
Match 7 - Team1: 3 - 0 :Team2  (team1 higher skills)

Have fun! Let me know if you need any help: aiden.g@live.co.uk


Thursday, 25 January 2018

Node JS Football / Soccer Simulation Engine Module

Football Simulation Engine - Node Module

As previously mentioned in my blog HERE, I had been looking to design and build a football manager game, with the main purpose being to improve my JavaScript (JS) and node (Node JS) skills. I soon found there were no existing node package modules (npm) that could provide a simulated match result.

I posted on a few sites to try and see if anyone had done this before - there’s no point repeating work is there? After finding nothing specific that matched my purpose I went on ahead and built my prototypes which consisted of two random numbers and a little use of player skill to create results (see previous blog), but it didn’t really fit the bill for a football manager games back end as it didn’t take other factors into consideration.

So, I went ahead and built my own, and as of today it is now available on the npm website HERE or run 
          npm install footballsimulationengine

How does it work?
Great question, glad you asked. Basically, you provide it with two JSON strings, each its own team and requiring a specific set of JSON objects. This includes team name, players, player positions, skills and each players starting position.
Example:
{
  "name": "Team1",
  "players": [{
      "name": "Player",
      "position": "GK",
      "rating": "99",
      "skill": {
        "passing": "99",
        "shooting": "99",
        "tackling": "99",
        "saving": "99",
        "agility": "99",
        "strength": "99",
        "penalty_taking": "99",
        "jumping": "300"
      },
      "startPOS": [60,0],
      "injured": false
    }...],
  "manager": "Aiden"
}

Key things to remember:
·      Each team MUST have 11 players
·      The code currently does not check these parameters, so the skills SHOULD be between 1 and 100.
·      Except for “jumping” which is intended to be the maximum jump height of the player in centimetres.
·      Start Position should between you pitch Sizes Width and half of the pitch length. The code deals with switching their start position side. E.g if my pitch size is [120, 600], “startPOS” SHOULD BE [0-120, 0 - 300].

The other thing we will need to start a game/match is pitch size, which is shown in [width, height] where the pitch is intended to be taller than it is wide, like below.

PIC

Example Pitch JSON:
{
            "pitchWidth": 120,
            "pitchHeight": 600
}

We feed these three JSONs into the initiate function like so:

Example:
initiateGame(team1, team2, pitch).then(function(matchDetails){
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
})

what we get back is a super larger JSON with both teams, their originPOS (so we can get them back to their original position), relativePOS (so we know where they’re heading towards), and a whole bunch of match details such as the score, number of shots and importantly, where the ball is, ball direction.

The main idea is that the game runs in iterations this allows the client using the simulation engine to change players throughout the game, set up the game in certain positions.

Playing iterations is then as simple as running that big old outputted JSON back into a play iteration function which in turn, gives an updated big old output JSON.

Example:
playIteration(matchDetails).then(function (matchDetails) {
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
}

Example Output:
{ kickOffTeam:
   { name: 'Team1',
     players:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     manager: 'Aiden'
     intent: 'defend' },
  secondTeam:
   { name: 'Team2',
     players:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     manager: 'Joe',
     intent: 'attack' },
  pitchSize: [ 120, 600 ],
  ball:
   { position: [ 76, 314 ],
     withPlayer: true,
     Player: 'Joe Bloggs',
     withTeam: 'Team2',
     direction: 'south' },
  half: 1,
  kickOffTeamStatistics:
   { goals: 0,
     shots: 0,
     corners: 0,
     freekicks: 0,
     penalties: 0,
     fouls: 0 },
  secondTeamStatistics:
   { goals: 0,
     shots: 0,
     corners: 0,
     freekicks: 0,
     penalties: 0,
     fouls: 0 },
  iterationLog:
   [ 'Closest Player to ball: Aiden Gallagher',
     'Closest Player to ball: Joe Bloggs' ] }

An important feature here is the “iterationLog” which gives an overview of what has happened during that iteration. i.e. someone has passed the ball, someone has taken a shot, scored, freekick awarded, penalty taken, a throwin given and taken.

Finally, the last function that can be played is switch sides of the teams that are playing, i.e. after half time or if running into extra time.

Example:
startSecondHalf(matchDetails).then(function (matchDetails) {
  console.log(matchDetails);
}).catch(function(error){
  console.error("Error: ", error);
}

TL;DR / Overview:
·      Three function; initiateGame - needs two team JSONs and a Pitch Details JSON, playIteration - takes the output from initiate game and updates one movement of each player, startSecondHalf - switches the sides the players are on.
·      All three functions are return promises
·      JSON isn’t checked so make sure you’ve got it right
·      Recommended match length is 10,000 iterations.

If you’d like help setting up, have some general questions please feel free to comment below and I’ll get back to you ASAP.

Improvements:
This code is setup on a public Github which you can find HERE and I’m hoping people who use the module (if anyone) will help me improve it! You can raise issues HERE but otherwise please get in touch by email: aiden.g@live.co.uk

Visual Example:
For those who want to see, here is a youtube video of the game being used in an example I have set up. Feel free to get in touch and I can send you the "manager" setup and some instructions.