Coursework - Creating a Match-3 "Candy Crush" Game in C - c

I'm having a little bit of trouble on an assignment and am looking for some advice. I'm supposed to create a "game" that is similar to Candy Crush or Bejeweled. The assignment takes in a .txt file that contains a matrix of values from 1-5 and then assigns each value to a spot in a [10][10] array. Then an Escape Code function prints out colored pixels in place of the number values for each spot, creating a "game board" looking output. Finally, the program is supposed to look for any matches of 3 same-colored pixels and replace them with a white pixel and "XX". Then the program prints the corrected game board with the matches X'd out.
I have it mostly coded, but I've encountered a couple of issues...
1.) I am supposed to label the columns and rows 0-9, and while I have no problem coding the labels for the columns using printf( ), when I try to print the row labels I get a random string of numbers.
2.) I replaced the matches with white pixels by reassigning the value in the array to 7, for which the ANSI Escape Code is white. However, I'm unsure about how to print the "XX" in the same spot.
I wish I could post some pictures as an example but I don't have enough "reputation" on this site as a new account. I've included my code so far below.
#include <stdio.h>
void printEscapeCode(int c);
int main(void)
{
/* Declare an image array to be gameboard */
int gameboard[10][10];
/* Declare variables and load in how many rows and columns */
int Nrows;
int Ncols;
scanf("%d %d",&Nrows, &Ncols);
/* Load in candy values for each row */
int row, col;
for(row = 0; row < Nrows; row++)
{
/* Load in candy values for each column */
for(col = 0; col < Ncols; col++)
{
/* Declare variable to hold value */
int x;
scanf("%d",&x);
/* Tell where to store candy value */
gameboard[row][col] = x;
}
}
/* Calls function to print candy colors for each row */
printf(" 0 1 2 3 4 5 6 7 8 9\n");
for(row = 0; row < Nrows; row++)
{
printf("0 ");
/* Calls function to print candy colors for each column */
for(col = 0; col < Ncols; col++)
{
/* If statement to look for three matching candies */
if(gameboard[row][col] == gameboard[row+1][col] && gameboard[row+1][col] == gameboard[row+2][col])
{
/* Sets matching candies to display white */
gameboard[row][col] = 7;
gameboard[row+1][col] = 7;
gameboard[row+2][col] = 7;
}
if(gameboard[row][col] == gameboard[row][col+1] && gameboard[row][col+1] == gameboard[row][col+2])
{
gameboard[row][col] = 7;
gameboard[row][col+1] = 7;
gameboard[row][col+2] = 7;
}
printEscapeCode(gameboard[row][col]);
}
printEscapeCode(7);
printf("\n");
}
return 0;
}
/* Function that prints candy colors */
void printEscapeCode(int c){
printf("\x1b[4%dm ",c);
}

Related

Input multiple values to multidimensional array C

