Hello everyone,

Ok, well I am faced with the challenge of creating a scouting program for my robotics team so we could keep a track of how other teams do at competitions to compare and contrast their designs. I have 95% of the program done, it reads and adds info into an XML file with a team element for each team's data. It retrieves that information from the XML and displays it into a DataGridView component. The variables/values for each Team element are as follows:

Balls Scored
balls Blocked
Balls Hit Into Offensive Area
Penalties
Contribution

To calculate the best robot in the fields of defense and mid-field are easy, just find the number with the largest values for blocked and hit into offensive area respecitively. Calculating the best robot for offense is the difficult part for me. Here is my current code for calculating best teams.

private String[] getBestTeams() {
            String[] bestTeams = new String[3];
            string bestDef = "";
            string bestMid = "";
            string bestOff = "";

            int highDef = 0;
            int highMid = 0;

            for (int i = 0; i < numofteams; i++)
            {
                if (Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Blocked].Value) > highDef)
                {
                    highDef = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Blocked].Value);
                    bestDef = scoutGrid.Rows[i].Cells[AfterNode.Team].Value.ToString();
                }
                if (Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Moved].Value) > highMid)
                {
                    highMid = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Moved].Value);
                    bestMid = scoutGrid.Rows[i].Cells[AfterNode.Team].Value.ToString();
                }
            }

            bestTeams[0] = bestDef;
            bestTeams[1] = bestMid;
            bestTeams[2] = bestOff;

            return bestTeams;
        }

As you can see, it iterates through every row of the DataGridView (Rows) and then The corresponding Cells. I made a class with specific indexes for each cell pertaining to the value it holds, specifically:

AfterNode.Team
AfterNode.Scored
AfterNode.Blocked
AfterNode.Moved
AfterNode.Penalties
AfterNode.Contribution

My question is, how would I calculate the best offensive team, the team that has the highest balls scored, the highest contribution and the lowest number of penalties. Obviously the same robot has very little chances of matching all 3 fields. So how would I go about doing this. Thank you!

Edited 6 Years Ago by WargRider: Forgot AfterNode.Moved

it depends how you want to go about it; as you said, its unlikely that one robot will win hands down (best in all three fields).
One approach could be to order the three elements in order of importance and rank in that order. eg:

Element Ranks:
1st Goals Scored
2nd Contribution
3rd Penalties

Find set of robots with highest Goals Scored.
If more than one robots in set
Find the subset of robots with highest Contribution
If more than one robot in set
Find subset with lowest Penalties

This approach works if you place greater emphasis on certain criteria for winning. But what if a robot has scored only a handful of goals but has a very high rate of contributions. OR what if a robot scores lots of goals but also gets lots of penalties.

If you want to rate the robot based on an overall comparison then i think your best bet is give each element a weighting and calculate an offensive score based on those weightings. eg:

Weightings
Goals Scored 20
Contributions 10
Penalties -10

Offensive score = (20*GoalsScored) + (10*Contributions) + (-10* Penalties)

How much you weight each element should reflect how much you feel it reflects the robots overall offensive performance.
You can make the calculation as simple as this or as complex as you like. You could add multipliers based on ratio of goals to penalties to further reduce the score of robots that get penalties too often, or add a bonus for robots with zero penalties, etc.
The end result should be a numeric value that you feel reflects the robots offensive play. As with anything like this, it will be subjective. You might weight goals scored highly whilst someone else might feel the contributions are equally important.

Hope this helps.

Edited 6 Years Ago by Geekitygeek: n/a

I really like your last idea, adding points based on those things, thank you for that suggestion, I will get to work on that, and hopefully post the code here for it :D. Thanks!

private const int ScoreWeight = 2;
private const int ContribWeight = 1;
private const int PenaltyWeight = -1;

 private String[] getBestTeams() {
            String[] bestTeams = new String[3];
            string bestDef = "";
            string bestMid = "";
            string bestOff = "";

            int highDef = 0;
            int highMid = 0;
            int highOff = 0;

            for (int i = 0; i < numofteams; i++)
            {
                int score = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Scored].Value);
                int contrib = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Contribution].Value);
                int penalty = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Penalties].Value);

                int weightedScore = (ScoreWeight * score) + (ContribWeight * contrib) + (PenaltyWeight * penalty);

                if (Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Blocked].Value) > highDef)
                {
                    highDef = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Blocked].Value);
                    bestDef = scoutGrid.Rows[i].Cells[AfterNode.Team].Value.ToString();
                }
                if (Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Moved].Value) > highMid)
                {
                    highMid = Convert.ToInt32(scoutGrid.Rows[i].Cells[AfterNode.Moved].Value);
                    bestMid = scoutGrid.Rows[i].Cells[AfterNode.Team].Value.ToString();
                }
                if (weightedScore > highOff)
                {
                    highOff = weightedScore;
                    bestOff = scoutGrid.Rows[i].Cells[AfterNode.Team].Value.ToString();
                }
            }

            bestTeams[0] = bestDef;
            bestTeams[1] = bestMid;
            bestTeams[2] = bestOff;

            return bestTeams;
}

It works just as intended, thank you soo much :D. have a nice day.

Edited 6 Years Ago by WargRider: Updated Code

Your welcome :)
Remember to mark the thread as solved..and well done on using CONST for the weighting, it makes your code much more easily read and maintained

This question has already been answered. Start a new discussion instead.