Updating my array board game - c

So I'm creating a game. It has a 5 by 5 board filled with characters a, b and c. I need to create a function where if the board detects the same letter next to each other, it disappears and the emptied cells are replaced with a new set of letters (a,b,c). So a bit like the candy crush game. I also need to display the number of moves that are made before the game ends. Here's where I am so far
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX 10
//creates board and fills in the letters randomly
int board()
{
char grid[MAX][MAX];
char letter[3] = {'a', 'b', 'c'};
int i,j,row,col;
printf("Please enter your grid size: ");
scanf("%d %d", &row, &col);
if(row < 10 && col < 10){
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
grid[i][j] = letter[rand()%3];
}
}
for(i=0; i < MAX; i++){
for(j=0; j < MAX; j++){
printf("%c ", grid[i][j]);
}
printf("\n");
}
}
else{
printf("Board is too big\n");
board();
}
return 0;
}
//the count doesn't quite do what I need it to
int moveCount()
{
char s;
printf("Press s to start: ");
scanf("%c", &s);
if(s == 's' || s == 'S'){
int count;
int max = 10;
for(count=1; count < max; count++)
if(count == max){
-printf("No more moves can be made");
}
else{
printf("Number of moves made: %d\n", count);
}
}
else{
printf("That is not s\n");
moveCount();
}
}
//Trying to check to make sure that n board is always atleast three cells
int inputCheck(){
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
moveCount();
}
}
int main()
{
board();
inputCheck();
}
What's the best way to implement a function that checks if neighbouring cells are the same and then deletes them. I would imagine doing something like if(myArray[0][0] == 'a' && myArray[0][1] == 'a'{do something}...but i don't know if that's the best way or how I would loop that. Also how to correctly implement a count that displays the move made?
I realise this code has a lot of flaws but I'm quite new so go easy please. Thanks for any help or a push in the right direction.

