'C' Program: multidimensional array issue - c++

Please help me figure this out, I have tested it and tested it and re-read and re-wrote for the past 11 hours and I give up. I found a working code that someone else wrote, but it still doesn't explain to me why his works and mine doesn't because the problem that I am having works on his but not on mine
Got it people, code edited for anyone who has had a similiar problem...
The original code that I had is here http://pastebin.com/h7fXHKzf
the problem I was having was that it kept hanging up on the if(board[x][y - 1] == '.') checks.
Spoke too soon....The program will sometimes crash...it's rare but has crashed 3x in a row before...most of the time when I run it everything works.
// Chapter 8 Programming Project #9
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 10
#define PATH_SIZE ((int) (sizeof(brd_path)))
#define ROW_SIZE ((int) (sizeof(board) / sizeof(board[0])))
int main(void)
{
char board[SIZE][SIZE] = {};
char brd_path[25] = {'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z'};
// 0 = Up, 1 = Down, 2 = Left, 3 = Right
bool path_dir_chk[4] = {false};
bool blocked = false;
unsigned short i, j, x = 0, y = 0;
// Generate a random number
srand((unsigned) time(NULL));
int dir = rand() % 4;
// Set all positions of board to '.'
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
x = 0;
y = 0;
board[0][0] = 'A';
// Generate the path
while (blocked != true && i != PATH_SIZE) {
for (i = 0; i < PATH_SIZE;) {
// Reset path_dir_chk values if empty
for (j = 0; j < 4; j++) {
if (board[x][y - 1] == '.')
path_dir_chk[0] = false;
if (board[x][y + 1] == '.')
path_dir_chk[1] = false;
if (board[x - 1][y] == '.')
path_dir_chk[2] = false;
if (board[x + 1][y] == '.')
path_dir_chk[3] = false;
}
// Check the direction and replace that char
switch (dir) {
case 0: if ((y - 1) >= 0 && board[x][y - 1] == '.') {
board[x][--y] = brd_path[i];
path_dir_chk[0] = true;
printf("I is now: %d\n", ++i);
} break;
case 1: if ((y + 1) >= 0 && board[x][y + 1] == '.') {
board[x][++y] = brd_path[i];
path_dir_chk[1] = true;
printf("I is now: %d\n", ++i);
} break;
case 2: if ((x - 1) >= 0 && board[x - 1][y] == '.') {
board[--x][y] = brd_path[i];
path_dir_chk[2] = true;
printf("I is now: %d\n", ++i);
} break;
case 3: if ((x + 1) >= 0 && board[x + 1][y] == '.') {
board[++x][y] = brd_path[i];
path_dir_chk[3] = true;
printf("I is now: %d\n", ++i);
} break;
}
// if all path's are true exit
if (path_dir_chk[0] == true &&
path_dir_chk[1] == true &&
path_dir_chk[2] == true &&
path_dir_chk[3] == true)
blocked = true;
// Reset the random direction
dir = rand() % 4;
}
}
// Print the board
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
printf("%c ", board[x][y]);
printf("\n");
}
return 0;
}
OK I have made changes to reflect what I have so far, no it is printing 'I is now:' numbers 1 - 25 and then it starts over but it stops on 12 the second time around and freezes into some kind of loop
Below is the working code I found online, you can compare the two and see the similarity's but the lines of code on his that are exactly like mine do not work on mine.....
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROWS 10
#define COLS 10
int main (void)
{
int i, j, k, direction;
char board[ROWS][COLS];
const char letters[] = {'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z'};
srand ((unsigned) time(NULL));
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
board[i][j] = '.';
i = 0;
j = 0;
k = 1;
//set array[0][0] to first element
board[i][j] = letters[0];
while (k < 26) {
direction = rand() % 4;
if (board[i][j] == '.')
board[i][j] = letters[k++];
if ((board[i][j + 1] != '.' || j == ROWS - 1 )&&
(board[i + 1][j] != '.' || i == COLS -1) &&
(board[i - 1][j] != '.' || i == 0) &&
(board[i][j - 1] != '.' || j == 0))
break;
switch (direction) {
case 0: if (j < ROWS - 1 && board[i][j + 1] == '.'){ //move right
j++;
break; }
case 1: if (i < COLS -1 && board[i + 1][j] == '.') { //move down
i++;
break; }
case 2: if (i > 0 && board[i - 1][j] == '.'){ //move up
i--;
break; }
case 3: if (j > 0 && board[i][j - 1] == '.') { //move left
j--;
break; }
}
}
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++)
printf ("%4c", board[i][j]);
printf ("\n");
}
return 0;
}

