1

I'm working on a table football cup program (in C), where I have 16 people facing off to get to the final. I'm having trouble putting elements into the different elements of the array (which has sort of stopped my progress until I figure it out). I've searched on the internet (not extensively) about pointers, but I can't find anything on multi dimensional arrays.


I have 8 games, each with 2 participants, who each play 5 matches against each other. Hopefully that means I define the array as int lastSixteen[8][2][5]. All participants have a unique ID

Assuming I have declared my arrays correctly... On to the main question.

This is what I'm currently doing:

int i;
for(i=0; i<MAX_PLAYERS/2;i++){
    roundOne[i] = i;
}

I want to set the first dimension of my array to be the numbers 1 through 8 incl. but I run into 'error: incompatible types in assignment'.

I tried setting the line with the assignment to be roundOne[i][][] = i; but as I expected, that didn't work either.


Later on in the program I need to set the second set of numbers to be the games participants to be the 16 participants (to keep it simple I'm doing it in ascending numerical order) so Game 1 is Player 1 and Player 2, Game 2 is Player 3 and 4 etc.

for(i=0; i<16; i++){
    if(i % 2 != 0){
        roundOne[(MAX_PLAYERS/2)-1][0] = i; /* puts 1,3,5,7,9,11,13,15 */
    }
    else{
        roundOne[(MAX_PLAYERS/2)-1][1] = i; /* puts 2,4,6,8,10,12,14,16 */
    }
}

I'm assuming the second part will be fixed by the answer to the first part since they return the same error, but I included it because I don't know.


A sample of code that has a minimal, Complete, and Verifiable example.

#include <stdio.h>

#define MAX_PLAYERS 16

int main(void){

    int i;
    int roundOne[8][2][5];

    /* seeded in numerical order.*/
    for(i=0; i<MAX_PLAYERS/2;i++){
        roundOne[i] = i;
    }
    for(i=0; i<MAX_PLAYERS; i++){
        if(i % 2 != 0){
            roundOne[(MAX_PLAYERS/2)-1][0] = i;
        }
        else{
            roundOne[(MAX_PLAYERS/2)-1][1] = i;
        }
    }

    return 0;
}

Thanks in Advance,

Rinslep

Rinslep
  • 65
  • 10
  • Apparently you did **not** "declare your arrays correctly". Provide a [mcve]. – too honest for this site Nov 02 '15 at 21:19
  • Sorry, didn't want to clutter the post. Will edit now. – Rinslep Nov 02 '15 at 21:21
  • `roundOne[i][][]` is not going to work, `roundOne[i][0][0]` will work better. – Linus Nov 02 '15 at 21:23
  • 2
    @Rinslep You can torture yourself with a 3D array if you like, but a simple array of 8 structs each holding 2 player names and a way to determine the outcome of 5 games sure seems a lot easier approach to the problem. – David C. Rankin Nov 02 '15 at 21:24
  • Now I'm feeling like an idiot, because I would be using the game struct a lot. Could I use an array of these structs? `typedef struct gameInfo{int player1; int player2; int match[5]}game;` – Rinslep Nov 02 '15 at 21:31

2 Answers2

1

You can't just use a multi dimensional array - it doesn't do what you want. And here is why: Lets say you have 8 games and 2 players (forget that there are 5 matches for a second) That means your multi dimensional array would have 16 spots:

      Player
      0   1
    +---+---+
  0 |   |   |
    +---+---+
  1 |   |   |
    +---+---+
  2 |   |   |
G   +---+---+
a 3 |   |   |
m   +---+---+
e 4 |   |   |
    +---+---+
  5 |   |   |
    +---+---+
  6 |   |   |
    +---+---+
  7 |   |   |
    +---+---+

Now you want to put the game number in there AND you want to put the unique player IDs in there AND you might want to put other stuff in there (like who won and the score)? How are you going to do that? There are a couple choices:

  1. The game number is the index into the array - not a value you store in the array. Now you can store the palyer IDs for each game in the array. But this still doesn't address storing other stuff (like who won and the score)
  2. If the game number needs to be stored in the array (or other things like who won and the score) you will need to store more than one thing in the array so the array cannot hold ints - you need an array of structures.

It is hard to guess what the right data structure is because it depends on what your program is going to do, but I think I would do this:

typedef struct match
{
  int score[2]; /* index 0 is player 1, index 1 is player 2 */
  int winner; /* index into the player and score arrays (either 0 or 1) */
};

typedef struct game
{
  int players[2]; /* index 0 is player 1, index 1 is player 2 */
  match matches[5];
};

game games[8];

Now, the the game number (1-8) is just the index to games plus 1, the match number (1-5) is just the index to matches plus 1 and if you want to make unique player numbers that go from 1-16 you can do this:

i=1;
for(int g=0;g<8;g++)
  for(int p=0;p<1;p++)
    games[g].player[p]=i++;
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • Although I disagree on the types generated, I agree with the point that rather than a 3D array `[game]*[players_per_game]*[team_count]`, it makes more sense to create arrays (or lists) of `teams` and `games`, etc. – chux - Reinstate Monica Nov 02 '15 at 22:42
  • A list of games with fields: team[2], score[2], state (W,L,T,not played, canceled), playing site, date , etc.. An array of teams with fields: name and a list of pointers to the above games - (possible as an array of 8). Prefer list (e.g. linked) when access is usually sequential. Arrays are good for random access. – chux - Reinstate Monica Nov 02 '15 at 23:28
0

You need to initialize the array with dynamic allocation.

How do I work with dynamic multi-dimensional arrays in C?

Think of it this way

A = [
      [B],
      [C],
      [D],
      ...
    ]

So lets say we need an array round with 10 rows and each row has 20 columns. They will all be filled with integer values.

Option One - Dynamically Allocating

  1. Define the number of buckets the array will have. We are taking the size of the pointer because each bucket will container a pointer/array that represents the inner array.

    int** round;
    round = malloc(10 * sizeof(int*))
    
  2. Now that we have allocated the space for the buckets, go through and give space for the points. This one is just a normal integer so we take the sizeof(int).

    for (int i = 0; i < 10; i++) {
        round[i] = malloc(20* sizeof(int))
    }
    

Option Two

  1. We can define the size of the multidimensional array in a bit of an easier way. We know the number of rows and the number of columns. So alternatively we can allocate the space like this:

    int* round;
    round = malloc (10 * 20 * sizeof(int));
    

Both of these will produce the array round[10][20] with memory allocated for it. With C you can't add elements to an array on the fly if the size of the array is unknown, in my experience linked lists are better for this.

Edit: I see that you updated the question, this code can be used with a 3D array also. You can easily use option two as 3D like round = malloc(x * y * z * sizeof(int)), where x, y, and z are equal to the dimensional values. You can also modify option one to work with this also.

Community
  • 1
  • 1
kyle
  • 2,563
  • 6
  • 22
  • 37
  • Yes you would access it through the pointer. Keep in mind that pointers can use the array notation also, so if you have the pointer int** round and have malloced the space using one of the above options you could do something like round[0][0] to get the top top left element of the matrix. – kyle Nov 02 '15 at 21:51