Index


RISC World

Football Manager

Paul Johnson

Football Manager - What are the chances?

Something which may have dawned by now is that there must be someway of ensuring that a team at the base of division 3 stands very little chance of beating a team at the top of the premiership. This is one part of the original Football Manager game which really was awful!

How the past was done...

When you first started the original game, you were asked which skill level you wanted to play at (1 being beginner, 7 being God like). Depending on the level chosen would depend on how easy the game was. On the easy level it was easier to win a game and so on (with the reverse being true for the harder levels). The only problem was that it was unrealistic. You could still be playing at level 7 and have Acrington Stanley of Division 4 beating Arsenal of Division 1 by a silly 4 goal margin.

How the now will be done...

As before you will have to choose a managerial level and as before, you will still start out with the same amount of cash as before. Unlike before though, your team will have an overall score which takes into account the current league place and which division you're in. Bottom of division 3 will be the lowest.

Say we draw up the leagues and Division 3 looks like this.

  • Hartlepool
  • Rushden & Diamonds
  • Torquay
  • Bournemouth
  • Kidderminster
  • Wrexham
  • Leyton Orient
  • Darlington
  • // rest of the division
  • Carlisle
  • Bristol Rovers
  • Exeter
  • Boston
  • Swansea

If we give Swansea a rating of 1 and Hartlepool a rating of 24 (ie. the reverse of the actual league position) then we have a sort of basis for saying what the chances are that Hartlepool would have versus Everton (rating of 88). If we divide 24 by 88, you get a figure of 27% - the chance Hartlepool would have. Obviously, Swansea vs Liverpool (91) or Arsenal (92) would not have a cat in hells chance (1.09% vs Liverpool, 1.08% vs Arsenal).

Of course, any horse can have it's day and upsets such as bottom of the third giving top of the Premiership a good drubbing does happen.

Next we have to take into account the players skill level. Assuming a skill level of 1, then taking the above for purely the position is probably fine. How to make it harder though? One solution would be a linear scale and the other an exponential scale.

Linear scale.

You're playing as Hartlepool (rated 24) and are up against Everton (rated 88). By simply getting the result from level 1 (27% chance of a win based on rating) and divide that by the level we get.

Level         %age chance of win based on rating
  1                           27
  2                           13.5 (14)
  3                            9
  4                            6.75 (7)
  5                            5.4  (5)
  6                            4.5 
  7                            3.8  (4)

Exponential scale

An exponential scale starts slowly and rapidly rises. The problem with using this sort of scale is deciding where on the curve to start the slide up. Too near x = 0 and the skill levels are meaningless. Too near x = 1 and the skill levels rise too dramatically and you end up with no chance whatsoever of having a playable game. If you decide to use the curve, you could end up having as near as dammit, a linear scale anyway!

For ease, stick to a linear scale.

Having the rating chances is all well and good. Suppose though you're playing at level 1 and are top of division 3 and are playing the bottom team. Based on the the chance method outlines above, you could have the bottom team having a 4% chance of winning against the top - but with only 3 points between them (it's the start of the season). For the same division, the ranking chance system is pretty useless. Here we need to go on sheer skill.

Take a typical team (team A) with these stats (max number : 18).

Morale  : 12
Defence : 9
Midfield: 11
Attack  : 10

It's a pretty balanced team. They're taking on a team (B) with these stats.

Morale  : 14
Defence : 12
Midfield: 10
Attack  : 16

Not only does the morale show that they've been on a winning streak, but should A attack B, there chances are that A won't score very often, conversely, if B attacks A, they will probably score more than miss. The midfield is pretty much evenly matched. But hang fire...

If team A play a 4-4-2 formation and team B play a 3-5-2 formation then we come into another problem. B has an extra man in midfield and is more likely (even with the slight disadvantage in the terms of numbers), yet when it comes to attacking, A has the upper hand (B only has 3 in defence).

For the above example, the extra man will probably not make much of a difference however if team B had a midfield of 13 against team A having a score of 10, then the number of balls sent to the attack will greatly increase, therefore the number of chances will increase. If the defence score for A has not changed then it's very likely that the final score will be quite high!