You aren't setting x and y back to 0 after this code
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
Thus x and y will start at 10. Also you aren't range checking x and y, which means that x and y might wander off the board.
This code
if ((board[x][y - 1] != '.' || y - 1 < 0) &&
(board[x][y + 1] != '.' || y + 1 > ROW_SIZE) &&
(board[x - 1][y] != '.' || x - 1 < 0) &&
(board[x + 1][y] != '.' || x + 1 > ROW_SIZE))
should be this
if ((y - 1 < 0 || board[x][y - 1] != '.') &&
(y + 1 >= ROW_SIZE || board[x][y + 1] != '.') &&
(x - 1 < 0 || board[x - 1][y] != '.') &&
(x + 1 >= ROW_SIZE || board[x + 1][y] != '.'))
There are two subtle differences.
First y+1 and x+1 are not allowed to be equal to ROW_SIZE, since ROW_SIZE is 10, but the valid array indices are 0 to 9.
Second, order is important. When evaluating a logical OR, the left side is evaluated first, and if it's true, then the right side is not evaluated. This is important, since on some machines, even reading outside of the array bounds will cause a crash.

for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
After the initialization you are not resetting the value of x and y. While value of X= ROW_SIZE, you are trying to access board[x + 1][y] and board[x][y + 1].
x = 0;
y = 0;

Thanks user3386109 your input was invaluable as was the rest of y'alls help I appreciate it, the working code is below :)
// Chapter 8 Programming Project #9
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 10
#define PATH_SIZE 25
#define ROW_SIZE ((int) (sizeof(board) / sizeof(board[0])))
int main(void)
{
char board[SIZE][SIZE];
// 0 = Up, 1 = Down, 2 = Left, 3 = Right
unsigned short i = 0, x, y;
// Generate a random number
srand((unsigned) time(NULL));
int dir = rand() % 4;
// Set all positions of board to '.'
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
board[x][y] = '.';
}
x = 0;
y = 0;
board[0][0] = 'A';
// Generate the path
for (i = 0; i < PATH_SIZE;) {
// Check that the last character has not been cornered
if ((board[x][y - 1] != '.' || y - 1 < 0) &&
(board[x][y + 1] != '.' || y + 1 > ROW_SIZE) &&
(board[x - 1][y] != '.' || x - 1 < 0) &&
(board[x + 1][y] != '.' || x + 1 > ROW_SIZE))
break;
// Check the direction and replace that char
switch (dir) {
case 0: if ((y - 1) >= 0
&& board[x][y - 1] == '.') {
board[x][--y] = i + 'B';
++i;
} break;
case 1: if ((y + 1) < ROW_SIZE
&& board[x][y + 1] == '.') {
board[x][++y] = i + 'B';
++i;
} break;
case 2: if ((x - 1) >= 0
&& board[x - 1][y] == '.') {
board[--x][y] = i + 'B';
++i;
} break;
case 3: if ((x + 1) < ROW_SIZE
&& board[x + 1][y] == '.') {
board[++x][y] = i + 'B';
++i;
} break;
default: if (board[x][y] == '.')
board[x][y] = i + 'B';
break;
}
// Reset the random directions
dir = rand() % 4;
}
// Print the board
for (x = 0; x < ROW_SIZE; x++) {
for (y = 0; y < ROW_SIZE; y++)
printf("%4c ", board[x][y]);
printf("\n");
}
return 0;
}

Related

How to check all neighbors of a character in a string vector