A serious bug here:
int n, m;
if(n == 3 || n > 3 && m == 1 || m > 1){
n and m are used uninitialized.
And you need to #include <stdlib.h> for rand()

In answer to your actual question, something like this would work. This is rather sloppy, but it's my 5 min answer. I assume grid is the actual board, which exists only in your board() function at the moment, so I simply added that as a parameter. AKA You're going to have to make it fit your actual game.
inline int clamp (int v, int min, int max) {
return (v < min) ? min: (v > max) ? max: v;
}
void place (char ltr, int x, int y, char grid[MAX][MAX])
{
grid[y][x] = ltr; // TODO: put bounds checking around x & y
for (int i = clamp(y - 1, 0, MAX); i <= clamp (y + 1, 0, MAX); i++) {
for (int j = clamp(x - 1, 0, MAX); j <= clamp(x + 1, 0, MAX); j++) {
if (i != y || j != x && grid[i][j] == ltr) {
grid[i][j] = '\0'; // TODO: replace null char with desired one.
}
}
}
}

The board function is set up just fine.
As the previous answers said parameters are the best way to check a value if you are going to check them within a different function, if you wish to check them within your function a simple if command would do the trick.
I would not pass an entire array as a parameter, instead I would use a pointer to that specific cell. Then, upon a person choosing a cell they are given a memory address that you could then compare the information stored inside that memory address with the other they are comparing.
Quick Pointer Lesson
- * is used to create a pointer. For instance, char *ch = array; would point to the memory address of the entire array. And then through more research you will be able to go to a specific memory address in a 2-D array, such as your board, see what is at that location and compare it to the contents contained in another memory address within your 2-D array.
Why would you want to to this?
Since this is not Java, we can about memory management in C and using an entire array as a parameter is the easy but more memory costly way of doing it. Plus, pointers are a fundamental element within most programming languages and knowing them well will make you a much better programmer.
Happy Travels!!
Also this will also be easier to go through your board to say, this person chose this address at array[3][2], there are only four memory address they would be choosing from at that point. Which ever way they choose to go, the memory address will be there and you will be able to compare both with minimal system usage and a quick response.

Related

Index Value goes to 5 million for nested for loop - C

I am programming a board game and I need to assign character values to a 2D array. To do this, I am using a nested for loop with the i as the row index and j as the column index. With a 4x4 dimension (n=4) The loop works fine until the second row. Using the debugger on codelite, I've noticed that the value of j does not increase from 0 to 1 like it should, but it increases to 5,560,570, disrupting the loop. I've also noticed that when using a dimension larger than 4, the program fails to display anything at all. Is this a memory error? I am stumped and have showed this to multiple other people as well.
int main(void){
int n;
char board[n][26];
printf("Enter the board dimension: ");
scanf("%d", &n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if((i == (n/2)-1 && j == (n/2)-1) || (i == (n/2) && j == (n/2))){
board[i][j] = 'W';
}
else if((i == (n/2) && j == (n/2)-1) || (i == (n/2)-1 && j == (n/2))){
board[i][j] = 'B';
}
else{
board[i][j] = 'U';
}
}
}
It appears that you are using n before you set it, in the declaration of board. Because this is undefined behavior, absolutely anything is permitted to happen; in this case, that is disrupting the value of other variables.
To fix this, you should probably wait until after initializing n in scanf to declare board, like so:
int main(void) {
int n;
printf("Enter the board dimension: ");
scanf("%d", &n);
char board[n][26];
...
}
As has been pointed out in the comments, this still will cause problems if n > 26, and can be wasteful for n != 26. Due to the way that arrays work in C, fixing that would probably require rethinking how the board is stored altogether.

Find symmetry in Array

Hi i need to check if the array is symmetry or not. i have a function that takes in a two-dimensional array of integer numbers M and the array sizes for rows and columns as parameters, and returns 1 if M is symmetric or 0 otherwise. I tried many times but the output will be either yes to non-symmetric array or no to symmetric array
Here is my code:
#include <stdio.h>
#define SIZE 10
#define INIT_VALUE -1
int symmetry2D(int M[][SIZE], int rowSize, int colSize);
int main()
{
int M[SIZE][SIZE], i, j, result = INIT_VALUE;
int rowSize, colSize;
printf("Enter the array size (rowSize, colSize): \n");
scanf("%d %d", &rowSize, &colSize);
printf("Enter the matrix (%dx%d): \n", rowSize, colSize);
for (i = 0; i < rowSize; i++)
for (j = 0; j < colSize; j++)
scanf("%d", &M[i][j]);
result = symmetry2D(M, rowSize, colSize);
if (result == 1)
printf("symmetry2D(): No\n");
else if (result == 0)
printf("symmetry2D(): Yes\n");
else
printf("Error\n");
return 0;
}
int symmetry2D(int M[][SIZE], int rowSize, int colSize)
{
int h, k, temp;
int result;
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
M[h][k] = M[k][h];
}
}
result = 0;
for (h = 0; h < rowSize && result; h++)
{
for (k = 0; k < colSize; k++)
{
//if it is not equal to its transpose
if (M[h][k] != M[h][k])
{
result = 1;
break;
}
}
}
if (result == 0)
{
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
return result = 0;
}
}
}
else
return result = 1;
}
Several issues:
By your definition, a matrix is symmetric if and only if it is equal to its transpose. That can be the case only for square matrices, yet you accommodate non-square matrices as well, for no apparent reason.
Your symmetry2D() function contains serious logical flaws:
It makes the input symmetric via the loop that performs M[h][k] = M[k][h]
Even if it did not do so, it would never find the input non-symmetric, because its test for that is if (M[h][k] != M[h][k]), which must always fail.
It's unclear what you think the if/else and loop nest at the end of symmetry2D() are achieving for you, but provided that rowSize and colSize are both greater than zero, the actual effect of the whole construct is the same as a simple return result;.
It looks like the idea might have been to create an array containing the transpose of the input, and then compare the input to that. That would have worked, despite being rather grotesquely inefficient, but you never in fact create that separate array for the transpose. If you're going to test without creating the transpose -- which you should -- then
Do not modify the input array (so remove the first loop nest altogether).
Get your indexing right for the symmetry comparisons: M[h][k] != M[k][h]
For best efficiency, avoid redundant and needless comparisons. For example, if you have already tested the M[1][2] == M[2][1] then you do not need to test whether M[2][1] == M[1][2]. And you never need to test elements on the main diagonal. You could achieve this efficiency pretty easily with a better choice of loop bounds.
Also, if indeed the symmetry2D() function is supposed to avoid modifying the input array, consider declaring the element type for its first argument to be const int instead of plain int (but do not modify the type of the corresponding variable in main()). If you had written it that way in the first place then the compiler would have noticed the function's logically erroneous attempt to modify the array elements, and rejected the code.

issues randomly populating a 2d array of structure type in C

