⚽ Argentina’s Tactical Brilliance — A Football Match Simulated in JavaScript

Table of contents
- 🛠️ The Team is Born
- ✅ Validating the Team
- 🚨 First Issue: One Player Extra
- 🔁 Tactical Substitutions
- 🩺 Halftime Twist: Messi is Injured
- 🏆 Victory Secured – Time for the Headlines
- ❌ The Hidden Bug: Why sort() Fails for Names
- ✅ The Fix: Using localeCompare()
- 📞 But Then the Editor Replies Again…
- ✅ The Real Fix: Merge and Sort by Name, With Position Labels
- 📃 Output:
- 📜 Final Thoughts
- 🧠 Final Takeaway:

By Krishna Soni
In a world where code meets creativity, Argentina takes the field not just in the stadium but in the console. This is not your average football match. This is a JavaScript-powered showdown between Argentina and Real Madrid, and our main character is not Lionel Messi — it's team_structure
.
Let’s relive this match, play-by-play — in code and story.
🛠️ The Team is Born
Our coach (the programmer(Me)) carefully assembles Argentina’s initial squad using four arrays:
Goalkeepers
Defenders
Midfielders
Forwards
Then, he packed them into a team structure:
This was a solid start—but the coach wanted to validate the team.
✅ Validating the Team
To ensure fair play, a custom function
isValid()
checked if the team has exactly 11 players:At first check, there were 12 players — oops! One too many. Time to strategize.
A quick validation function ensures the team respects FIFA’s 11-player rule.
🚨 First Issue: One Player Extra
The
isValid()
function alerts the coach — there are 12 players. A closer look reveals the problem: 5 defenders.Now enters the substitute bench, also modeled in JavaScript:
🔁 Tactical Substitutions
The coach spotted the imbalance: 5 defenders instead of 4. A difficult choice, but Nicolás Tagliafico was removed from the field and added to the substitutes:
A tough call, but the right one — and now, the team was perfectly valid.
🩺 Halftime Twist: Messi is Injured
The match is intense. At halftime, it's 2-2. But disaster strikes — Messi is injured.
The coach reacts:
Thanks to depth on the bench, Giuliano Simeone stepped up and filled in. The coach removed a midfielder to maintain balance.
🏆 Victory Secured – Time for the Headlines
With teamwork, tactics, and substitutions well executed, Argentina clinched the victory and moved on to the semi-finals.
Now it was time for the newspaper editor to print the team sheet—but wait!
this won’t work
forwards.sort();
Defenders.sort();
Midfielders.sort();
❌ The Hidden Bug: Why sort()
Fails for Names
JavaScript's .sort()
is lexicographical and case-sensitive. It doesn’t understand that "Ángel"
should come before "Giuliano"
, or that "Nicolás"
should follow "Giuliano"
.
Here’s why:
It uses UTF-16 character codes.
Accented letters like
Á
,É
,Ñ
are treated differently fromA
,E
,N
.Uppercase letters come before lowercase ones.
✅ The Fix: Using localeCompare()
To fix this, the coach switches to a proper comparison function:
forwards.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
Defenders.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
Midfielders.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
The players inside each position group are now alphabetically ordered.
The coach proudly sends the structure.
📞 But Then the Editor Replies Again…
“No, no! I don’t want four separate lists.
I want one single alphabetical list of all players — and mention their positions!”
A new problem emerges. Sorting inside each category wasn’t enough. The editor wants it merged — like:
EditÁngel Correa (Forward)
Cristian Romero (Defender)
Emiliano Martínez (Goalkeeper)
...
✅ The Real Fix: Merge and Sort by Name, With Position Labels
The coach codes a new solution:
// Step 1: Collect players with their positions
let labeledPlayers = [];
for (const [position, players] of Object.entries(team_structure)) {
// Clean up the label (Goalkeepers → Goalkeeper, etc.)
let role = position.slice(0, -1); // remove the 's' at the end
if (role === "forwards") role = "Forward";
else role = role.charAt(0).toUpperCase() + role.slice(1);
// Add each player with their role label
players.forEach(player => {
labeledPlayers.push(`${player} (${role})`);
});
}
// Step 2: Sort alphabetically (case- and accent-insensitive)
labeledPlayers.sort((a, b) =>
a.localeCompare(b, 'en', { sensitivity: 'base' })
);
// Step 3: Show output
console.log(labeledPlayers);
📃 Output:
📜 Final Thoughts
What started as a football match turned into a coding masterpiece. With the perfect blend of logic and storytelling, Team Argentina not only won the match but also taught us the value of structure, validation, and substitution—in code and on the field.
🏁 Coach says:
“Remember: Even in code, football is a game of balance, planning, and precision.”
🧠 Final Takeaway:
✅ 1. length
Purpose: Returns the number of elements in an array.
Used in: Team validation to check total players.
size = Goalkeepers.length + Defenders.length + Midfielders.length + forwards.length;
✅ 2. splice()
Purpose: Adds/removes elements at a specific index.
Used in:
Removing a player (e.g., Messi or Tagliafico).
Removing a midfielder after substitution.
Defenders.splice(Defenders.indexOf("Nicolás Tagliafico"), 1);
forwards.splice(forwards.indexOf("Lionel Messi"), 1);
M.splice(1, 1);
✅ 3. indexOf()
Purpose: Finds the index of a value in an array.
Used in: To locate player names before removal.
Defenders.indexOf("Nicolás Tagliafico");
forwards.indexOf("Lionel Messi");
✅ 4. push()
Purpose: Adds an element to the end of an array.
Used in: Adding Tagliafico to the substitute defenders.
D.push("Nicolás Tagliafico");
✅ 5. unshift()
Purpose: Adds an element to the start of an array.
Used in: Bringing a new player (Simeone or a sub forward) to the front of the
forwards
array.
forwards.unshift(M[2]);
✅ 6. sort()
Purpose: Sorts the elements of an array in place.
Used in: Sorting each positional group and the final merged team list.
forwards.sort();
labeledPlayers.sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }));
✅ 7. localeCompare()
Purpose: Compares two strings alphabetically, respecting case and accents.
Used in: Custom comparator in
sort()
for correct name ordering.
a.localeCompare(b, 'en', { sensitivity: 'base' });
✅ 8. forEach()
Purpose: Iterates through each element in an array.
Used in: Tagging players with their roles before merging.
players.forEach(player => {
labeledPlayers.push(`${player} (${role})`);
});
✅ 9. Object.entries()
Purpose: Returns key-value pairs of an object.
Used in: Looping through
team_structure
to access player arrays and their positions.
for (const [position, players] of Object.entries(team_structure)) { ... }
✅ 10. Spread Operator (...
)
Purpose: Expands arrays into individual elements.
Used in: Merging all position arrays into one combined list (if needed).
let allPlayers = [...Goalkeepers, ...Defenders, ...Midfielders, ...forwards];
🙏 Thank You!
Thank you so much for reading this fun blend of football and JavaScript!
This article was a tribute not just to the beautiful game, but also to the beauty of code — where every substitution, every sort, and every splice has meaning.
Whether you're a developer, a football fan, or both — I hope this story made you smile and helped you learn.
Stay curious, keep coding, and may all your bugs be as easy to debug as replacing Messi with Simeone 😄.
– Krishna Soni
Subscribe to my newsletter
Read articles from Krishna Soni directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
