League Mode - Sorting Arrays
Hello!
Currently, I am trying to develop a management game with teams, tournaments, and leagues. Although I figured out how to sort my array with teams in the scene, I find my code very inefficient but I do not know how I can make it better, and only because it works, it does not mean it is good or clean. Furthermore, I think I will run into trouble or lose the overview if I continue with this method because I plan to make it a bit more complex than that.
So my goal was simply to make a league mode where the teams are listed from top to bottom according to their scored points so far.
Please note: I commented the script out, so everyone should be able to understand the gist of it. The main part which worries me is the "for loop chain", that's how I called it in the commented area. xD
If you have a better approach to the problem I would highly appreciate your input, if this is a good approach, well, then I hope I could help other people with this code, lol.
(Current League Mode: 8 Teams, sorted according to their scored points - just saying it once again: the code works, but I don't find it efficient and there might be a better method)
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class ShiroLeagueManager : MonoBehaviour {
public TeamValue[] leagueTeam; // The Team's script (for points, stats, and other information)
public TeamSlot[] leagueSlots; // The League Slots in which the teams are put in
public int[] ranking = new int[8]; // determines which team is on which place
private int[] comparison = new int[8]; // needed for comparison if ranking is the same on both teams
// Use this for initialization
void Start ()
{
ShiroLeagueSort();
}
public void ShiroLeagueSort()
{
// Ranking for every Array Number is assigned 0 for calculation
for(int i = 0; i < leagueTeam.Length; i++)
{
ranking[i] = 0;
}
// Checks which Team has the most league points
// if a team has less then another one, the team gets +1 in ranking (i.e. one place lower)
for (int i = 0; i < leagueTeam.Length; i++)
{
if (leagueTeam[0].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[0]++;
}
if (leagueTeam[1].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[1]++;
}
if (leagueTeam[2].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[2]++;
}
if (leagueTeam[3].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[3]++;
}
if (leagueTeam[4].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[4]++;
}
if (leagueTeam[5].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[5]++;
}
if (leagueTeam[6].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[6]++;
}
if (leagueTeam[7].leaguePoints < leagueTeam[i].leaguePoints)
{
ranking[7]++;
}
}
// sets up the comparison variable (int) to -1 for calculation
for (int i = 0; i < comparison.Length; i++)
{
comparison[i] = -1;
}
// - FOR LOOP CHAIN -
// for loops every single ranking through all rankings in the array, everytime
// the ranking matches another ranking the comparison var gets +1
// Since there will be definitely the same ranking once (ranking[0] = ranking[0])
// the comparison variable starts with -1
// if there is another ranking with the same value, the ranking in question gets +1
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[0] == ranking[i])
{
comparison[0]++;
ranking[0] += comparison[0];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[1] == ranking[i])
{
comparison[1]++;
ranking[1] += comparison[1];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[2] == ranking[i])
{
comparison[2]++;
ranking[2] += comparison[2];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[3] == ranking[i])
{
comparison[3]++;
ranking[3] += comparison[3];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[4] == ranking[i])
{
comparison[4]++;
ranking[4] += comparison[4];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[5] == ranking[i])
{
comparison[5]++;
ranking[5] += comparison[5];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[6] == ranking[i])
{
comparison[6]++;
ranking[6] += comparison[6];
}
}
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[7] == ranking[i])
{
comparison[7]++;
ranking[7] += comparison[7];
}
}
// - END OF FOR LOOP CHAIN -
for (int i = 0; i < leagueTeam.Length; i++)
{
leagueSlots[ranking[i]].leagueTeam = leagueTeam[i]; // Assigns the Ranking to the team
leagueSlots[i].teamPlace.text = (i + 1).ToString(); // writes the place number in the table
}
for(int i = 0; i < leagueTeam.Length; i++)
{
leagueSlots[i].TeamLeagueSlotUpdate(); // Updates the Slots with the received Team Info
}
}
}
I found the solution, I combined the for loop with a while loop and set up an additional comparison variable.
If someone is interested in a cleaner version of this:
compVar = 0; // resets comparison Variable
// sets up the comparison variable (int array) to -1 for calculation
for (int i = 0; i < comparison.Length; i++)
{
comparison[i] = -1;
}
// - FOR LOOP CHAIN in While LOOP-
// for loops every single ranking through all rankings in the array, everytime
// the ranking matches another ranking the comparison var (int array) gets +1
// Since there will be definitely the same ranking once (ranking[0] = ranking[0])
// the comparison variable starts with -1
// if there is another ranking with the same value, the ranking in question gets +1
while (compVar < leagueTeam.Length)
{
for (int i = 0; i < leagueTeam.Length; i++)
{
if (ranking[compVar] == ranking[i])
{
comparison[compVar]++;
ranking[compVar] += comparison[compVar];
}
}
compVar++;
}
Works like a charm. :D
Answer by iBicha · Jul 29, 2017 at 01:48 AM
I would say you are right, this is definitely not the way to sort elements. First, if you have complex entities (Teams and leagues and points and players and so on) Try to create a class that organizes things logically. After that, sorting can become pretty easy once you know about IComparable
or IComparer
Here's a simple example. Add this file to your project, and call SortingElemetsExample.TestCompabales ();
and see the results in the console.
using System;
using System.Collections.Generic;
using UnityEngine;
public class SortingElemetsExample {
//So this is a team, which has a Name, and points.
//It can have many other attributes
//Note how it implement IComparable, which makes it sortable.
public class Team : IComparable
{
public Team(string Name, int LeaguePoints) {
this.Name = Name;
this.LeaguePoints = LeaguePoints;
}
public string Name;
public int LeaguePoints;
public override string ToString ()
{
return string.Format ("{0} : {1} points", Name, LeaguePoints);
}
//For sorting to work, we need to implement this function this way:
// return -1 if the current object is bigger than the other object
// return 1 if the current object is smaller than the other object
// return 0 if they are equal
public int CompareTo (object obj)
{
Team otherTeam = (Team)obj;
if (otherTeam.LeaguePoints < LeaguePoints) {
return -1;
} else if (otherTeam.LeaguePoints > LeaguePoints) {
return 1;
} else {
return 0;
}
}
}
public static void TestCompabales() {
//We create a list
List<Team> teams = new List<Team> ();
//Add a bunch of teams
teams.Add (new Team ("Team 1", 145));
teams.Add (new Team ("Team 2", 50));
teams.Add (new Team ("Team 3", 83));
teams.Add (new Team ("Team 4", 120));
teams.Add (new Team ("Team 5", 193));
//Show the teams as is
for (int i = 0; i < teams.Count; i++) {
Debug.Log (teams [i]);
}
//Calling sort.
//Because Team implements the IComparable interface, the CompareTo method will be used to compare teams
teams.Sort ();
//Show are now sorted
for (int i = 0; i < teams.Count; i++) {
Debug.Log (teams [i]);
}
}
}
Your answer
Follow this Question
Related Questions
How to add a Type to a Class in Javascript? 1 Answer
increase score with a variable from another script 1 Answer
Generating random points and instantiating prefabs with a set distance 0 Answers
How to set a variable of a non-monobehavior script from a monobehaviour script 0 Answers
UI buttons won't recognize script 0 Answers