I have an assignment where I have to make a program that takes in 3 sets of data of 5 values and adds them to a 3 * 5 array. I have already made a program where you type in each individual value, but I would rather want it to take in five values over 3 different inputs.
The code is not finished. I also have to do some operations on the data but I got that covered.
#include <stdio.h>
#include <stdlib.h>
#define THREE 3
#define FIVE 5
void totalArray(int, int, int set_numbers[][FIVE]);
void totalArray(int row, int column, int set_numbers[][FIVE]){
int total, subtotal;
printf("\tThe total of your 3-by-5 array is:\n");
for(row = 0, total = 0; row < THREE; row++){
// for each row, the numbers are summed
for(column = 0, subtotal = 0; column < FIVE; column++){
subtotal += set_numbers[row][column];
printf("%d %d", row, subtotal);
total += subtotal; // Total for entire array
}
}
}
int main(){
// 2D array of 15 numbers declaration
int set_numbers[THREE][FIVE] = {{}, {}, {}};
//counter variables for the loop
int i, j, column, row;
printf("\tYou're given an array which is a 3 by 5 array.\n");
printf("\tYou're going to put in each of the total 15 values.\n");
printf("\t___________________________________________________\n");
printf("\n\t\t\t--ATTENTION--\n");
for(i = 0; i < 3; i++){
for(j = 0; j < 5; j++){
printf("\n\t ******************************************");
printf("\n\t ** Array values have to be integers **");
printf("\n\t ******************************************");
printf("\n\tWhich values do you want in set_numbers[%d][%d]\n", i, j);
scanf("%d", &set_numbers[i][j]);
}
}
totalArray(row, column, set_numbers);
printf("The average of your three sets of numbers are: \n\n");
for(i = 0; i < 3; i++){
for(j = 0; j < 5; j++){
printf("%d", set_numbers[i][j]);
if(j == 4){
printf("\n");
}
}
}
return 0;
}
I should specify, that what i want it to do, is take in sets of data. Something along the lines of
int array[][] = {{}, {}, {}}
First, you should rename the macros THREEto COLUMNS and FIVE to ROWS, because it doesn´t make much sense to name macros after values. Consider, that you might want to change the values later and the understanding of what these macros are meant for is unclear at first sight.
Furthermore i don´t see any reason for declare the separate variables column and row inside of main() if you already have such macros. Please adjust that (You also need to change the declaration of totalArray() respectively).
Than you can incorporate this loop:
for (i = 0; i < COLUMNS; i++)
{
scanf("%d %d %d %d %d", &set_numbers[i][0], &set_numbers[i][1], &set_numbers[i][2], &set_numbers[i][3], &set_numbers[i][4]);
}
And you should really only use the macros, instead of hardcoding the actual values in the program. Consider you need to change the values later, then you need to go through the whole program again and change the according parts (which is relatively easy in your case, but just shouldn´t be). Consider also, you need to change them thereafter back again. That is the reason also, what the macros are meant for.

How can I delete N number of rows and columns of a 2d array selected by the user in c

