C ignoring incrementation - c++

I tried this but my compiler(Visual Studio 2013) keeps messing up things.
I have a 9 by 9 matrix indexed from 1. It is 0 at the beginig. And starting from element 1:1 I start incrementing the value in the matrix or incrementing x,y, basically moving to the next matrix element.
However, the program ignores my incrementation and the fact that x,y are initially set to 1.
Also it ignores a function call.
Code is commented below.
I am sure this is the source I am compiling!
Restarted laptop and Visual Studio but still doesn't work.
Opened new project, same thing.
Thanks in advance.
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}

You feel that the increment is ignored because the checkSquare function is buggy. It never returned 1 and hence the increment function was never called.

What happens is that you're incrementing the position marked by x and y, that's position [1][1]. Until it reaches 10 nothing interesting happens, you can actually see the top left corner of the matrix increasign to 10, but then the condition to decrement becomes true and you decrement.
See for yourself (prints),
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
printf( "Enter to continue\n" );
getchar();
}
It turns Y = 9, X = 0 and the [1][1] position becomes 0, so you see only zeros because you're not printing the zero indexes.
This process repeats until Y = 1 and X = 0, you increase the position until 10 so that the decrement works again.
When Y = 1, X = 0 and position [0][1] is 10, the decrement call will do x--. Since X is an unsigned int, it will underflow and become 4.2 billion something, which is greater than 10 and the loop ends.
What are you trying to achieve here?
Edit: Something even more amazing happens when you make x and y ints instead of unsigned ints.
Instead of x underflowing it will become -1. Matrix[-1][9]++ strangely increased x by 1 when I ran the code, so x went back to 0. Which means the program loops forever at this point.
The increment function was never called.

It shows matrix and increment when tested online, here are results
1) for C compiler
http://ideone.com/KRLO8w
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}
2) for c++ compiler C++ 4.9.2 (changed return type of main to int)
http://ideone.com/Ey5nG1
In your image starting value of 0, 3 is due to buffer limit of command prompt. As the program never ends, so it terminates abruptly and latest few bytes are stored in buffer and is only shown that much. To see complete output redirect it to a file and open it.