This is all well and good for dealing with two teams, but what happens come match day? Obviously you can't watch every match and it would unrealistic to have to emulate every shot on goal. Fortunately, this problem can be circumvented in the following way.

  • The stats are worked out for the two teams.

  • Get a random number between 8 and 20.

  • Start in the midfield - pick 1 or 2 (2 = away team) for possesion.

  • Take a number between 1 and 18 (higher the better).

  • Depending if the number is higher than that of midfield of the other team, says if the ball goes forward.

  • If the player loses the ball, the number generated in (2) is reduced by 1 and we start again from (3).

  • Get another number between 1 and 18 - if the number is higher than the defence you shoot.

  • Decide on which attacker is shooting - take the skill (ranges from 1 to 5) and fitness (1 to 20) and multiply one by the other. The higher the better. A score of 100 means the player doesn't miss.

  • Get a number between 1 and 99. If the players skill is above this number, then they score.

  • Repeat until the number generated in step (2) reaches zero.

Given we're not actually do much more than generating some random numbers and doing a couple of comparisons, the final results can be quickly generated - and what's even better, is that the above can also be used for the main game (except we have the animations as well).

Code

There are a couple of ways of generating random numbers.

We can use srand and rand in combination with the time functions from both <cstdlib> and <ctime>. This is fine, but the numbers which are generated are not always that good. A far better solution would be to use something like this.

rand() % N

this tries to return numbers from 0 to N-1. Unfortunately, it's not a very good way to generate the numbers as the low-order bits of many random number generators are distressingly non-random.

A far better method is

static_cast<int>(static_cast<double>(rand()) / (static_cast<double>(RAND_MAX) + 1 * N).

(for floating point, remove the casts)

RAND_MAX is a constant defined in <cstdlib> and cannot be redefined. (ref : K&R 2nd ed. Sec 7.8.7 page 168)

A practical example is this

/*****************************************************************
                          random.cpp  -  description
                             -------------------
    begin                : Fri Nov 29 2002
    copyright            : (C) 2002 by PFJ
    email                : paulf.johnson@ukonline.co.uk
    license              : GPL all the way!
 ****************************************************************/

#include <cstdlib>
#include <iostream>

#ifndef __EASY_C
using namespace std;
#endif

void random_number(int &number, int seed)
{
  number = static_cast<int>(static_cast<double>(rand()) / 
	(static_cast<double>(RAND_MAX) + 1) * seed);
}

int main()
{
  cout << "Random number demonstration.\n"
       << "Please enter a number between 1 and 20 : ";
  int s;
  while (cin >> s, s < 1 || s > 20)
  {
    cout << "Nooooo, I asked for a number between 1 and 20\n";
    cin.clear();
    cin.ignore();
  }
  int n = 0;
  random_number(n, s);
  cout << "The random number generated is " << n << endl;
  return 0;
}

If you're using Acorn C++ (or the old version of Easy C++), you will need to change the headers as follows

#include <iostream.h>
#include <stdlib.h>

And also remove the using namespace std; line

Compiling under g++ (unless you're using EasyGCC).

g++ random.cpp -o random -O2

For EasyC++ and AcornC++, just use the graphic interface (and if you're using Acorn C++, get hold of a copy of either GCC or EasyC++ as soon as you can) you won't be able to compile much of the code for this game using Acorn C++.

Okay, this will run, however, the output will be very predictable. Why? Well, we haven't actually seeded the random number generator yet. A simple way to do this would be to include into the source.

#include <ctime>

And in main()

srand(time(0));

Now we will get numbers which make far more sense.

Getting the tackle in

Up to this point, we've only actually considered kicking the ball, but what happens if the random number generated is the same for the player as it is for the opponent, then what we have to deal with is a tackle. We can handle this in one of three ways .

  • a random number
  • based on the players statistics
  • some combination of the above.

Taking each one. Well, a random number is a tad boring, but quick (if number_generated > 49 player wins tackle else the ball is given away). Player stats can be used quite effectively� in any real football tackle, the stronger player normally wins the tackle (as long as the tackle was legal that is!). We will still need some method of deciding should the stats be either identical or very close to identical, therefore the best choice would be the combination. Should the numbers be close, decide on the coin toss.

Next time, I will take a deeper look into the management side (including injuries and the transfer market).

Paul Johnson

 Index