I'm trying to populate a 20x20 matrix where each entry is of structure type. My goal is to randomly assign 100 ants and 5 doodlebugs on this 2D array. Even though I got it to work, I don't always get the amount of ants or doodlebugs I need in the matrix. I added a counting function to always verify how many of them I have each time I run the program, but I'm always slightly short. I'm trying to force those number to work (100 ants and 5 doodlebugs) by using a do/while loop in my populating function, although it's not working. Can someone spot where is my logic is failing me?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define N 20
struct cellState {
int emptyInt;
int antInt;
int dBInt;
char emptyChar;
char antChar;
char dBChar;
};
struct cellState gridState[N][N];
// function to populate world
void pop_mtx(struct cellState gridState[N][N], int antsNeeded, int dBNeeded) {
int i, j;
do {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if ((gridState[i][j].emptyInt = rand() % 3) == 0) {
gridState[i][j].emptyChar = '.';
} else
if (((gridState[i][j].antInt = rand() % 3 == 1) && antsNeeded != 0)) {
gridState[i][j].antChar = 'a';
antsNeeded--;
} else
if (((gridState[i][j].dBInt = rand() % 3 == 2) && dBNeeded != 0)) {
gridState[i][j].dBChar = 'D';
dBNeeded--;
}
}
}
} while (dBNeeded != 0 && antsNeeded != 0);
}
//function to display current state of the world
void display_mtx(struct cellState gridState[N][N]) {
int i, j;
char charToDisplay;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
charToDisplay = 'a';
else
if (gridState[i][j].dBChar == 'D')
charToDisplay = 'D';
else
charToDisplay = '.';
printf("%c ", charToDisplay);
}
printf("\n");
}
printf("\n\n");
}
//function to count ants and doodlebugs
void count_mtx(struct cellState gridState[N][N]) {
int i, j, antCount = 0, dBcount = 0;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
antCount++;
else
if (gridState[i][j].dBChar == 'D')
dBcount++;
}
}
printf("ant count: %i, doodlebug count: %i\n", antCount, dBcount);
}
int main(void) {
srand((unsigned int)time(NULL));
//populate grid state with 5 doodlebugs and 100 ants
int antsNeeded = 100, dBNeeded = 5;
pop_mtx(gridState, antsNeeded, dBNeeded);
count_mtx(gridState);
display_mtx(gridState);
}
There are several problems. First, each time you call rand() you obtain a different value, so it is possible that none of the three tests pass. You should call rand () once and save the value.
Second, there is nothing that guarantees that over NxN calls of rand() you will get as many ones and twos as you need. The outer loop is therefore necessary. You should also preserve already populated squares from one iteration to the next because it might take a long time before you reach an iteration that produces enough ones and twos.
Third, this method is biased toward the squares at the beginning of the grid. It will not give you one out of all possible distributions of 100 ants and 5 doodlebugs over 400 squares with equal probability.
Here is the proper way to do it:
Consider the grid as a uni-dimensional array. First fill it, in order, with 100 ants, 5 doodlebugs, and empty spaces. Then perform a random shuffle of the array.
This procedure will return each possible distribution of the ants and doodlebugs on the grid with equal probability.

How can I reduce the runtime?

Here is a link to the problem I'm trying to solve: http://acm.timus.ru/problem.aspx?space=1&num=1086
Here is my approach:
#include <stdio.h>
#include <math.h>
int main()
{
int n, i, m, p;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &m);
p = find_prime(m);
printf("%d\n", p);
}
return 0;
}
int find_prime(int a)
{
int i, p = 1, t, prime[15000], j;
prime[0] = 2;
for(i = 0; i < a; )
{
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
t = 0;
for(j = 0; prime[j] <= sqrt(p); j++)
{
if(p%prime[j] == 0 && p != 2)
{
t = 1;
break;
}
}
if(t != 1)
{
i++;
prime[i] = p;
}
}
return p;
}
I know the algorithm is fine and it produces the correct answer. But I always get "Time Limit Exceeded". I can't get the runtime download to 2 seconds. It's always equal to 2.031 seconds. I have tried few other approaches, for example, I iterated through all the numbers until I found the mth prime number, I tried skipping the even integers greater than 2 but I still get 2.031 seconds.
What should I do?
Your buffer for prime numbers doesn't need to be a local variable that's recalculated every time.
You can try to memoize by storing the buffer in the global scope and using a global counter to keep track of how many primes you have already calculated until now and which number was the maximum number requested.
If the next number that's requested from you is smaller than the previous maximum, you should fall back to the corresponding pre-calculated number. If the next number is larger than the previous maximum, make it the new maximum - and also try to start calculating from where you last left off.
Remove
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
and replace it with
p++
as I understand it,
the problem is to find the next prime greater that the sum of all the prior input numbers.
That means there are certain expectations.
1) the sum of the prior input numbers is available in find_prime().
2) for simplification, the last found prime number is available in find_prime().
Neither of these expectations are implemented.
Then there is that 60 thousand byte array on the stack in find_prime().
Suggest moving that to a file global position and including a 'static' modifier.
move the prior sum of inputs to a file global location, so it is always available.
for overall speed,
calculate all the primes in the array as a first thing, thereby filling the array with prime values. then
1) add new input to sum,
2) index into array using sum.
3) return value found in array.

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Resources