Your output is a bit confusing since the output of the line
printf("%u, %u", x, y);
runs into the output of
print_Matrix();
By adding a newline to the output of the first line, i.e. by using
printf("%u, %u\n", x, y);
you will notice that at some point x gets decremented to 0 and never gets incremented again. Since you never print Matrix[0][y], you never see the non-zero values.
In addition to the change to above printf, if you change print_Matrix to:
void print_Matrix(){
unsigned int i, j;
for (i = 0; i <= 9; i++){
// ^^^ Use 0 instead of 1
for (j = 0; j <= 9; j++)
// ^^^ Use 0 instead of 1
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
you will see the non-zero values.
See working code at http://ideone.com/HlQ4xp.

Related

Contagion program, Matrices and Syntax issue

I am trying to do the following program:
Write a function onstepcontagion : bool array array -> bool array array = that given a rectangular bool matrix, where true represents an infected square and false represent non-infected square it calculates the next step of infection. Infected squares remain infected indefinitely, non-infected squares become infected if the they are vertically/horizontally adjacent to at least two other infected squares
My code so far:
let printmat matrix =
let n = Array.length matrix in
let n1 = Array.length matrix.(0) in
for i = 0 to n - 1 do
for j = 0 to n1 - 1 do
if matrix.(i).(j) == true then print_string"1"
else print_string"0";
done;
print_string "\n";
done;;
let onstepcontagion matrix =
let n = Array.length matrix in
let n1 = Array.length matrix.(0) in
for i = 0 to n - 1 do
for j = 0 to n1 - 1 do
if (j < n1-1) then
let right = if matrix.(i).(j+1) == true then 1 else 0 in
if (j > 0) then
let left = if matrix.(i).(j-1) == true then 1 else 0 in
if (i < n-1) then
let up = if matrix.(i-1).(j) == true then 1 else 0 in
if (i > 0) then
let down = if matrix.(i+1).(j) == true then 1 else 0 in
let sum = right + left + up + down in
if sum > 1 then matrix.(i).(j) = true
done;
print_string "\n";
done;;
printmat matrix
**Error: Error: This expression has type bool but an expression was expected of type
unit
Characters 1618-1639:
if sum > 1 then matrix.(i).(j) = true **
I have made a C version of the program I want to implement:
#include <stdio.h>
#include <stdlib.h>
void print_mat (int n, int m, int arr[n][m])
{
int i,j;
for (i = 0; i < n; i++){
for (j = 0; j < m; j++)
printf("%d ",arr[i][j]);
printf("\n");
}
printf("\n\n");
}
int main()
{
int n, m, i, j, tmp, changes = 1;
printf("input Mat len\n");
scanf("%d%d",&n,&m);
int arr[n][m];
int cpy[n][m];
for (i = 0; i < n; i++)
for (j = 0; j < m; j++){
scanf("%d",&tmp);
if (tmp == 0)
arr[i][j] = tmp;
else
arr[i][j] = 1;
}
while (changes){
changes = 0;
for (i = 0; i < n; i++){
for (j = 0; j < m; j++)
{
tmp = 0;
if (arr[i][j] != 1){
if (j < m-1)
if (arr[i][j+1] == 1)
tmp++;
if (j > 0)
if (arr[i][j-1] == 1)
tmp++;
if (i < n-1)
if (arr[i+1][j] == 1)
tmp++;
if (i > 0)
if (arr[i-1][j] == 1)
tmp++;
if (tmp > 1){
cpy[i][j] = 1;
changes = 1;
}
}
}
}
if (changes == 1){
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
if (arr[i][j] == 1 || cpy[i][j] == 1)
arr[i][j] = 1;
printf("\n");
print_mat(n,m, arr);
}
}
return 0;
}
= is the structural equality operator. To set an array element you need to use <-.
Also, you should almost never use == because it tests for physical equality, i.e. that references point to the same address in memory. For comparing bools it doesn't strictly matter, because they're not pointers, but you should get into the habit of using = instead to avoid surprises in the future.

Null characters randomly added to string C++

I have written a simple battleship game in C++. After several iterations of the game, one of the strings in a "Player" object is changed. This change is several null characters are added to the end of the string. Otherwise the rest of the object is untouched. For example if the player type is "cpu", the player type switches to "cpu\0\0\0\0\0\0\0\0". I believe the line of code causing the problem is:
currPlayer->getStrategy().getNextAttack(nextPlayer->getBoard(1));
Here is the code for getNextAttack():
int Strategy::getNextAttack(Board enemyBoard) {
//clear prob board
for(int i = 0; i < 100; i++) {
probBoard[i] = 0;
}
//reset largest ship
largestShip = 0;
//assign largest ship
for(int i = 0; i < 100; i++) {
Ship currShip = enemyBoard.getShipByCoord(i);
if(!currShip.isSunk()) { //if ship is still afloat
if(currShip.getSize() > largestShip) { largestShip = currShip.getSize(); } //reassign largest ship on board
}
}
//assign base prob
std::vector<int> allPossible;
//for all horiz coords
for(int i = 0; i < 10; i++) {
for(int j = 0; j < (10 - largestShip +1); j++) {
for(int k = 0; k < (largestShip); k++) {
if(!enemyBoard.beenHit((i*10) + j + k) || (enemyBoard.beenHit((i*10) + j + k) && !enemyBoard.getShipByCoord((i*10) + j + k).isSunk())) { //if not hit or if hit but contains a ship that is not sunk
allPossible.push_back((i*10) + j + k);
}
else {
for(int m = 0; m < k; m++) {
allPossible.pop_back(); //should delete last element
}
break;
}
}
//for all vert coords
for(int z = 0; z < (largestShip); z++) {
if(!enemyBoard.beenHit(((j+z)*10) + i)) {
allPossible.push_back(((j+z)*10) + i);
}
else {
for(int m = 0; m < z; m++) {
allPossible.pop_back(); //should delete last element
}
break;
}
}
}
}
for(int p = 0; p < allPossible.size(); p++) {
probBoard[allPossible[p]] += 1;
}
//add improvements based on hits
for(int i = 0; i < 10; i++) {
for(int k = 0; k < 10; k++) {
int currCoord = (i*10) + k;
int leftCoord = (i*10) + k-1;
int rightCoord = (i*10) + k+1;
int upCoord = ((i-1)*10) + k;
int downCoord = ((i+1)*10) + k;
if(enemyBoard.beenHit(currCoord) && (enemyBoard.getShipByCoord(currCoord).getName() != "") && !enemyBoard.getShipByCoord(currCoord).isSunk()) { //currCoord is a coordinate that has been hit, contains a ship and is not sunk
if((enemyBoard.beenHit(leftCoord) || enemyBoard.beenHit(rightCoord)) && (enemyBoard.getShipByCoord(leftCoord) == enemyBoard.getShipByCoord(currCoord) || enemyBoard.getShipByCoord(rightCoord) == enemyBoard.getShipByCoord(currCoord))) { //if space to left or right is hit and the same ship
//increment only the left and right
if(!enemyBoard.getShipByCoord(currCoord).isSunk()) { //ship cannot be sunk as well
probBoard[leftCoord] += 25;
probBoard[rightCoord] += 25;
}
}
else if((enemyBoard.beenHit(upCoord) || enemyBoard.beenHit(downCoord)) && (enemyBoard.getShipByCoord(upCoord) == enemyBoard.getShipByCoord(currCoord) || enemyBoard.getShipByCoord(downCoord) == enemyBoard.getShipByCoord(currCoord))) { //if space on top or bottom is hit and the same ship and not sunk
//increment only the top and bottom
if(!enemyBoard.getShipByCoord(currCoord).isSunk()) { //ship cannot be sunk as well
probBoard[upCoord] += 25;
probBoard[downCoord] += 25;
}
}
//if no direct spaces in any direction to hit coord, increment top, bot, left, and right equally
else {
probBoard[upCoord] += 20;
probBoard[downCoord] += 20;
probBoard[leftCoord] += 20;
probBoard[rightCoord] += 20;
}
}
}
}
//marks odds at 0 if already fired upon
for(int n = 0; n < 100; n++) {
if(enemyBoard.beenHit(n)) {
probBoard[n] = 0;
}
}
//find next best attack coord based on prob board
int highestValue = 0;
std::vector<int> highestSpaces;
for(int j = 0; j < 100; j++) {
if(probBoard[j] > highestValue) { highestValue = probBoard[j]; }
}
for(int r = 0; r < 100; r++) {
if(probBoard[r] == highestValue) {
highestSpaces.push_back(r);
}
}
srand(static_cast<unsigned int>(time(NULL)));
int randNum = rand() % highestSpaces.size();
return highestSpaces[randNum];
}
Thank you for reading and any help!
This looks like it will go out of the array bounds at the edges when the row or column is 0 or 9:
probBoard[upCoord] += 20;
probBoard[downCoord] += 20;
probBoard[leftCoord] += 20;
probBoard[rightCoord] += 20;

Puzzle related to sorting a 2-D array in ascending order

A randomly generated 4x4 2-D array is given to the user, of which one element is definitely 0. Considering 0 to be an empty location, the user will have to exchange the remaining 15 elements with 0 repeatedly until they get the array in ascending order, with 0 as the last element.
At this point, they're allowed to exchange any element with 0.
But how do I modify this code to ensure that are only able to exchange those elements with 0 that are adjacent to it (either above, below or beside it) ?
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
int check_asc(int a[][4])
{
int i, j, previous = a[0][0];
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
if(i == 3 && j == 3)
{
if (a[i][j] == 0)
return 1;
}
else if (a[i][j] < previous)
{
return 0;
}
previous = a[i][j];
}
}
return 1;
}
void swap(int a[][4], int &xpos, int &ypos)
{
int arr, temp;
cout << "\n\nEnter number to be swapped with 0: ";
cin >> arr;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (a[i][j] == arr)
{
temp = a[xpos][ypos];
a[xpos][ypos] = a[i][j];
a[i][j] = temp;
xpos = i;
ypos = j;
return;
}
}
}
}
int check_rep(int a[][4], int assign)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (assign == a[i][j])
return 0;
}
}
return 1;
}
void main()
{
int a[4][4], assign, xpos = 0, ypos = 0, asc_result, rep_result;
srand((unsigned)time(NULL));
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
{
if (i == 0 && j == 0)
a[i][j] = 0;
else
{
do {
assign = rand() % 50;
rep_result = check_rep(a, assign);
} while (rep_result == 0);
a[i][j] = assign;
}
}
cout << "\n\nArrange the 4x4 matrix into ascending order. (Consider 0 as a blank space)" << endl;
for (int i = 0; i < 4; i++)
{
cout << endl;
for (int j = 0; j < 4; j++)
cout << a[i][j] << '\t';
}
do {
swap(a, xpos, ypos);
system("cls");
for (int i = 0; i < 4; i++)
{
cout << endl;
for (int j = 0; j < 4; j++)
cout << a[i][j] << '\t';
}
asc_result = check_asc(a);
} while (asc_result == 0);
cout << "\n\tYou win"<<endl;
system("pause");
}
Simple, just extend your swap function with a piece of code that will check whether the location of the element to be swapped is adjacent to the location of 0:
void swap(int a[][4], int &xpos, int &ypos)
{
...
if (a[i][j] == arr &&
((i == xpos && (j == ypos - 1 || j == ypos + 1)) ||
(j == ypos && (i == xpos - 1 || i == xpos + 1))))
{
temp = a[xpos][ypos];
a[xpos][ypos] = a[i][j];
a[i][j] = temp;
xpos = i;
ypos = j;
return;
}
An improvement would be to separate the check condition and inform the user in case when the element is not adjacent to 0.
Rough Algorithm
1) create a function find location, it will return a structure Point that has x, y integer fields, it will find the x, y location of any piece based on the pieces value, i.e. lets say 0 is entered, if it is located in the top left corner (0,0), a point (0, 0) will be returned
2) create a function that takes in 2 points, the location of the '0' and the location of the piece we wish to swap lets call it S, if S.x = 0.x and 0.y - 1 = S.y or S.y - 0.y + 1 then you know that said piece is directly above or below the 0, now of course you have ot add a few conditions for boundaries so as we dont check outside the grid. Have this function return an int 1 if the piece S is located above/below/beside, 0 if not.
3) if 1 is returned your allowed to do the flip, if 0 is returned find another piece

