0

Very much a novice, my fixture and league table program works fine with hardcoded fixtures but attempting a more flexible code that builds fixtures round by round has broken it.

You'll see I've coded both methods, and use the flag 'hardFix' to determine how the fixtures are built.

  var players = ["P1", "P2", "P3"];

  var Fixtures = [];

  var rounds = 3;

  var hardFix = false;

  function buildFixtures() {
    if (hardFix == true) {

      Fixtures = [
        [players[0], , , players[1]],
        [players[0], , , players[2]],
        [players[1], , , players[2]],
        [players[1], , , players[0]],
        [players[2], , , players[0]],
        [players[2], , , players[1]],
        [players[0], , , players[1]],
        [players[0], , , players[2]],
        [players[1], , , players[2]],
        [players[1], , , players[0]],
        [players[2], , , players[0]],
        [players[2], , , players[1]],
      ];
    } else {

      let oddRound = [
      [players[0],,,players[1]],
        [players[0],,,players[2]],
        [players[1],,,players[2]]
      ];

      let evenRound = [
      [players[1],,,players[0]],
        [players[2],,,players[0]],
        [players[2],,,players[1]]
      ];
      for (let i = 1; i <= rounds; i++) {
        if (i & 1) {
            Array.prototype.push.apply(Fixtures, oddRound);
        } else {
            Array.prototype.push.apply(Fixtures, evenRound);
        }
    }

   }
  }


You'll see below:

  • with two rounds there's not a problem
  • when there's more, the first round becomes 'invisible'
  • and the final fixture's result gets dupicated (see whole array below table)

enter image description here enter image description here enter image description here enter image description here

I believe it's something to do with the structure of the array that I've built. Any advice apprecitated. Thanks in advance

gdh48k
  • 29
  • 6
  • 3
    Isn't this exactly the same question you asked 6 days ago? And what is a "fixture" anyway? – Pointy Mar 28 '20 at 16:39
  • Impossible to fix a logical error without knowing in plain language or pseudo code on what the end goal is. Upvoting Pointy's comment on what is a fixture? Also if you can provide some context on the "game rules". – GetSet Mar 28 '20 at 16:45
  • @Pointy It's a different aspect of the that problem. My question here focuses on the array structure rather that the code itself. I'll clarify above what is meant by 'fixture'. – gdh48k Mar 28 '20 at 17:10
  • Please tell us exactly what this code is supposed to do, and what it's doing instead, and what you've done to try and figure out why it's not working. I don't understand why your arrays have null entries in the middle, especially when the only way you're modifying them is by pushing onto the end. – Mark Reed Mar 28 '20 at 17:12
  • @GetSet Excuse the lack of clarity. A fixture is a tie or a match between two players or teams, as in a football fixture. The scores are entered and stored with the'Fixtures" array, and are used to produce the league table, again as in a football league. – gdh48k Mar 28 '20 at 17:14
  • If you could give @MarkReed comment above that would be great. In particular, his comment essentially advises on *do you know what you are doing?* and if you do, can you explain it plain words? If you have the knowledge of what *needs* to be done then that is ideal. Because then you have the *algorithm*. What is the algorithm gdh48k? – GetSet Mar 28 '20 at 17:19
  • It seems you need a [function that can generate all pairs from an array](https://stackoverflow.com/questions/22566379/how-to-get-all-pairs-of-array-javascript) – Stuart Mar 28 '20 at 17:20
  • @MarkReed Please see my comments regarding the purpose of the code. The Fixture have null entries ready for the scores to be entered. When fixtures are hardcoded or where there's two rounds, the league table is produced faultlessly (first image above), where three or more rounds are generated, the table is incorrectly calculated as per images 2,3 and 4. Apologies for the lack of clarity. – gdh48k Mar 28 '20 at 17:21
  • 2
    When you build the table dynamically from `oddRound` and `evenRound`, understand that pushing those into the target array **does not make copies**. If you later manipulate the sub-arrays in the target, you'll be changing the same array for multiple target rows. You can `.push(oddRound.slice())` to push copies of those source arrays. – Pointy Mar 28 '20 at 17:58
  • @Stuart Thanks - adding fixtures in pairs is something I'll explore. Do you know why this might be the issue? It makes me wonder if adding three arrays (or fixtures) at a time impacts the resultant array's index? – gdh48k Mar 28 '20 at 18:17
  • Thank you @Pointy It's making much more sense now, and explains why that one scoreline was duplicated across fixtures. I'll look into adding '.slice' as you advise – gdh48k Mar 28 '20 at 18:25
  • Either building up the fixtures table one row at a time (as in my answer), or using `slice` to duplicate segments should work, while repeatedly appending the same segments of 3 rows will create problems. – Stuart Mar 28 '20 at 18:28

1 Answers1

2

As per @Pointy's comment, the problem probably results from repeatedly appending the same sets of rows (oddRound and evenRound) - when you alter values within these rows all of the others are also altered. (However I'm not sure how your output could result from this problem alone, so there may be other problems in parts of your code not shown.)

One way to tackle this is with a separate function that lists all pairings of an array - this is a more flexible solution in case you later need more than 3 players.

function pairs(arr) {
    // Return list of all pairs of values in an array
    const r = [];
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            r.push([arr[i], arr[j]]);
        }   
    }
    return r;
}

function buildFixtures(rounds, players) {
    const pairings = pairs(players),
        r = [];
    for (let i = 0; i < rounds; i++) {
        for (const [first, second] of pairings) {
            if (i % 2) {   // odd round
                r.push([second,,,first]);   
            } else {        // even round
                r.push([first,,,second]);
            }
        }
    }        
    return r;
}
let players = ["P1", "P2", "P3"],
    rounds = 3,
    fixtures = buildFixtures(rounds, players);
Stuart
  • 9,597
  • 1
  • 21
  • 30
  • This is great! And adding more players was next on my list too. This has been highly instructive and I'm gonna learn more implementing this - many thanks again @Stuart – gdh48k Mar 29 '20 at 19:36