Thread: Data structure to record football season game results

  1. #1
    Registered User javaeyes's Avatar
    Join Date
    Feb 2012
    Posts
    153

    Data structure to record football season game results

    I want to create a data structure to record the results of football games for an entire season (or more.) I only want to record the final score, not quarters, or any stats on any players. I think I also want to keep track of who the the home team is. I thought about a multi-dimensional array, but just visualizing it isn't working in my head. e.g. lets say, week 1, patriots=team #3, dolphins=team #10, patriots at home, and the final score is 30-14 (patriots). In my (not workable) multi-dimensional array approach it would look something like this:
    Code:
    gameresult[1][3][10][30][14] = ? or possibly
    gameresult[1][3][10]={30,4}
    I can visualize it better as related tables in a database, with lookups. But I feel like I'm missing a very simple solution. Any ideas?

  2. #2
    Registered User
    Join Date
    Sep 2008
    Posts
    200
    I assume you're working in C?

    What's wrong with an array of structs?

    Code:
    typedef struct
    {
        int home_team_id;
        int away_team_id;
        int home_score;
        int away_score;
    } result_t;
    
    result_t results[MAX_RESULTS];
    Or dynamically allocate a result_t array.
    Programming and other random guff: cat /dev/thoughts > blogspot.com (previously prognix.blogspot.com)

    ~~~

    "The largest-scale pattern in the history of Unix is this: when and where Unix has adhered most closely to open-source practices, it has prospered. Attempts to proprietarize it have invariably resulted in stagnation and decline."

    Eric Raymond, The Art of Unix Programming

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    A game could be defined as a struct with the following fields
    • first team
    • second team
    • where the play
    • score of first team
    • score of second team


    Hope this helps

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    @John, I would still think that where they play should be a field

  5. #5
    Registered User javaeyes's Avatar
    Join Date
    Feb 2012
    Posts
    153
    Hmmm, this seems like the right approach. I debated whether to have a field that explicitly states the home team, or to do it by convention with the home team always the 'firstteam.' I feel like one approach is better, just not sure which one it is.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I'd think a spreadsheet would be perfect, with one page for every year. Linux has a free spreadsheet, btw - pretty darn good.

    This is a basic scorecard, but it gets quite awkward after much more data.
    Code:
    /* This is an update to scorecard.c
    
    # Our Data for the Scores Array:
    2 3 4 3 2 1 1 5 4
    0 3 2 3 0 4 2 2 4
    2 3 5 0 1 3 3 0 2
    1 1 1 5 5 2 3 1 5
    4 2 0 2 3 0 5 2 1
    3 0 3 1 4 4 0 3 2
    0 4 2 3 1 1 6 4 3
    5 5 4 0 3 2 4 0 0
    6 2 3 1 3 1 5 6 3
    3 3 1 2 5 0 5 4 1
    
    
    */
    
    #include <stdio.h>
    #include <string.h>
    
    #define Rows 10
    #define Cols 15
    #define NumberOfGames 11
    
    void getPoints(int scores[Rows][NumberOfGames], int team, int home[Rows][NumberOfGames]); 
    void output(char teams[Rows][Cols], int scores[Rows][NumberOfGames],int home[Rows][NumberOfGames]);
    int main(void) {
       
       int c, r, i, goals1, goals2, away; 
       int scores[Rows][NumberOfGames] = {
       {-1,2,3,4,3,2,1,1,5,4,0},  //team[0]'s game scores    
       {0,-1,3,2,3,0,4,2,2,4,0},  //team[1]'s game scores
       {2,3,-1,5,0,1,3,3,0,2,0},  //last column is team's total score
       {1,1,1,-1,5,5,2,3,1,5,0},  //away win= 3 pts.
       {4,2,0,2,-1,3,0,5,2,1,0},  //home win= 2 pts.
       {3,0,3,1,4,-1,4,0,3,2,0},  //tie= 1 pt.
       {0,4,2,3,1,1,-1,6,4,3,0},  //loss= -1 pt.
       {5,5,4,0,3,2,4,-1,0,0,0},
       {6,2,3,1,3,1,5,6,-1,3,0},
       {3,3,1,2,5,0,5,4,1,-1,0}
       };
       char teams[Rows][Cols] = {
       {"Kickers"}, 
       {"Kings"},
       {"Flyers"}, 
       {"Jaguars"},
       {"Giants"},
       {"Gladiators"},
       {"Rogues"},
       {"Miners"},
       {"Titans"},
       {"Eagles"}
       };
       int home[Rows][NumberOfGames]={0};
       printf("\n\n");
       //calculate home games
       away=0;
       for(r=0;r<Rows;r++) {
         for(c=0;c<NumberOfGames-1;c++) {
           if(r==c) 
             home[r][c]= -1;
           else if(r<c) 
             home[r][c]=away;
           else
             if(!home[c][r])
               home[r][c]=1; 
           away = !away;
           printf(" %2d", home[r][c]);
         }
         putchar('\n');
         away = !away;
       }
       //getch(); //check the home and away assignments
       for(r=0;r<Rows;r++) {
         for(c=0;c<NumberOfGames-1;c++) {
           if((home[r][c] == home[c][r]) && (r != c)) {
             printf("\nconflict at R: %d  C: %d. press enter to continue", r, c);
             (void)getchar();
           }
         }
       }
       //(void) getchar(); return 0; //for debug only
       putchar('\n');
       for(r = 0; r < Rows; r++)  {
          printf("%s", teams[r]);
          for(c = 0; c < NumberOfGames; c++)
             printf(" %d", scores[r][c]);
          putchar('\n');
       }
       //calculate points
       getPoints(scores, i, home);
    
       output(teams, scores, home);
       printf("\n\n\t\t    Program Complete - Press Enter When Ready ");
       i = getchar(); i++;
       return 0;
    }
    void output(char teams[Rows][Cols], int scores[Rows][NumberOfGames],int home[Rows][NumberOfGames]) {
      int i, j, namelen, maxlen, spaces, points;
    
      printf("\n\n\n");
      for(i = 0, maxlen = 0; i < Rows; i++) {     //get the length of the longest team name
        namelen = strlen(teams[i]);
        if(namelen > maxlen)
          maxlen = namelen;
      }
      //print the header
      for(i = 0; i < maxlen; i++)  //the slashes: backslashes are escape char's
        printf("%c", '\\');       //so we need two of them, to print one.
      printf("  ");
      for(i = 0; i < Rows; i++)  {    //format the team column names
        printf(" %c%c%c%c%c", teams[i][0],teams[i][1],teams[i][2],teams[i][3],teams[i][4],teams[i][5]);
      }
      printf(" Points");
      printf("\n-------------------------------------------------------------------------------");
        
      //print the rows
      for(i = 0; i < Rows; i++)  {
        printf("\n %s", teams[i]);
        namelen = strlen(teams[i]);
        if(namelen < maxlen)  {
          spaces = maxlen - namelen;
          while(spaces--)
            putchar(' ');
        }
        printf(" |");
        for(j = 0; j < NumberOfGames-1; j++) {
          if(scores[i][j] < 0) {
            printf(" --- |");
            continue;
          }
          //this is the scorecard flip trick:
          if(home[i][j])
            printf(" %d%c%d |", scores[i][j], 254,scores[j][i]);
          else
            printf(" %d-%d |", scores[i][j], scores[j][i]);
          //every game in on the scorecard TWICE, once from the 
          //perspective of each of the two teams.
        }
        printf(" %2d", scores[i][10]);
      }
    }
    void getPoints(int scores[Rows][NumberOfGames], int team, int home[Rows][NumberOfGames]) {
      int i, j;
      
      for(i=0;i<Rows;i++) {
        scores[i][10]=0;
        for(j=0;j<NumberOfGames-1;j++) {
          if(home[i][j] && scores[i][j] > scores[j][i]) //win at home +2
            scores[i][10]+=2;
          else if(!home[i][j] && scores[i][j] > scores[j][i]) //win at away +3
            scores[i][10]+=3;
          else if(scores[i][j] < scores[j][i]) //loss -1
            scores[i][10]--;
          else if(scores[i][j]==scores[j][i] && i != j) //draw +1
            scores[i][10]++;
        }
      }
    }
    
    
    Output:
    
     -1  1  0  1  0  1  0  1  0  1
      0 -1  1  0  1  0  1  0  1  0
      1  0 -1  1  0  1  0  1  0  1
      0  1  0 -1  1  0  1  0  1  0
      1  0  1  0 -1  1  0  1  0  1
      0  1  0  1  0 -1  1  0  1  0
      1  0  1  0  1  0 -1  1  0  1
      0  1  0  1  0  1  0 -1  1  0
      1  0  1  0  1  0  1  0 -1  1
      0  1  0  1  0  1  0  1  0 -1
    
    Kickers -1 2 3 4 3 2 1 1 5 4 0
    Kings 0 -1 3 2 3 0 4 2 2 4 0
    Flyers 2 3 -1 5 0 1 3 3 0 2 0
    Jaguars 1 1 1 -1 5 5 2 3 1 5 0
    Giants 4 2 0 2 -1 3 0 5 2 1 0
    Gladiators 3 0 3 1 4 -1 4 0 3 2 0
    Rogues 0 4 2 3 1 1 -1 6 4 3 0
    Miners 5 5 4 0 3 2 4 -1 0 0 0
    Titans 6 2 3 1 3 1 5 6 -1 3 0
    Eagles 3 3 1 2 5 0 5 4 1 -1 0
    
    
    
    \\\\\\\\\\   Kicke Kings Flyer Jagua Giant Gladi Rogue Miner Titan Eagle Points
    -------------------------------------------------------------------------------
     Kickers    | --- | 2-0 | 3-2 | 4-1 | 3-4 | 2-3 | 1-0 | 1-5 | 5-6 | 4-3 |  8
     Kings      | 0-2 | --- | 3-3 | 2-1 | 3-2 | 0-0 | 4-4 | 2-5 | 2-2 | 4-3 | 10
     Flyers     | 2-3 | 3-3 | --- | 5-1 | 0-0 | 1-3 | 3-2 | 3-4 | 0-3 | 2-1 |  5
     Jaguars    | 1-4 | 1-2 | 1-5 | --- | 5-2 | 5-1 | 2-3 | 3-0 | 1-1 | 5-2 |  8
     Giants     | 4-3 | 2-3 | 0-0 | 2-5 | --- | 3-4 | 0-1 | 5-3 | 2-3 | 1-5 | -1
     Gladiators | 3-2 | 0-0 | 3-1 | 1-5 | 4-3 | --- | 4-1 | 0-2 | 3-1 | 2-0 | 15
     Rogues     | 0-1 | 4-4 | 2-3 | 3-2 | 1-0 | 1-4 | --- | 6-4 | 4-5 | 3-5 |  3
     Miners     | 5-1 | 5-2 | 4-3 | 0-3 | 3-5 | 2-0 | 4-6 | --- | 0-6 | 0-4 |  5
     Titans     | 6-5 | 2-2 | 3-0 | 1-1 | 3-2 | 1-3 | 5-4 | 6-0 | --- | 3-1 | 14
     Eagles     | 3-4 | 3-4 | 1-2 | 2-5 | 5-1 | 0-2 | 5-3 | 4-0 | 1-3 | --- |  2
    
    		    Program Complete - Press Enter When Ready
    Last edited by Adak; 11-25-2012 at 11:01 AM.

  7. #7
    Registered User javaeyes's Avatar
    Join Date
    Feb 2012
    Posts
    153
    Thanks Adak for the verbose reply. This would definitely work. I'm going to go over it a bit more and factor in some more of my own requirements and decide which approach to take.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You can indicate home teams, etc., by using color in the points, but one of the spreadsheets great advantages, is it's ability to have columns with more data, but you "fold" them over and hide them out of the way, when you want to work with less detailed data - and font size, the ability to easily add columns or rows, and on and on.

    The program I show above, just gets more and more clumsy - it's meant for something very small, like a small tournament scorecard.

  9. #9
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by javaeyes View Post
    I'm going to go over it a bit more and factor in some more of my own requirements and decide which approach to take.
    I favor the approach from JohnGraham, to develop a structure. If you combine it with accessor functions, it can help maintain a top-down design in case you have expanding/unknown requirements.

    Example:

    Game_test.c
    Code:
    #include <stdio.h>
    #include "Game.h"
    
    int main()
    {
        struct Game games[20] = {Game_init()};
        
        // Initialize some games
        {
            int i=0;
            games[i++] = Game_create(.week_wk=1, .hometeam_tid=3, .awayteam_tid=10, .hometeam_score=30, .awayteam_score=14);
            games[i++] = Game_create(.week_wk=2, .hometeam_tid=10, .awayteam_tid=3, .hometeam_score=40, .awayteam_score=24);
            games[i++] = Game_create(.week_wk=3, .hometeam_tid=3, .awayteam_tid=10, .awayteam_score=14, .hometeam_score=6);
        }
        
        // Print out all recorded games
        for (int i=0; i < 20; i++)
            if (games[i].gid) {
                Game_print(games[i]);
                printf("\n");
            }
    }
    Game.h
    Code:
    #ifndef GAME_H__DEFINED
    #define GAME_H__DEFINED
    
    typedef int score_t;
    typedef int tid_t;
    typedef int week_t;
    
    struct Game {
        int gid;
        score_t hometeam_score;
        score_t awayteam_score;
        tid_t hometeam_tid;  
        tid_t awayteam_tid; 
        week_t week_wk;
    };
    
    struct Game Game_init(void);
    struct Game Game_create_(struct Game g);
    #define Game_create(...) Game_create_((struct Game){ __VA_ARGS__ })
    void Game_print(struct Game g);
    
    #endif
    The typenames score_t, week_t and tid_t can be optionally used to ease data validation; for example a week_t is an int with only a specific limited range.

  10. #10
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by c99tutorial View Post
    The typenames score_t, week_t and tid_t can be optionally used to ease data validation; for example a week_t is an int with only a specific limited range.
    I would suggest you not to typedef so that everything is clear.

    Quote Originally Posted by c99tutorial View Post
    I favor the approach from JohnGraham, to develop a structure.
    I am invisible. Just kidding

  11. #11
    Registered User javaeyes's Avatar
    Join Date
    Feb 2012
    Posts
    153
    Ok, I can create the array of structs, and I can start initializing the array within main, but really I want to do the initialization within a function init_games(). So I want to pass the array of structs into the function, and I want to work directly on the array, and not a local copy. So I assume I will need to pass in a pointer to the array of structs. Here's my attempt, please tell me what I am doing wrong here.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    void init_games(struct game_t *game)
    {
      game[0].week = 1; // MORE INITIALIZATION TO COME HERE...
    }
    
    
    typedef struct
    {
      int week;
      int hometeam;
      int awayteam;
      float homescore;
      float awayscore;
    } game_t;
    
    
    int main(void)
    {
      printf("FOOTBALL: \n");
      game_t game[10];
      init_games(&game);
    
      return 0;
    }

  12. #12
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Code:
    init_games(&game);
    write this instead
    Code:
    init_games(game);
    You should pass a pointer, not the address of the pointer

  13. #13
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Also since you typedef the struct you should have as argument of the function
    Code:
    game_t *game
    (without the struct)

    Aslo place the struct above the function , so that it is 'visible' to her.

    Like this
    Code:
    typedef struct
    {
      int week;
      int hometeam;
      int awayteam;
      float homescore;
      float awayscore;
    } game_t;
    
    
    
    void init_games(game_t *game)
    {
      game[0].week = 1; // MORE INITIALIZATION TO COME HERE...
    }

  14. #14
    Registered User javaeyes's Avatar
    Join Date
    Feb 2012
    Posts
    153
    This is my compiler output, when I try init_games(game)
    Code:
    c:26:3: warning: passing argument 1 of âinit_gamesâ from incompatible pointer type
    nfl1.c:6:6: note: expected âstruct game_t *â but argument is of type âstruct game_t *â

  15. #15
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Did you see my last post? If so, but the error still is alive, post your code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structure, user input and printing out results
    By alvarito in forum C Programming
    Replies: 3
    Last Post: 10-04-2011, 11:04 AM
  2. Record data types....Structures
    By Lego_TeCh in forum C Programming
    Replies: 6
    Last Post: 08-31-2009, 11:36 AM
  3. how to make function return value go to structure record
    By Tom Bombadil in forum C Programming
    Replies: 1
    Last Post: 05-27-2009, 03:38 PM
  4. linear search for structure (record) array
    By jereland in forum C Programming
    Replies: 3
    Last Post: 04-21-2004, 07:31 AM
  5. Add to my football strategy text game
    By real_cozzy in forum Game Programming
    Replies: 6
    Last Post: 01-20-2002, 05:09 PM