C++ .exe "has stopped working" after calling function twice

So I have a program in C++ that calls a function three times, I'm making this project using Code::Blocks and when I run the release version of the .exe it tells me that the program has stopped working and that I have to close the program. I tried calling the function just once and it works, no matter which call I leave. So it looks like it crashes only when it's called twice, regardless of which variables I pass. Any idea of why this happens?
Here's the function I call:
int interval(int h, int i, std::vector< std::vector<int> >& Array, int arr[], int interv)
{
int k = i + 1;
int P[20];
int number;
bool a;
int b;
int N;
int maxres;
int result[90];
for (h = 0; h < 20; h++)
{
for (N = 1; N <= 90; N += 1)
{
result[N] = 0;
for (i = 1; i <= (k - interv); i++)
{
number = Array[i - 1][h] - N;
if (number <= 0)
number += 90;
for (b = 0; b < 20; b++)
{
a = false;
if ((number == Array[i][b]) || ( (interv == 1) && (number == Array[i + 1][b]) ) || ( (interv == 2) && (number == Array[i + 2][b]) ) )
{
a = true;
result[N]++;
break;
}
}
if (!a)
break;
}
if (N == 1)
maxres = N;
else
{
if (result[N] >= result[maxres])
maxres = N;
}
}
P[h] = maxres;
}
for (h = 0; h < 20; h++)
{
arr[h] = Array[0][h] + P[h];
if ( arr[h] > 90 )
arr[h] -= 90;
}
return 0;
}
And here are the calls:
int c[20];
int e[20];
int d[20];
interval(h, i, Array, c, 0);
interval(h, i, Array, e, 1);
interval(h, i, Array, d, 2);
One problem is out-of-bounds accesses to result:
int result[90];
for (h = 0; h < 20; h++)
{
for (N = 1; N <= 90; N += 1) <--- Here!
{
result[N] = 0;
The allowed values for N are 0 to 89 (like in for (N = 0; N != 90; ++N))
There might be a similar problem here
for (i = 1; i <= (k - interv); i++)
but I can't tell for sure.

Sudoku solving matrix, while statement gives an infinite loop

This code should produce a solved sudoku matrix, however the while statement puts it in an infinite loop. Removing the while statement gives me a matrix with some values still 99 or 0. And i can't generate 9 random numbers uniquely one by one.
IF YOU WANT TO RUN AND CHECK THE CODE, REMOVE THE WHILE STATEMENT.
int a[9][9];
int b[9][9];
int inputvalue(int x, int y, int value) //checks horizontally, vertically and 3*3matrix for conflicts
{
int i, j;
for (i = 0; i < 9; i++)
{
if (value == a[x][i] || value == a[i][y])
return 0;
}
for (i = (x / 3) * 3; i <= ((x / 3) * 3) + 2; i++)
{
for (j = (y / 3) * 3; j <= ((y / 3) * 3) + 2; j++)
if (b[i][j] == value)
return 0;
}
return value;
}
int main()
{
int i, j, k;
unsigned int s;
cout << "sudoku\n";
time_t t;
s = (unsigned) time(&t);
srand(s);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
a[i][j] = 99;
}
for (i = 0; i < 9; i++)
{
for (j = 1; j <= 9; j++)//j is basically the value being given to cells in the matrix while k assigns the column no.
while(a[i][k]==99||a[i][k]==0)
{
k = rand() % 9;
a[i][k] = inputvalue(i, k, j);
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
getch();
}
You are using assignment =, instead of equality == here:
while(a[i][k]=99||a[i][k]=0)
^ ^
this should be:
while(a[i][k]==99||a[i][k]==0)
a[i][k]=99 will always evaluate to true since 99 is non-zero, although your original code does not compile for me under gcc as it is, so I suspect the code you are running either has some parenthesizes or is slightly different.
Also using k in the while loop before it is initialized is undefined behavior and it is unclear that your termination logic makes sense for a k that is constantly changing for each loop iteration.
Another source of the infinite loop is inputvalue which seems to get stuck returning 0 in some instances, so you need to tweak that a bit to prevent infinite loops.
Also, srand(time(NULL)); is a more common way to initialize the pseudo-random number generator