Game of conway. Trying to access all neighbors of a each "cell" that i read in from a file.
If a cell is alive, it stays alive for the next generation if it has exactly two or three neighbors.
If a cell is dead, then it becomes alive for the next generation if it has exactly three neighbors.
E has exactly 8 neighbors in both situations.
Im having issues with the top line of the next generation:
......... F......DE
...ABC... I......GH
...DEF... .........
...GHI... .........
......... C......AB
file is read into currentgen, a string vector
nextgen is a copy of currentgen, that I change as needed
//find neighbors
for (size_t i=0; i < currentgen.size(); i++){
for(size_t j = 0; j < currentgen[0].length(); j++){
//neighbor count
int neighborcount = 0;
//south neighbor
if(currentgen[(i+1) % currentgen.size()][j] == 'O'){
neighborcount++;
}
//north
if(currentgen[(i-1) % currentgen.size()][j] == 'O'){
neighborcount++;
}
//left
if(currentgen[i][(j-1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//right
if(currentgen[i][(j+1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//south right
if(currentgen[(i+1) % currentgen.size()]
[(j+1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//south left
if(currentgen[(i+1) % currentgen.size()]
[(j-1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//north right
if(currentgen[(i-1) % currentgen.size()]
[(j+1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//north left
if(currentgen[(i-1) % currentgen.size()]
[(j-1) % currentgen[i].length()] == 'O'){
neighborcount++;
}
//if cell is alive
if(currentgen[i][j] == 'O'){
nextgen[i][j] = '.';
if(neighborcount == 2){
nextgen[i][j]= 'O';
}
if(neighborcount == 3){
nextgen[i][j]= 'O';
}
}
//if cell is dead
if(currentgen[i][j] == '.'){
if(neighborcount == 3){
nextgen[i][j]= 'O';
}
}
The issue with your code is that you're relying on % having the usual meaning of remainder. However, in c++, doing % on negative values will give you a remainder towards 0.
So the following expression is:
-1 % 5 // -1 not 4
To do the remainder correctly, you can add the value you're using as the modulus, and then you're guaranteed to have a positive number, and the calculation will work:
(-1 + 5) % 5 // 4 yay!!
Also, all those if conditions to check the neighbors is very verbose. You could simplify that to:
for (size_t i=0; i < currentgen.size(); i++) {
for(size_t j = 0; j < currentgen[0].length(); j++) {
//neighbor count
int neighborcount = 0;
for (int i_offset : {-1, 0, 1})
for (int j_offset : {-1, 0, 1})
if (i && j && currentgen[(i + i_offset + currentgen.size())
% currentgen.size()]
[(j + j_offset + currentgen[i].size())
% currentgen[i].size()] == 'O')
neighborcount++;
//if cell is alive
// ... etc
Here is a small piece of advice on how to avoid hard-coding the coordinates (south, north, left, right, etc.). You can use 2 arrays, namely dx and dy, which indicates the delta of x and y coordinates.
For example, start with a north neighbour and go clockwise (see the picture attached):
dx and dy description
int dx[] = {0, 1, 1, 1, 0, -1, -1, -1};
int dy[] = {-1, -1, 0, 1, 1, 1, 0, -1};
Now, in order to cycle through the neighbours of a cell (x, y), just add the corresponding dx and dy entries.
As pointed out by #cigien, you should not compute a remainder operator for negative values. The easiest thing to do is to add n and take modulo n, where n is a size of the field. It will save you from having negative value before modulo operation while preserving the same result, since n % n = 0.
Here is how you can cycle through the neighbours of (x, y):
int x;
int y;
// fill x and y
for(int d = 0; d < 8; ++d)
{
int nx = x + dx[d];
int ny = y + dy[d];
nx = (nx + n) % n;
ny = (ny + n) % n;
// horray!
}
Something like this:
#include <iostream>
#include <utility>
int main() {
char field[5][5]{
'.', '.', '.', '.', '.',
'.', '.', 'O', '.', '.',
'.', 'O', '.', 'O', '.',
'.', '.', 'O', '.', '.',
'.', '.', '.', '.', '.'
};
int posX = 2, posY = 2, count = 0;
for (int y = -1; y <= 1; ++y)
for (int x = -1; x <= 1; ++x) {
const char symbol = field[(posY + y + 5) % 5][(posX + x + 5) % 5];
count += static_cast<int>((y != 0 || x != 0) && symbol == 'O');
}
std::cout << count << '\n';
}
or
const char symbol = field[(posY + y + HEIGHT) & (HEIGHT - 1)][(posX + x + WIDTH) & (WIDTH - 1)];
if your field size is a power of 2 in x/y direction

How can I fix the "Invalid memory reference" error in my code?

I'm working on a maze-solver robot for my arduino project. I want my robot to memorize the maze and then find the shortest path. I keep having a problem when the char array's lenght is 3.
The problem appears when the lenght is <= 3, so I tried diffrent stuff to make a particular case out of that, that's why the if (strlen(a) > 3) is there.
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
char a[] = "LLLBLLLRBLLBSRSRS";
char b[200];
while(strcmp(a, b) != 0) {
strcpy(b, a); //sa verific daca se schimba sirul, daca nu inseamna ca a ajuns la minim
for(int i = 0; i < strlen(a) - 2; i++)
{
if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'R') //if urile astea cauta combinatii de cate 3 miscari sa optimizezi drumul
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'S')
{
a[i] = 'R';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'L' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'S';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'S' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'R';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'S' && a[i + 1] == 'B' && a[i + 2] == 'S')
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
else if(a[i] == 'R' && a[i + 1] == 'B' && a[i + 2] == 'L')
{
a[i] = 'B';
if (strlen(a) > 3) strcpy(a + i + 1, a + i + 3);
else a[i + 1] = '\0';
}
}
cout << a << endl;
}
return 0;
}
This is the output:
LLSLLBRRSRS
LLSLBRSRS
LLSBSRS
LLBRS
LBS
and then the error message Runtime error(Exit status:139(Invalid memory reference)).
The goal is to make the last output be R, because LBS means R.
Thanks for the attention!
The reason for invalid memory reference is in the loop consition:
for(int i = 0; i < strlen(a) - 2; i++)
you are accessing a[i + 2] inside loop so the last iteration must end at i < strlen(a) - 3:
for(int i = 0; i < strlen(a) - 3; i++)
this just fixes your memory problem. you still get LBS as the last output.

A function about checking whether the game is over in 2048 game

I took some days to code 2048 game. And now I made most of the functions but one, testing whether the game is over. To code this game, my idea is to merge the same numbers first with the function up(down, left or right)_merge and make all the numbers go to the arrow direction that user presses with the function all_go_up(down, left or right). And then add a new number with the add_new_number function.
Here are some piece of those code I mentioned above:
void up_merge()
{
for(int i = 1; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(grid[i][j] > 0 && grid[i - 1][j] == grid[i][j]) {
while(grid[i - 1][j] == grid[i][j]) {
grid[i - 1][j] *= 2;
grid[i][j] = 0;
}
}
else if(grid[i][j] > 0 && grid[i - 1][j] == 0 && grid[i - 2][j] == grid[i][j]) {
while(grid[i - 2][j] == grid[i][j]) {
grid[i - 2][j] *= 2;
grid[i][j] = 0;
}
}
else if(grid[i][j] > 0 && grid[i - 1][j] == 0 && grid[i - 2][j] == 0 && grid[i - 3][j] == grid[i][j]) {
while(grid[i - 3][j] == grid[i][j]) {
grid[i - 3][j] *= 2;
grid[i][j] = 0;
}
}
}
}
}
void all_go_up()
{
for(int i = 3; i > 0; i--) {
for(int j = 0; j < 4; j++) {
if(grid[i][j] > 0 && grid[i - 1][j] == 0) {
grid[i - 1][j] = grid[i][j];
grid[i][j] = 0;
}
for(int k = 3; k > 0; k--) {
if(grid[k][j] > 0 && grid[k - 1][j] == 0) {
grid[k - 1][j] = grid[k][j];
grid[k][j] = 0;
}
}
}
}
}
bool add_new_number(int num)
{
int n = rand() % 2 + 1;
int newnumber = 1 << n;
int r, c;
switch(num) {
case 1: //up
r = rand() % 2 + 2;
c = rand() % 4;
break;
case 2: //down
r = rand() % 2;
c = rand() % 4;
break;
case 3: //left
r = rand() % 4;
c = rand() % 2 + 2;
break;
case 4: //right
r = rand() % 4;
c = rand() % 2;
break;
}
do {
if(check_empty() == 1) {
if(grid[r][c] == 0) {
grid[r][c] = newnumber;
return false;
}
if(grid[r][c] != 0) {
switch(num) {
case 1: //up
r = rand() % 2 + 2;
c = rand() % 4;
break;
case 2: //down
r = rand() % 2;
c = rand() % 4;
break;
case 3: //left
r = rand() % 4;
c = rand() % 2 + 2;
break;
case 4: //right
r = rand() % 4;
c = rand() % 2;
break;
}
}
}
else {
return false;
}
} while(true);
}
I have some other functions to check whether the grid is full and so on. I also tried use some while() and for() to do this, too. But I do not know where I get wrong to code the function to test whether the game is over.
I hope I express my problem well. Hoping to get some suggestions to code the test_fail function without changing too much of my code. Thanks.
With all the respect, your code looks totally unreadable. Consider functional approach where you compose few smaller function to break down more complex problem. I am going to demonstrate this in Typescript but it would be very similar in C++. In this way the code is I believe self-explanatory.
type Board = number[][]
function isGameOver(board: Board) {
if (hasEmptySpace(board)) return false
return checkHorizontalGameOver(board) && checkVerticalGameOver(board)
}
function hasEmptySpace(board: Board) {
for (let r = 0; r < NUM_ROWS; r++) {
for (let c = 0; c < NUM_COLS; c++) {
if (board[r][c] === 0) return true
}
}
return false
}
function checkHorizontalGameOver(board: Board) {
for (let i = 0; i < NUM_ROWS; i++) {
for (let j = 0; j < NUM_COLS - 1; j++) {
if (board[i][j] === board[i][j + 1]) return false
}
}
return true
}
function checkVerticalGameOver(board: Board) {
for (let i = 0; i < NUM_ROWS - 1; i++) {
for (let j = 0; j < NUM_COLS; j++) {
if (board[i][j] === board[i + 1][j]) return false
}
}
return true
}
I understand it's 5 years ago as I am reading now and your skills in programming are far far better, but still - I will post it here for people who might come across this so it can possibly help them.

tictaktoe Array bound overflow

I am in need of help for this code that i am working on for a assignment. I am have the issue where if i have any X's on the board that is either in the left 2 columns it will display a X in the row above. I used my debugger and it seems that it is trying to access something outside the array bounds, but it shouldnt be. any advice on how to do this?
#include <iostream>
using namespace std;
void printTTT(char a[3][3]);
void insertX(/*PASS BY REFERENCE*/);
void insertO(char (&arr)[3][3]);
void checkForWin(/*PASS BY REFERENCE*/); // IGNORE THIS FOR NOW
int main() {
char TTTarray[3][3] = { { 'X','-','-' },
{ '-','-','-' },
{ 'X','-','-' } };
//char TTTarray[3][3] = { {'-','X','-'},
// {'-','X','-'},
// {'-','-','O'}};
//char TTTarray[3][3] = { {'-','-','-'},
// {'-','X','-'},
// {'-','O','-'}};
//char TTTarray[3][3] = { {'X','-','X'},
// {'-','-','-'},
// {'O','-','-'}};
//char TTTarray[3][3] = { {'X','-','X'},
// {'O','X','-'},
// {'O','-','O'}};
//insertX(/*CALL*/);
//OR
insertO(TTTarray);
printTTT(TTTarray);
/*****************
I have included the declaratoin of the array, initialized to - for each spot.
The '-' represents an empty position. You should fill it with either a
capital 'O' or a capital 'X'. I have also included a number of initialized arrays
to test; just comment out the ones you don't want for that moment
*****************/
return 0;
}
void printTTT(char a[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << a[i][j];
}
cout << endl;
}
}
void insertX(/*PASS BY REFERENCE*/) {
}
void insertO(char (&arr)[3][3])
{
int x1x;
int x1y;
//int x2x;
//int x2y;
for (int i = 0; i < 3; i++)
{
int go = 0;
for (int j = 0; j < 3; j++)
{
if (arr[i][j] == '-')
{
x1x = i;
x1y = j;
// looking for 2 x's for the block lol
if (x1x == 0 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1x == 1 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1x == 2 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x - 2] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 0 && go == 0)
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 1 && go == 0)
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
if (x1y == 2 && go == 0)
181,1-8 83%
{
if (arr[x1x + 1][x1y] == 'X' && arr[x1x + 2][x1y] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x + 1][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
if (arr[x1x - 1][x1y] == 'X' && arr[x1x - 2][x1x] == 'X')
{
arr[i][j] = 'O';
go = 1;
}
}
}
}
}
}
Take a look at these lines from your insertD function:
if (x1x == 0 && go == 0)
{
if (arr[x1x][x1y + 1] == 'X' && arr[x1x][x1y + 2] == 'X')
In this case you have checked that x1x is zero, but you haven't checked x1y. So in this case you will go out of bounds if x1y is non-zero.
A couple of lines below you have
if (arr[x1x][x1y - 1] == 'X' && arr[x1x][x1x + 1] == 'X')
This will go out of bounds too, when x1y is zero.
You need to add more checks, or rethink the logic.

My c++ program runs, but say "8queens.exe has stopped working"

this code attempts to solve the 4 queens problem, placing 4 queens on a 4*4 chessboard without any of them being able to capture eachother
#include <iostream>
using namespace std;
int Place(int Chess[][4], int collumn, int i);
bool Check(int Chess[][4], int collumn, int i);
int findrow(int Chess[][4], int collumn);
const int size = 3;
int main()
{
int Chess[4][4];
int collumn;
int i = 0;
collumn = 0;
for(int s = 0; s < 4; s++)
{
for(int j = 0; j < 4; j ++)
{
Chess[s][j] = 0;
}
}
//Chess[0][0] = 1;
//Chess[3][3] = 1;
//if(Check(Chess, 3, 3) == false)
Place(Chess, collumn, i);
for(int z = 0; z < 4; z++)
{
for(int a = 0; a < 4; a++)
{
if(Chess[z][a] == 1)
cout<<"Row: "<<z<<"Collumn: "<<a<<"."<<endl;
}
cout<<endl;
}
system("pause");
return 0;
}
int Place(int Chess[][4], int collumn, int i)
{
if(collumn > size)
return 0;
while(i <= size)
{
if(Check(Chess, collumn, i) == true)
{
//cout<<"hi"<<endl;
Chess[collumn][i] = 1;
return(Place(Chess, (collumn + 1), i));
}
i ++;
}
if(i>= size)
{
//cout<<"hilo"<<endl;
return Place(Chess, collumn-1, findrow(Chess, collumn-1));
}
}
bool Check(int Chess[][4], int collumn, int i)//checks to see if it can be captured
{// very inneficitnt
int x = collumn;// this is so we can now work in terms of x and y
int y = i;
bool found = true;
// checks all the diagonal captures
if(Chess[x -1 ][y -1]== 1&& x>=1 && y >=1 )
found = false;
if(Chess[x -2 ][y - 2]== 1&& x>=2 && y>=2 )
found = false;
if(Chess[x - 3][y - 3]== 1 && x>=3 && y>=3 )
found = false;
if(Chess[x + 1][y - 1] == 1&& x<=2 && y>=1 )
found = false;
if(Chess[x + 2][y -2] == 1&& x<=1 && y>=2)
found = false;
if(Chess[x + 3][y - 3] == 1 && x<=0 && y>=3)
found = false;
if(Chess[x + 1][y + 1] == 1 && x<=2 && y<=2)
found = false;
if(Chess[x + 2][y + 2] == 1&& x<=1 && y<=1)
found = false;
if(Chess[x + 3][y + 3] == 1 && x<=0 && y<=0 )
found = false;
if(Chess[x -1 ][y + 1]== 1 && x>=1 && y<=2 )
found = false;
if(Chess[x - 2][y + 2] == 1&& x>=2 && y<=1 )
found = false;
if(Chess[x - 3][y + 3] == 1&& x>=3 && y<=0)
found = false;
//checks all the horizontal captures. We don't need to check for vertical captures
if(Chess[x + 1][y] == 1 && x<=2)
found = false;
if(Chess[x + 2][y] == 1&& x<=1 )
found = false;
if(Chess[x+3][y] == 1 && x<=0)
found = false;
if(Chess[x -1 ][y] == 1&& x>=1)
found = false;
if(Chess[x-2][y] == 1&& x>=2 )
found = false;
if(Chess[x-3][y] == 1 && x>=3)
found = false;
if(found == false)
return false;
if(found == true)
return true;
}
int findrow(int Chess[][4], int collumn)
{
for(int z = 0; z < 4; z++)
{
if(Chess[collumn][z] == 1)
{
Chess[collumn][z] = 0;
return z;
}
}
}
The first thing I see is a probable out-of-bounds access:
if(Chess[x -1 ][y -1]== 1&& x>=1 && y >=1 )
What if the value of x is 0? You are accessing Chess[-1][y], which is out of bounds. Your if statement does not stop this, even with the x>=1 condition.
The if will first test the Chess[x-1][y-1]==1 condition. If you want this to not happen, place the test for x>=1 before Chess[x-1][y-1]==1.
But even with this, that entire section of code looks suspicious. I wouldn't be surprised if there were more out-of-bounds accesses.