Printing 2 dimensional array of pointers to structs - c

I have been doing homework yesterday, I have done most of it, but couldn't make the main thing. I don't know why it's not working I have asked other students, but nobody knows what's the problem. Basically this program is a small game, there are 18 players 9 on each team. the program randomly gives players coordinates and directions and they start to move. I have basically done the program, but I have problem with field, It doesn't show the players at all.
I tried many things and when testing noticed that it doesn't print even testing string in the if statement I wrote. when I write this part field[i][j] = &players[k][0]; I have checked if field[i][j] really gets the x and y coordinate and yes it does. but in the print_field class it takes field[][] as null and the field is empty. players is an array of structs. field is an array of pointers that point to players or NULL.
I have tried with all of my knowledge and couldn't make any better.
What is wrong with this code? Why isn't it showing the players on the field?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define LENGTH 25
#define WIDTH 25
enum direction {Right, Left, Up, Down}; /*Right = 0, Left = 1, Up = 2, Down = 3*/
void print_field();
void random_positions();
void playerdirection();
void motion();
void game();
struct player
{
char *dora;
char *team;
char *name; //string?
int x,y; //coordinates
int direction;
};
typedef struct player Player;
struct player *field[WIDTH][LENGTH];
Player players[8][1];
int main()
{
srand (time(NULL));
int i; //players 9 in each team team1 = 0 team2 = 1
players[0][0].name = "A1";
players[1][0].name = "A2";
players[2][0].name = "A3";
players[3][0].name = "A4";
players[4][0].name = "A5";
players[5][0].name = "A6";
players[6][0].name = "A7";
players[7][0].name = "A8";
players[8][0].name = "A9";
players[0][1].name = "B1";
players[1][1].name = "B2";
players[2][1].name = "B3";
players[3][1].name = "B4";
players[4][1].name = "B5";
players[5][1].name = "B6";
players[6][1].name = "B7";
players[7][1].name = "B8";
players[8][1].name = "B9";
for(i = 0; i < 9 ; i++)
{
players[i][0].team = "Team A";
players[i][1].team = "Team B";
players[i][0].dora = "Alive";
players[i][1].dora = "Alive";
}
random_positions();
playerdirection();
print_field();
motion (Player player);
print_field();
game();
return 0;
}
void random_positions()
{
int i,j,k;
int xs[17],ys[17];
for(i= 0; i<9 ; i++)
{
players[i][0].x = rand() % 25;
players[i][0].y = rand() % 25;
players[i][1].x = rand() % 25;
players[i][1].y = rand() % 25;
printf("A%d x = %d y = %d \n",i+1,players[i][0].x,players[i][0].y);
printf("B%d x = %d y = %d \n",i+1,players[i][1].x,players[i][1].y);
}
for(i = 0; i < 9 ; i++)
{
xs[i] = players[i][0].x;
xs[i+8] = players[i][1].x;
ys[i] = players[i][0].y;
ys[i+8] = players[i][1].y;
for(j = 0; j <= i ; j++)
{
//printf("j%d start\n",j);
if(i != j && xs[i] == xs[j])
{
//printf("i%d start\n",j);
if(ys[i] == ys[j])
{
return random_positions();
}
//("j%d done\n",j);
}
//printf("j%d done\n",j);
}
}
for(i = 0; i < 25; i++)
{
for(j = 0; j < 25; j++)
{
for(k = 0; k < 9; k++)
{
if(i == players[k][0].x && j == players[k][0].y)
{
field[i][j] = &players[k][0];
}
if(i == players[k][1].x && j == players[k][1].y)
{
field[i][j] = &players[k][1];
}
else field[i][j] = NULL; //I da J sheidzleba shesacvleli iyos
}
}
}
}
/*this function prints out the given state of the field*/
void print_field(){
int i,j;
printf("\n");
printf("|0 1 2 3 4 5 6 7 8 9 101112131415161718192021222324|\n"); /*just to show easier the allignment*/
for(j=0; j<WIDTH+2; j++) /*This first loop goes through row and creates them each by each*/
{
if(j == 0 || j == WIDTH +1) /*creates the upper and lower part of the field*/
for(i=0; i<LENGTH+2; i++) /*there should be space for frame so I added 2 to LENGTH in the loop*/
{
if(i==0)
printf("-");
else if(i == LENGTH+1)
printf("-\n");
else printf("--"); /*3 decimals*/
}
else
for(i=0; i<LENGTH+2; i++) /*Goes through the columns in this row and creates either frame or puts the nodeid*/
{
if(i==0)printf("|"); /*frame*/
else if(i == LENGTH+1) printf("| %d\n",(j-1)); /*frame*/
else if(field[j-1][i-1] != NULL)
{
printf("aaa");
printf("%-*s",2,(*field[j-1][i-1]).name); /*putting nodeid 3 decimals*/
}
else printf(" ");
}
}
printf("\n");
}