I am writing a piece of code that uses a struct containing a 2d array and predetermined functions which I have listed with comments describing what the function does.
struct matrix
{
char name;
int mValues[10][10[;
int nrows;
int ncols;
};
/** Function Prototypes**/
// Lets user name, choose dimensions and populates matrix from a 10x10 .txt file
void matrixInput(struct matrix *matA);
// Asks the user to choose how many rows to delete and select which rows
// Asks the user to choose how many columns to delete and select which columns.
// The result should be a sub matrix of the input matrix stored in a new struct matrix
void subMatrix(struct matrix m1, struct matrix *m2);
// What the Input/Output should look like
How many rows do you want to delete? : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 2
Please enter, one per row, the number(s) of the 2 rows you want to delete : 1
How many columns do you want to delete? : 3
Please enter, one per column, the number(s) of the 3 columns you want to delete : 4
Please enter, one per column, the number(s) of the 3 columns you want to delete : 2
Please enter, one per column, the number(s) of the 3 columns you want to delete : 5
// Displays sub matrix
It's the last function I am having problems with.
I know the size of the input matrix and I think that I need to some how tell the complier pass the values of the input matrix to the new struct matrix while excluding the value of the user input for row/col number to be deleted. I'm not sure if this could be done in a nested loop or if I would need other variables to store values.
I know how to read and pass values at a given index but I'm stuck for ideas when it comes to not reading and passing values at a given index.
Can anybody point me in the right direction?
Side note, any tips on how to improve the quality of my question is welcomed.
If you know which columns and rows to delete, and you are sure that the result is going to fit in the new matrix, then just do a nested loop and tell it to ignore a certain range of values.
But what you really want to do is create the new matrix inside the copying function and return it. If they are created dynamically you can ignore assignment of the columns or rows you are trying to copy in the same way (nested loops) and fit it exactly with the size you need.
You can't easily store delete information in a matrix, because matrix->values[0][0] could refer to either row or column. It's easier to declare to integers instead.
The function void subMatrix(struct matrix m1,...) is technically okay if you don't want to change m1, but this makes an extra copy of m1 which is not efficient. It's better to use void subMatrix(const struct matrix *source,...) instead.
You can also use dynamic allocation instead of fixed array of value[10][10]. Example:
struct matrix {
int **data;
int rows;
int cols;
};
void create(struct matrix *m, int rows, int cols)
{
m->rows = rows;
m->cols = cols;
m->data = malloc(rows * sizeof(int*));
for(int r = 0; r < rows; r++)
m->data[r] = malloc(sizeof(int) * cols);
}
void destroy(struct matrix *m)
{
for(int i = 0; i < m->rows; i++)
free(m->data[i]);
free(m->data);
}
void print(const struct matrix *m)
{
for(int r = 0; r < m->rows; r++)
{
for(int c = 0; c < m->cols; c++)
printf("%4d", m->data[r][c]);
printf("\n");
}
printf("\n");
}
void change(struct matrix *new, struct matrix *m, int *delete_rows, int *delete_cols)
{
int rows = 0;
for(int row = 0; row < m->rows; row++)
if(!delete_rows[row])
rows++;
int cols = 0;
for(int col = 0; col< m->cols; col++)
if(!delete_cols[col])
cols++;
create(new, rows, cols);
int next_row = 0;
for(int row = 0; row < m->rows; row++)
{
if(delete_rows[row]) continue;
int next_col = 0;
for(int col = 0; col < m->cols; col++)
{
if(delete_cols[col]) continue;
new->data[next_row][next_col] = m->data[row][col];
next_col++;
}
next_row++;
}
}
int main(void)
{
struct matrix m;
create(&m, 10, 10);
for(int r = 0; r < m.rows; r++)
for(int c = 0; c < m.rows; c++)
m.data[r][c] = r * 100 + c;
print(&m);
//get delete information
int delete_rows[10] = { 0 };
int delete_cols[10] = { 0 };
delete_rows[0] = 1;//delete row 0
delete_cols[7] = 1;//delete col 7
struct matrix new;
change(&new, &m, delete_rows, delete_cols);
print(&new);
destroy(&m);
destroy(&new);
return 0;
}

Strange Output while using the iterating variable of a "for" loop in C

I'm currently developing a simple naval battle game for my first exam at my college but i'm getting a strange output on my gameboard...
It should be iterating my "j" variable, but instead I get that strange character...
Here's my code:
//CREATES COORDENATES OF THE GAMEBOARD
//ATTRIBUTE ONE LETTER TO EACH TRAY LINE
for (i=0;i<11;i++){
tabuleiro[i][0] = letra[i-1];
}
//ATTRIBUTE ONE NUMBER TO EACH TRAY COLUMN
for (j=1;j<11;j++){
tabuleiro[0][j] = j;
}
//CREATES THE "SEA"
for (i=1;i<11;i++){
for (j=1;j<11;j++){
tabuleiro[i][j] = '~';
}
}
I've tryied to change my tabuleiro[0][j] = j; to tabuleiro[0][j] = (j+'0'); but then it only iterates until 9 and give me strange characters again...
If I'm not wrong I think this has something to do with the ASCII code (please correct me if I'm wrong) but I've no clue how to fix this.
Could you explain me how can I solve this please.
to have precise control of the character i suggest
tabuleiro[0][j] = "123456789T"[j];
This will pick the jth character from that string
BTW the reason you got ':' is becasue ':' is the next ascii character after '9' - see http://www.asciitable.com/
The issue is the char code for 10 + '0' = 58 which is the char code for ':'. You might consider removing the column and row names out of the game array. They are just labels and not part of the game (I assume).
#define board_size 10
And
// Create game board and initialize grid to '~', in main() possibly
// Game is 10x10 grid
char tabuleiro[board_size][board_size];
for (int row = 0; row < board_size; row++) {
for (int col = 0; col < board_size; col++) {
tabuleiro[row][col] = '~';
}
}
Have a function that draws the game board:
void drawBoard(char tabuleiro[board_size][board_size]) {
// Print top line
printf(" ");
for (int col = 0; col < board_size; col++) {
printf(" %-2d", col+1);
}
printf("\n");
// Print grid
for (int row = 0; row < board_size; row++) {
// Print letter
printf("%c ", 'A' + row);
// Print board
for (int col = 0; col < board_size; col++) {
printf(" %c ", tabuleiro[row][col]);
}
printf("\n");
}
}

Printing a pattern to the screen in C

I'm in my first programming course ever and have a few questions about an assignment that we've been given.
I'm trying to print the following pattern to the screen:
*
***
*****
*******
The pattern is supposed to contain 5 rows and each subsequent row has 2 additional asterisks from the row above making roughly a pyramid shape.
I've been working on creating code to do this using for loops (this was part of the instructions) and here's what I have so far:
int main ()
{
int row;
int col;
for (row = 1; row <= 5; row++) //rows
{
for (col = 1; col <= row; col++) //columns
{
printf_s("*");
}
printf_s("\n");
}
return 0;
}
The problem with my code is that I am not accounting for the required empty spaces to get the alignment correct. With the above current code here's what the output looks like:
*
**
***
****
*****
I'm hoping someone can point me in the right direction as to how to re-write my code to get the correct alignment and the correct number of leading spaces.
Thank you in advance.
You have a loop to print the asterisks but you are not printing out any spaces before that.
And the number of asterisks you print are not correct. For example your output has only 2 *s in second line when there should've been 3.
You could do
printf("%*s", NUM, "");
to print NUM spaces instead of using a separate loop.
Something like
for (row = 0; row < ROWS ; row++) //rows
{
printf("%*s", ROWS-1-row, "");
for (col = 0; col < row*2+1; col++) //columns
{
printf("*");
}
printf("\n");
}
The number of asterisks in each row is one more than double the row number if the row numbering starts from 0.
ROWS represent the number of rows to be printed.
The outer loop is for each row and the inner loop prints a number of asterisks in the row. YOu have omitted to preceded the row with a suitable number of spaces.
If you change the outer loop to the more conventional:
for (row = 0; row < 5; row++)
It makes the character count arithmetic simpler.
The inner loop should be preceded by another loop to print 4 - row spaces.
The asterisk loop needs to print row * 2 + 1 asterisks.
Try this:
r - count of rows
s - increment
i - rows index
j - columns index
start - starting count of *
#include <stdio.h>
int main(void)
{
int i,j,r=4,s,start;
start = 1;
s = start*2;
for (i=0;i<r*s;i+=s)
{
for (j=0;j<r*s/2-(i/2)-start;j++) printf(" ");
for (j=0;j<i+start;j++) printf("*");
printf("\n");
}
return 0;
}

replacing values in 2d arrays in c

I have searched through this site and found some very helpful information up to this point but I struggle in rewriting elements in arrays or finding info on this site on how to go about doing it. This is the part of the code I'm stuck on.
int game_board[3][3];
int row, col, i = 1;
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
game_board[row][col] = i++;
for (row = 0; row < 3; row++)
{
for (col = 0; col < 3; col++)
printf("%d\t", game_board[row][col]);
printf("\n");
}
int spot1 = game_board[0][0];
int spot2 = game_board[0][1];
int spot3 = game_board[0][2];
int spot4 = game_board[1][0];
int spot5 = game_board[1][1];
int spot6 = game_board[1][2];
int spot7 = game_board[2][0];
int spot8 = game_board[2][1];
int spot9 = game_board[2][2];
printf("enter the number of the square you want to place an x in\n");
scanf("%d", );//what goes here?
printf("%d", game_board[row][col]);
printf("\n");`
This gives me the numbers 1-9 but I dont know the next step to change the value in the array. Any direction would be appreciated.
int r, c;
printf("enter the row number of the square you want to place an x in\n");
scanf("%d", &r);
printf("enter the column number of the square you want to place an x in\n");
scanf("%d", &c);
if (r <= row && c <= column)
game_board[r][c] = 'x';
else
/* error */
printf("%d\n", game_board[r][c]);
Enter the position of the square? You just need to know the position of the square to put a x over that square.
#define CROSS -1
int i,j;
scanf("%d%d",&i,&j);
game_board[i][j]=CROSS;
So what should you do?
#define CROSS -1
int row1,col1;
printf("enter the position of the square you want to place an x in\n");
scanf("%d%d",&row1,&col1 );//what goes here?
// modify game_board[row1][col1] as you need. Assuming zero-indexing.
if(row1<3 && col1<3)
game_board[row1][col1]=CROSS;
Note: Instead of hardcoding the magic numbers here 3, just use them as a macro. In this case it will be...
#define MAXROW 3
#define MAXCOL 3
These will help you change your code easily later.
You put checks like this ..
if(row<MAXROW && col <MAXCOL)
// do something
The benefit is if you reconsider using a board size of 9x9 then you don't have to change all the 3's to 9's. Rather just change
#define MAXROW 9
#define MAXCOL 9

Resources