You need Player[9][2] instead of Player[8][1]. You should initialize an array with its length although you could only access index up to length - 1 because arrays are indexed from 0.

Related

how to write a code that prints an specific numerical spiral pattern in c using for loops without array

I want to write a code that gets the integer n from the user and prints numbers in a spiral pattern from 1 to n*n without using arrays.
output for entering 5
input3
output:
1 2 3
8 9 4
7 6 5
do you have any suggestions on how to write this code?
EDIT:
here is the code using arrays:
#include <stdio.h>
int main(){
/*declaration of the variables*/
int i, j, ascendingNumbers;
int leftAndTop, rightAndBottom;
int size;
scanf("%d", &size);
int matrix[size][size];
leftAndTop = 0;
rightAndBottom = size - 1;
ascendingNumbers = 1;
/*filling the array*/
for(i = 1; i <= size/2; i++, leftAndTop++, rightAndBottom--){
/*left to right*/
for(j = leftAndTop; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[leftAndTop][j] = ascendingNumbers;
}
/*top to bottom*/
for(j = leftAndTop + 1; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[j][rightAndBottom] = ascendingNumbers;
}
/*right to left*/
for(j = rightAndBottom-1; j >= leftAndTop; j--, ascendingNumbers++){
matrix[rightAndBottom][j] = ascendingNumbers;
}
/*bottom to top*/
for(j = rightAndBottom - 1; j >= leftAndTop+1; j--, ascendingNumbers++){
matrix[j][leftAndTop] = ascendingNumbers;
}
}
/*fill the center for odd size*/
if(size % 2){
matrix[leftAndTop][j + 1] = ascendingNumbers;
}
/*print*/
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
One solution is to take code that already can fill an array with the spiral pattern, and put it in a nested loop that uses that code to find the number for the current printing position. There are certainly more efficient solutions, but this allows you to transform a solution that works for arrays into one that does not need arrays.
The first program here uses an array to print a spiral pattern of numbers. The second program is a modified version of the first that prints a number when the printing position matches the position in the spiral loop instead of storing it in an array. I'll leave it to you to see if you can modify your existing code to accomplish this.
Using a 2d array:
/* A program that prints a spiral using a 2d array */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 1) {
fprintf(stderr, "Usage: spiral N [N > 0]\n");
return 1;
}
int arr[size][size];
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
int side_len = size;
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around the spiral to fill the array
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
arr[row][col] = i + 1;
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++) {
printf("%4d", arr[row][col]);
}
putchar('\n');
}
putchar('\n');
return 0;
}
Using only loops:
/* A program that prints a spiral using loops but no arrays */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 0) {
fprintf(stderr, "Usage: spiral N [N >= 0]\n");
return 1;
}
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
// loop printing positions: print a row at a time
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int side_len = size; // length of current side
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around spiral until printing number is reached
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
if (row == y && col == x) { // print and escape loop
printf("%4d", i + 1);
break;
}
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
}
// newline after row
putchar('\n');
}
// newline after printing all numbers
putchar('\n');
return 0;
}
Here are a couple of sample interactions with the second program:
>$ ./spiral2 3
1 2 3
8 9 4
7 6 5
>$ ./spiral2 6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11

Created a simulation of 5 card hands to see probability of royal flush

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main() {
int i, n, j, a, g;
int d=0;
int k=0;
int hold[5];
time_t t;
typedef struct card{
int suit;
int value;
} cards;
struct card deck[52];
struct card *hand=malloc(sizeof(char));
n = 5;
void shuffle(cards *array, size_t q) {
if (q>1) {
size_t w;
for (w = 0; w < q - 1; w++)
{
srand(time(NULL));
size_t e = w + rand() / (RAND_MAX/ (q - w) + 1);
cards t = array[e];
array[e] = array[w];
array[w] = t;
}
}
}
for (g=0; g < 1000000; g++) { // the for loop that controls how many times this simulation occurs
for (i=0; i<13; i++) {// the following for loops create a deck in order (Ace to King spades, Ace to King clubs, etc)
deck[i].suit = 1;
deck[i].value =i+1;
}
for (i=13; i < 26; i++) {
deck[i].suit = 2;
deck[i].value = i - 12;
}
for (i=26; i < 39; i++) {
deck[i].suit = 3;
deck[i].value = i - 25;
}
for (i=39; i < 52; i++) {
deck[i].suit = 4;
deck[i].value = i - 38;
}
for (i=0; i < 1; i++) // shuffles the deck by randomizing deck[i]{
shuffle(deck, 53);
}
j=51;
for (i=0; i < n; i++) { // deals 5 random cards to a persons hand
srand(time(NULL));
k = rand()%j;
hand[i] = deck[k];
if (k != j) {
deck[k] = deck[j];
}
j = j-1;
}
for (i=0; i < n; i++) {
for (j=i+1; j < n; j++) {
if (hand[i].value > hand[j].value) {
a = hand[i].value;
hand[i].value = hand[j].value;
hand[j].value = a; //organizes the persons hand from smallest to largest card values
}
}
}
if (hand[4].value == 13 && hand[3].value == 12 && hand[2].value == 11 && hand[1].value == 10 && hand[0].value == 9) { if (hand[4].suit == hand[3].suit && hand[4].suit == hand[2].suit && hand[4].suit == hand[1].suit && hand[4].suit == hand[0].suit) {
d++;
// since the hand is organized from smallest to largest, if hand[5] is Ace, hand[4] is king etc, then we have a hand that goes from 10 to Ace (smallest to largest, 10 is actually 9 in this case). If all of the suit values are the same, then we have a royal flush. Therefore, increment variable d.
}
}
}
// do that however many times, and after it is done print d.
printf("%d\n", d);
return (0);
}
The problem with my code is that it always prints d = 0. I run the simulation upwards 10 million times, but still d is 0. The probability of being dealt a royal flash is 1 in 649,740 so I should expect to see a few flushes if I run it that many times. Is there an error in my code?
Any help would be greatly appreciated.
Insufficient memory allocated. #Weather Vane
Rather than allocating 1 char for hand, code should allocate enough for 5 card.
// struct card *hand = malloc(sizeof(char));
n = 5;
struct card *hand = malloc(sizeof *hand * 5);
... or simply
struct card hand[5];
Code excessive calls srand(time(NULL));. Best to call srand() only once. Each call resets the random number sequence. Calling srand() will the same value (same time) will generate the same sequence of results from rand(). #M.M
Local definition of void shuffle(cards *array, size_t q) inside main() is not standard C.
--
Odds of royal flush are 1 in 649,740. A simulation 1,000,000 hands may be insufficient.

Why are my array elements getting overridden?

I stared at this code for at least 4 hours.
I'm not sure what I'm doing wrong.
I'm updating the array hand[5][2] with a simple for loop.
The values stored in hand[0][2], hand[0][3] and hand[0][4] keep getting overwritten.
I used the debugger to go slowly through every single line but I still don't
understand why I'm getting different values.
This is the output I'm getting
hand[0][0] = 0
hand[0][1] = 1
hand[0][2] = 2
hand[0][3] = 3
hand[0][4] = 4
hand[1][0] = 0
hand[1][1] = 1
hand[1][2] = 2
hand[1][3] = 3
hand[1][4] = 4
0 1 0 1 2 // WHY ARE hand[0][2],hand[0][3],hand[0][4] not the same????
0 1 2 3 4
Code:
int main() {
//tests();
int hand[5][2];
int a[5], b[5];
char line[100];
int player = 0;
int card = 0;
for (int i = 0; i < 10; i++) {
hand[player][card] = card;
printf("hand[%d][%d] = %d\n", player, card, hand[player][card]);
card++;
if (card == 5) { player++; card = 0; }
}
// print first hand
for (int j = 0; j < 5; j++) {
printf("%d ", hand[0][j]);
}
printf("\n");
// print second hand
for (int j = 0; j < 5; j++) {
printf("%d ", hand[1][j]);
}
printf("\n");
return 0;
}
int hand[5][2]; should be int hand[2][5];

Sub Grouping algorithm

Recently, someone asked me to make a C program that "groups" (his words, not mine!) numbers into pairs.
Here's how it works.
First, the user inputs the maximum range:(let's say) 10
Now, user inputs a number: (let's say) 4.
Then, the program groups 4 and 5 together. (ie. n and n+1)
Next User Input: 8
The program groups 8 and 9 as well.
Now, this goes on.
Exceptions: If the user enters a number that has already been grouped, like 4,5,8 or 9. Then the group which it belongs to gets removed altogether. Also, the program invalidates inputs that require pairing with numbers that are already paired. Eg. If 4 and 5 are paired, 3 is not a valid input.
Also, entering the extremes (here, 1 and 10) is not allowed.
I made the above program in C, using Visual Studio 2013. I have provided the code below.
My questions are:
A) How could I have made my code considerably better?(Apart from initializing the array AFTER accepting the max input)
B) More importantly, can someone tell me what this algorithm is? Is this a standard problem? Does it have any real world application/implementation? Or is it just some random idea?
#include<stdio.h>
#inlcude<conio.h>
#define array_size 10
int group[array_size][2] = { 0 };
int n = 0, max=0, search = 0, max_mem = 0;
int tcount = 2;
void sort(int x[][2]);
void print_groups();
void test_print();
void main()
{
group[0][0] = 0;
group[0][1] = 1;
printf("Enter a number:");
scanf_s("%d", &max);
max_mem = (max/2)+1;
if (max_mem > array_size)
{
printf("Not enough memory assigned!");
return;
}
else
{
group[max_mem-1][0] = max;
}
print_groups();
test_print();
while (1)
{
printf("Enter a number:");
scanf_s("%d", &n);
if ((n <= 1) || (n >= max-1))
{
printf("Invalid entry!");
continue;
}
search = 0;
for (int i = 1; i < max_mem; i++)
{
for (int j = 0; ((j < 2)&&(search!=1)); j++)
{
if (n == group[i][j])
{
group[i][0] = 0;
group[i][1] = 0;
search = 1;
}
if (group[i][0]==n+1)
{
printf("Already group exists -> (%d,%d)", group[i][0], group[i][1]);
//getch();
search = 1;
}
}
}
if (search != 1)
{
group[1][0] = n;
group[1][1] = n + 1;
}
printf("\nSorting!\n");
sort(group);
//clrscr();
print_groups();
test_print();
}
}
void sort(int x[][2])
{
int i, j, t[1][2];
for (i = 1; i <= max_mem - 2; i++)
for (j = 2; j <= max_mem-1 - i; j++)
if (x[j - 1][0] >= x[j][0])
{
t[0][0] = x[j - 1][0];
x[j - 1][0] = x[j][0];
x[j][0] = t[0][0];
t[0][1] = x[j - 1][1];
x[j - 1][1] = x[j][1];
x[j][1] = t[0][1];
}
}
void print_groups()
{
printf("The group is:\n%d ", group[0][1]);
for (int i = 1; i < max_mem-1; i++)
{
if (group[i][0] != 0)
{
printf("(");
printf("%d,", group[i][0]);
printf("%d", group[i][1]);
printf(")");
}
}
printf(" %d.", group[max_mem - 1][0]);
printf("\n");
}
void test_print()
{
printf("Array Formation:\n");
for (int i = 0; i < array_size; i++)
{
printf(" %d,%d ", group[i][0], group[i][1]);
}
printf("\n");
}
Sounds like it's just some random idea. You can simplify your code by using a one-dimensional array, where each entry in the array is
0 for numbers not in a group
1 for the first number of a group
2 for the second number of a group
For example, if array[4] is 1 and array[5] is 2, then 4 and 5 are a group.
When the user enters a new number, it's easy to update the array. Here's an example in pseudo-code of how the array would be updated if the user enters the number 7
if (array[7] == 0 and array[8] == 0)
array[7] = 1, array[8] = 2
else if (array[7] == 0 and array[8] == 1)
input is invalid
else if (array[7] == 1)
array[7] = 0, array[8] = 0
else if (array[7] == 2)
array[6] = 0, array[7] = 0

Find the duplicate elements in a two-dimensional array

I need to find the duplicate elements in a two dimensional array.
route_ptr->route[0][1] = 24;
route_ptr->route[0][2] = 18;
route_ptr->route[1][1] = 25;
route_ptr->route[2][1] = 18;
route_ptr->route[3][1] = 26;
route_ptr->route[3][2] = 19;
route_ptr->route[4][1] = 25;
route_ptr->route[4][2] = 84;
Those are my data; the duplicate entries of route[2][1] (duplicate of route[0][2]) and route[4][1] (duplicate of route[1][1]) has to be found.
The solution is the duplicate 'i' value of route[i][j] which is 2 & 4 from this example.
please guide me.
#include <stdio.h>
struct route{
int route[6][6];
int no_routes_found;
int count_each_route[6];
};
int main() {
struct route *route_ptr, route_store;
route_ptr=&route_store;
int i,j,k;
// the data
route_ptr->route[0][1] = 24;
route_ptr->route[0][2] = 18;
route_ptr->route[1][1] = 25;
route_ptr->route[2][1] = 18;
route_ptr->route[3][1] = 26;
route_ptr->route[3][2] = 19;
route_ptr->route[4][1] = 25;
route_ptr->route[4][2] = 84;
route_ptr->count_each_route[0]=3;
route_ptr->count_each_route[1]=2;
route_ptr->count_each_route[2]=2;
route_ptr->count_each_route[3]=3;
route_ptr->count_each_route[4]=3;
route_ptr->no_routes_found=5;
//// process
for (i = 0; i <(route_ptr->no_routes_found) ; i++)
{
for (j = 1; j < route_ptr->count_each_route[i]; j++)
{
printf("\nroute[%d][%d] = ", i, j);
printf("%d",route_ptr->route[i][j]);
}
}
}
The solution expected is:
route[0][1] is compared by route [0][2] i.e [24 !=18]
route[0][1] and route [0][2] is compared by route[1][1] i.e [24 && 18 !=25]
route[0][1] and route[0][2] and route[1][1] is compared by route[2][1] i.e [ 24&&18&&25 is compared by 18, there is a matching element,
save the newcomer 'i' value which matches to the existence and drop it for next checking]
break the 'i' loop
route[0][1], route[0][2], route[1][1] is now compared route[3][1]
route[0][1], route[0][2], route[1][1] ,[3][1] is now compared route[3][2]
route[0][1], route[0][2], route[1][1] ,[3][1] ,[3][2] is now compared to route [4][1] i.e [ now there is a match to route[1][1], so save the newcomer 'i' value and break the 'i' loop
So i values [2 and 4] are duplicate, and that is my expected result of my code.
Got something against index zero, zero?
I also don't see the point of the pointer shenanigans.
It's a general safety thing to initialize all your data. You know, to zero or something.
The algorithm you suggest in your solution is rather hard to be faithful to, but this will find your duplicates. You have to walk through the entire array, in both dimensions, twice.
This will also match all the zeroes in your data, so you could add an exception to ignore routes values of zero.
//Cycling through the array the first time.
for (i = 0; i < 6 ; i++)
{
for (j = 0; j < 6; j++)
{
//Cycling through the array the second time
for (x = 0; x < 6 ; x++)
{
for (y = 0; y < 6; y++)
{
if(i==x && j==y)
continue;
if(routestore.route[i][j] == routestore.route[x][y])
printf("You have a match [%d][%d] = [%d][%d]", i, j, x,y);
}
}
}
}
Ok, so if you only want to see matches once, ie [0][2] == [2][1] but not [2][1] == [0][2], then you can do something like what I have below. This one made me scratch my head. Usually, when it's a simple list of items, you initialize the inner loop to the value of the outer loop, plus one. But you can't quite do that when it's a 2D array. So I gave up and made a super-lame hack-job. I'm a big fan of brute forcing things when possible. I'd normally tell you not to use pointers like this.
Now... this will still have multiple hits if you have three similar values. If that irks you then you need to start building a list and comparing hits against that as you walk through the data.
#include <stdio.h>
#include <string.h>
struct route{
int route[6][6];
int no_routes_found;
int count_each_route[6];
};
int lameAddOneAlternative(int *i, int *j)
{
if((*j)<6)
{
(*j)++;
return 1;
}
else if (*i<6)
{
(*i)++;
(*j) = 0;
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
struct route routeStore;
int i,j,x,y;
memset(routeStore.route,0,sizeof(int)*36);
// the data
routeStore.route[0][1] = 24;
routeStore.route[0][2] = 18;
routeStore.route[1][1] = 25;
routeStore.route[2][1] = 18;
routeStore.route[3][1] = 26;
routeStore.route[3][2] = 19;
routeStore.route[4][1] = 25;
routeStore.route[4][2] = 84;
//Cycling through the array the first time.
for (i = 0; i < 6 ; i++)
{
for (j = 0; j < 6; j++)
{
x=i;
y=j;
//Cycling through the array the second time
while(lameAddOneAlternative(&x,&y))
{
if(routeStore.route[i][j] == 0 )
continue;
if(routeStore.route[i][j] == routeStore.route[x][y])
printf("You have a match [%d][%d], [%d][%d] == %d\n", i, j, x,y, routeStore.route[i][j] );
}
}
}
}
for (i = 0; i <(route_ptr->no_routes_found) ; i++)
{
for (j = 1; j < route_ptr-> count_each_route[i]; j++)
{
for (x = 0; x < (route_ptr->no_routes_found) ; x++)
{
for (y = 0; y < route_ptr-> count_each_route[x]; y++)
{
if(i==x && j==y)
continue;
if(route_ptr->route[i][j] == route_ptr->route[x][y])
printf("You have a match [%d][%d] = [%d][%d]\n", i, j, x,y);
}
}
}

Resources