2D Arrays with 'Creature' Movement Error (C++) - c++

For this assignment, I have to make a creature 'C' be on a environment (20x20 array) and have it move.
The first time, it works and moves the creature, but the second time+, it doesn't.
So here's the code. Yes, I'm aware it's pretty messy, but I'm still kinda new to c++ (I wouldn't mind corrections :D). Also, as part of the assignment, the creature has to be in a LifeForm class.
Click here for a cpp.sh link to run.
#include <iostream>
#include <ctime>
#include <string>
using namespace std;
class LifeForm{
public:
int x, y;
char array[20][20];
string name(){
return "Control";
}
char symbol(){
return 'C';
}
void xy(){
x = (rand() % 18) + 1; //random position in x
y = (rand() % 18) + 1; //random position in y
array[x][y] = symbol();
}
void step(){
for (int a = 0; a < 20; a++){
for(int b = 0; b < 20; b++){
array[a][b] = '0';
}
}
array[x + 1][y + 1] = symbol();
if (x > 19 || x < 2 || y > 19 || y < 2){
cout << "The creature cannot move any further without leaving the environment!" << endl;
array[x][y] = '0';
array[x - 1][y - 1] = symbol();
}
system("pause");
system("cls");
find(array);
for (int a = 0; a < 20; a++){
for (int b = 0; b < 20; b++){
cout << array[a][b] << " ";
}
cout << endl;
}
}
void step10(){
//todo
}
void find(char array[][20]){
for (int a = 0; a < 20; a++){
for (int b = 0; b < 20; b++){
if (array[a][b] != '0'){
cout << "Found Creature '" << name() << "' in row " << a + 1 << ", column " << b + 1 << "." << endl;
}
}
}
}
};
int main(){
LifeForm creature;
srand((unsigned) time(0)); //randomize
for (int a = 0; a < 20; a++){ //initilize array to all 0's
for (int b = 0; b < 20; b++){
creature.array[a][b] = '0';
}
}
creature.xy();
creature.find(creature.array);
for (int a = 0; a < 20; a++){ //display the array
for (int b = 0; b < 20; b++){
cout << creature.array[a][b] << " ";
}
cout << endl;
}
creature.step();
string a;
bool abc;
do{
cout << "\n--- What would you like to do? --------------" << endl;
cout << "S for Step | S10 for Step 10 | E for Exit" << endl;
cout << "---------------------------------------------" << endl;
cin >> a;
if (a == "S" || a == "s") {
creature.step();
abc = true;
}else if (a == "S10" || a == "s10") {
creature.step10();
abc = true;
}else{
abc = false;
system("pause");
}
}while(abc == true);
}
So, as you can see, I'm trying to get the creature to move more then once when the user chooses to, but it stays at the same position.

In the method step you never update the current position of the Creature. In this line array[x + 1][y + 1] = symbol(); you update the array. But you should rewrite it to this:
x++;
y++;
array[x][y] = symbol();
By doing this, you ensure that the current position of the creature is updated correctly when you change the representation of the position (The array you draw on the screen).

Related

How do I make a function to check for the winning move in tic-tac-toe if the user chooses the size of the game board?

I have changed a Tic-Tac-Toe program from using a normal 3x3 grid to a grid-size chosen by the user (between 3 and 9). I am using a global constant 'SIZE' to hold the value the user chooses. My issue is adapting my winMove(); function so that it adjusts to check for the winning move based on the current board size chosen by the user(SIZE). I have tried different loops but can't get it to work. Right now it will only work with a 3x3 board.
I am still learning c++ and I have been stuck on this for a few days so I'm hoping a friendly person can help. This is my full program so far, hope it's not too much of a mess!
#include <iostream>
using namespace std;
struct TicTacToe
{
char **board;
};
void makeBoard(TicTacToe&);
void deallocBoard(TicTacToe&);
void printBoard(TicTacToe);
bool isDraw(TicTacToe);
void convertInput(char, char, int&, int&);
char winMove(TicTacToe, int, int);
bool validateSIZE(int);
int SIZE = 1;
int main(){
while(SIZE < 3 || SIZE > 9)
{
cout << "Enter number between 3 and 9 for the length of board.\n";
cout << "Example: 4 will make a board with 4 rows and 4 columns: ";
cin >> SIZE;
validateSIZE(SIZE);
}
TicTacToe game;
makeBoard(game);
char winner = 0;
char turn = 'X';
char rowIn, colIn;
int row, column;
while(!winner && !isDraw(game))
{
printBoard(game);
cout << "\nPlayer " << turn << "'s move (input format: a1): ";
cin >> rowIn >> colIn;
convertInput(rowIn, colIn, row, column);
if (game.board[row][column]==' ')
{
game.board[row][column] = turn;
if (turn == 'X')
{turn = 'O';}
else
{turn = 'X';}
winner = winMove(game, row, column);
}
else
cout << "Taken, try again!\n";
}
printBoard(game);
if (winner == 'X' || winner == 'O')
{cout << " Congrats, the winner is " << winner << '.' << endl;}
else
{cout << " Game ends in a draw." << endl;}
cout << endl << "Game Over!" << endl << endl;
deallocBoard(game);
return 0;
}
// Need help with this function.
char winMove(TicTacToe gameIn, int i, int j)
{
//row win
if (gameIn.board[i][0]==gameIn.board[i][1] &&
gameIn.board[i][0]==gameIn.board[i][2])
{
return gameIn.board[i][j];
}
//column win
if (gameIn.board[0][j]==gameIn.board[1][j] &&
gameIn.board[0][j]==gameIn.board[2][j])
{
return gameIn.board[i][j];
}
//left diagonal win
if (gameIn.board[0][0] != ' ' &&
gameIn.board[0][0] == gameIn.board[1][1] &&
gameIn.board[0][0] == gameIn.board[2][2])
{
return gameIn.board[i][j];
}
//right diagonal win
if (gameIn.board[0][2] != ' ' &&
gameIn.board[0][2] == gameIn.board[1][1] &&
gameIn.board[0][2] == gameIn.board[2][0])
{
return gameIn.board[i][j];
}
return 0;
}
bool validateSIZE(int SIZE)
{
if(SIZE < 3 || SIZE > 9)
{
cout << "\n\nNumber must be between 3 and 9!\nTry again!\nPlease ";
return false;
}
return true;
};
void makeBoard(TicTacToe& gameIn)
{
gameIn.board = new char*[SIZE];
for(int i = 0; i < SIZE; i++)
{gameIn.board[i] = new char[SIZE];}
for(int j =0; j < SIZE; j++)
for(int k = 0; k < SIZE; k++)
{gameIn.board[j][k] = ' ';}
}
void deallocBoard(TicTacToe& gameIn)
{
for(int i = 0; i < SIZE; i++)
delete [] gameIn.board[i];
delete [] gameIn.board;
gameIn.board = NULL;
}
void printBoard(TicTacToe gameIn)
{
int temp = 1;
cout << " ";
while(temp < SIZE + 1)
{
cout << temp << " ";
temp++;
}
temp = 1;
cout << endl;
for(int i = 0; i < SIZE; i++)
{
cout << char(i + 'a') << '|';
for(int j = 0; j < SIZE; j++)
{
cout << gameIn.board[i][j] << '|';
}
cout << endl;
}
}
bool isDraw(TicTacToe gameIn)
{
bool full = true;
for(int i = 0; full && i < SIZE; i++)
for(int j = 0; full && j < SIZE; j++)
full = gameIn.board[i][j] != ' ';
return full;
}
void convertInput(char rowIn, char colIn, int& row, int& column)
{
row = toupper(rowIn) - 'A';
column = colIn - '1';
}
You can easily use 2 for loops to iterate every starting point and its direction to preform victory checking. Something that would look like this:
// hor ver diagonals
// dx[4] = {1, 0, 1, 1};
// dy[4] = {0, 1, 1, -1};
// check horizontal win
for(int i = 0; i < SIZE; ++i)
{
bool win = true;
for(int j = 1; j < SIZE; ++j)
{
if(gameIn.board[j][i] != gameIn.board[j - 1][i])
{
win = false;
break;
}
}
if(win == true){return ;}
}
// check vertical win
.
.
.
// check diagonal 1 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][i] != gameIn.board[i - 1][i - 1])
break;
if(i == SIZE - 1)return ;
}
// check diagonal 2 win
for(int i = 1; i < SIZE; ++i)
{
if(gameIn.board[i][SIZE - i - 1] != gameIn.board[i - 1][SIZE - i])
break;
if(i == SIZE - 1)return ;
}
I'll leave the vertical win for you.

Recursive function throws unhandled exception at 0x79B20AD2 (ucrtbased.dll)

I write minesweeper and the current task is to write a function that would uncover the areas that have no mines neighbouring to them. In the original minesweeper if you click within the area with no mines, it would open up an area until there are mines alongside its borders. For that I wrote the function unravel(). Here is the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not (minusrows == 0 && minuscolumns == 0)) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
unravel(fogofwar, display, x, y);
}
return 0;
}
If I delete the recursivity by changing unravel(fogofwar, display, x + minusrows, y + minuscolumns); to continue; within the function unravel(), it works as intended. But I need to open up the entire area where there are 0's on the display. Any way to skirt the error or fix it for good?
First of all, I am unable to reproduce the error with the information in question. Please try to specify the complete usecase along with what values you are getting into error with.
However, there is an obvious problem in the implementation of unravel.
You go over the same cell multiple times, until the memory exceeds total memory of course (I believe this is the point your program crashes)
You should maintain the slots already visited. You can do this in multiple ways. I am providing one of the ways to handle this.
Try the following code:-
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#define Str1D vector<string>
#define Str2D vector<Str1D>
#define Int1D vector<int>
#define Int2D vector<Int1D>
void unravel(Str2D &fogofwar, Int2D &display, int x, int y, vector<vector<bool> > &visited) {
for (int minusrows = -1; minusrows < 2; minusrows++){ // going through the
// neighbouring cells (+ the cell itself)
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (x + minusrows > 0 && y + minuscolumns > 0 && x + minusrows < fogofwar.size() && y + minuscolumns < fogofwar[0].size()){ // checking
// if within borders
if (x > 0 && y > 0 && x < fogofwar.size() && y < fogofwar[0].size()) { // checking if the oririginal
// values are within borders
if (x > 0 && y > 0 && x < visited.size() && y < visited[0].size()) {
cout.flush();
}
visited[x][y] = true;
fogofwar[x + minusrows][y + minuscolumns] = to_string(display[x + minusrows][y + minuscolumns]); // revealing the
// neighbouring cells
if (display[x + minusrows][y + minuscolumns] == 0) { // if the cell is 0 on the display,
// open it and the 8 neighbouring to it cells
if (not visited[x + minusrows][y + minuscolumns]) { // if it's not the same cell, of course,
// otherwise it's an endless cycle
unravel(fogofwar, display, x + minusrows, y + minuscolumns, visited);
}
}
}
}
}
}
}
int main() {
int row, column, prob;
bool running = true;
cout << "Input width and height: ";
cin >> row >> column;
cout << endl << "Input mines probability (%): ";
cin >> prob;
cout << endl;
srand (time(NULL));
Int2D field(row + 1, Int1D(column + 1));
Int2D display(row + 1, Int1D(column + 1));
Str2D fogofwar(row + 1, Str1D(column + 1, "*"));
field[0][0] = 0; // field of mines
display[0][0] = 0; // display of neighbouring mines
fogofwar[0][0] = to_string(0); // what the player will see
for (int i = 1; i < row + 1; i++) { //assigning coordinates
field[i][0] = i;
display[i][0] = i;
fogofwar[i][0] = to_string(i);
}
for (int j = 1; j < column + 1; j++) { //assigning coordinates
field[0][j] = j;
display[0][j] = j;
fogofwar[0][j] = to_string(j);
}
for (int i = 1; i < row + 1; i++){ // filling the field with mines
for (int j = 1; j < column + 1; j++){
int x = rand() % 100;
if (x < prob) {
field[i][j] = 1;
}
else{
field[i][j] = 0;
}
}
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // printing field
for (int j = 0; j < column + 1; j++){
cout << " " << field[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
for (int i = 0; i < row + 1; i++){ // assigning the display of amount of neighbouring mines
for (int j = 0; j < column + 1; j++){
int count = 0;
if (i > 0 && j > 0){
for (int minusrows = -1; minusrows < 2; minusrows++){
for (int minuscolumns = -1; minuscolumns < 2; minuscolumns++){
if (i + minusrows > 0 && i + minusrows < row + 1 && j + minuscolumns > 0 && j + minuscolumns < column + 1){
if (field[i + minusrows][j + minuscolumns] == 1){
count++;
}
}
}
}
display[i][j] = count;
}
cout << " " << display[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
while (running) {
for (int i = 0; i < row + 1; i++){
for (int j = 0; j < column + 1; j++){
cout << " " << fogofwar[i][j] << " ";
}
cout << endl;
}
cout << endl;
int x, y;
cout << endl << "Input the target cell (x, y): ";
cin >> x >> y;
cout << endl;
vector<vector<bool> > visited(row+1, vector<bool>(column+1, false));
unravel(fogofwar, display, x, y, visited);
}
return 0;
}
The change is that I am maintaining a visited array, and I never go back to the spot I have already gone to before in unravel.

UVA Online Judge Runtime Error on 706 LCD Display

I am new to C++ programming and trying to solve some problems on UVa Online Judge our prof gave us.
Right now I am on the 706 LCD Display (https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=16&page=show_problem&problem=647).
In my IDE (VS2015 Community) everything works fine and as expected but when I'm trying to submit my code I get a runtime error. Unfortunately they don't show more details about it.
I tried to run my code in several online c++ compilers (such as http://cpp.sh/) and never expirienced an error.
This is my code
#include <iostream>
#include <cmath>
// set the "borders" for each number
#define ZERO 1+2+4+16+32+64;
#define ONE 4+32;
#define TWO 1+4+8+16+64
#define THREE 1+4+8+32+64
#define FOR 2+4+8+32
#define FIVE 1+2+8+32+64
#define SIX 1+2+8+16+32+64
#define SEVEN 1+4+32
#define EIGHT 1+2+4+8+16+32+64
#define NINE 1+2+4+8+32+64
using namespace std;
// draw the digits line by line. some lines (first, middle, last) only represents horizontal lines, where all other lines represent vertical lines
// in every line for every digit is checked wheter the lines on the current position must be drawn or not.
void drawDigits(int* digits, int cDigits, int height, int width) {
int middle = (height >> 1);
for (int i = 0; i < height; ++i) {
for (int j = 0; j < cDigits; ++j) {
if (i == 0) {
if (digits[j] & 1) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
else if (i < middle) {
if (digits[j] & 2) {
cout << "|";
for (int y = 0; y < width - 2; ++y) cout << " ";
}
else {
for (int y = 0; y < width - 1; ++y) cout << " ";
}
if (digits[j] & 4) {
cout << "|";
}
else {
cout << " ";
}
}
else if (i == middle) {
if (digits[j] & 8) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
else if (i < height - 1) {
if (digits[j] & 16) {
cout << "|";
for (int y = 0; y < width - 2; ++y) cout << " ";
}
else {
for (int y = 0; y < width - 1; ++y) cout << " ";
}
if (digits[j] & 32) {
cout << "|";
}
else {
cout << " ";
}
}
else {
if (digits[j] & 64) {
cout << " ";
for (int y = 0; y < width - 2; ++y) cout << "-";
cout << " ";
}
else {
for (int y = 0; y < width; ++y) cout << " ";
}
}
if (j != cDigits - 1) cout << " ";
}
cout << endl;
if (i == height - 1) cout << endl;
}
}
// a given number (c-string) is prepared for drawing
// find out the length of the 'number' and assign for each digit the defined value in the ditigs-array
void drawLCD(int size, char* number) {
if (size < 1 || size > 10) return;
int length = 0;
while (*(number + length) != '\0') {
++length;
}
int* digits = new int[length];
for (int i = 0; i < length; ++i) {
int t = 0;
switch (*(number++) - '0') {
case 0:
t = ZERO;
break;
case 1:
t = ONE;
break;
case 2:
t = TWO;
break;
case 3:
t = THREE;
break;
case 4:
t = FOR;
break;
case 5:
t = FIVE;
break;
case 6:
t = SIX;
break;
case 7:
t = SEVEN;
break;
case 8:
t = EIGHT;
break;
case 9:
t = NINE;
break;
default:
t = ZERO;
}
digits[i] = t;
}
drawDigits(digits, length, 2 * size + 3, size + 2);
}
void callDraws(int cNums, int* size, char** numbers) {
for (int i = 0; i < cNums; ++i) {
drawLCD(size[i], numbers[i]);
}
}
// gets the integer value from a number in a c-string
int getInt(char* str) {
int length = 0;
int res = 0;
while (*(str + length) != '\0') {
++length;
}
for (int i = 0; i < length; ++i) {
res += (int)pow(10, length - (i + 1)) * (*(str++)-'0');
}
return res;
}
int main() {
char* n = new char[10];
int counter = 0;
int* size = new int[1000];
char** numbers = new char*[1000];
for (int i = 0; i < 1000; ++i) {
size[i] = 0;
numbers[i] = "";
}
while (cin >> n) {
if (size[counter] <= 0) {
int nn = getInt(n);
if (nn <= 0) break;
size[counter] = nn;
}
else {
numbers[counter++] = n;
n = new char[10];
}
}
callDraws(counter, size, numbers);
return 0;
}
When I enter a 'return 0' before the call to callDraws() the code terminates. So the error must be somewhere in printing the digits.
Where is this runtime error or how can I find it?
Thanks in advance.

Two-Dimensional Array Searching Algorithm Optimisation

I have been given a "Sand box" of variable length and width. I've been given instructions to find a "shovel" of static size, which may be oriented either horizontally or vertically. I implement the following algorithm in order to search the least amount of times to find one valid location (one which corresponds to a "part of the object") in the grid:
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; j < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
In this case, the "Sand box" will be tested by the function as described below.
I completely recreate this scenario with a "Sand box" whose size is fixed (though easily manipulated) whose shovel is still randomly placed and oriented within the following code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
const int ROW = 12;
const int COL = 16;
char sandbox[ROW][COL];
bool probeSandBoxTwo(char c, int i);
void displayResults(int sCount, bool found, int x, int y);
void displaySandbox();
void displaySearchPattern();
void fillSandbox();
void placeShovel();
int main() {
fillSandbox();
placeShovel();
displaySandbox();
//define your variables here
bool found;
int nShift,
sCount,
shovelSize,
x,
y;
found = false;
nShift = 0;
shovelSize = 4;
sCount = 0;
for(int i = 0; i < ROW && !found; i++) {
for(int j = 0; j < COL && !found; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
x = i;
y = j + nShift;
sCount++;
cout << "Search conducted at (" << i << ", " << (j + nShift) << ")" << endl;
}
if(nShift >= shovelSize - 1 || nShift > ROW) {
nShift = 0;
} else {
nShift++;
}
}
displayResults(sCount, found, x, y);
displaySearchPattern();
}
bool probeSandBoxTwo(char c, int i) {
if(sandbox[c-'A'][i-1] == 'X') {
return true;
} else {
return false;
}
}
void displayResults(int sCount, bool found, int x, int y) {
cout << endl;
cout << "Total searches: " << sCount << endl;
cout << endl;
if(found) {
cout << "Shovel found at coordinates: (" << x << ", " << y << ")" << endl;
}
}
void displaySandbox() {
cout << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
cout << sandbox[i][j];
}
cout << endl;
}
cout << endl;
}
void displaySearchPattern() {
int nShift = 0;
int shovelSize = 4;
cout << endl << " ";
for(int i = 0; i < COL; i++) {
cout << (i % 10); //show index numbers [col]
}
cout << endl;
for(int i = 0; i < ROW; i++) {
cout << (i % 10) << " "; //show index numbers [row]
for(int j = 0; j < COL; j++) {
if(!((j + nShift) % shovelSize)) {
cout << 'o';
} else {
cout << '.';
}
}
if(nShift >= shovelSize - 1 || nShift > COL) {
nShift = 0;
} else {
nShift++;
}
cout << endl;
}
}
void fillSandbox() {
for(int i = 0; i < ROW; i++) {
for(int j = 0; j < COL; j++) {
sandbox[i][j] = '.';
}
}
}
void placeShovel() {
srand(time(NULL));
int shovelRow,
shovelCol,
shovelSize = 4;
if(rand() % 2) {
//horizontal
shovelRow = rand() % ROW + 1;
shovelCol = rand() % (COL - (shovelSize - 1)) + 1;
for(int i = shovelCol - 1; i < shovelSize + (shovelCol - 1); i++) {
sandbox[shovelRow - 1][i] = 'X';
}
} else {
//vertical
shovelRow = rand() % (ROW - (shovelSize - 1)) + 1;
shovelCol = rand() % COL + 1;
for(int i = shovelRow - 1; i < shovelSize + (shovelRow - 1); i++) {
sandbox[i][shovelCol - 1] = 'X';
}
}
}
In this code, I also graphically display the pattern (when run) with which my algorithm searches.
Is this truly the optimal search pattern for such a scenario, is my implementation correct, and if so, why might I be having incorrect results returned?
A given test driver reports the following results:
The source code for this result (and its test driver).
found = false;
nShift = 0;
shovelSize = 4;
for(int i = 0; i < SandBoxRows; i++) {
for(int j = 0; (j + nShift) < SandBoxColumns; j+=shovelSize) {
found = probeSandBoxTwo(('A' + i), (j + 1 + nShift));
}
if(nShift >= shovelSize - 1 || nShift > SandBoxColumns) {
nShift = 0;
} else {
nShift++;
}
}
This corrects an error in the conditional portion of the for loop header which did not account for the index-shifting variable nShift.

Connect Four C++

I am coding the game connect four for my computer science class, everything was going great then I dont know what happened but I kept getting Sementation faults whenever I tried to run it. Here is my code.
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
using namespace std;
struct game{
char **board;
char p1;
char p2;
};
void print_board(game p, int r, int c);
bool play(game p, bool gamewon, int r, int c, int pieces);
bool check(int a, int b, game p, int r, int c, int pieces);
int drop(int b, char player, game p, int c);
int main(int argc, char *argv[]){
game p;
int r, c, pieces;
bool gamewon = false;
/*if(argc == 7) {
for(int i = 1; i < argc; i += 2) {
if(argv[i][0]=='-' && argv[i][1]=='r')
r = atoi(argv[i+1]);
else if(!strcmp(argv[i],"-c"))
c = atoi(argv[i+1]);
else if(!strcmp(argv[i],"-p")){
pieces = atoi(argv[i+1]);
while (pieces < 1){
cout << "You cannot have 0 pieces to connect." << endl;
cout << "Please enter a positive, non-zero integer"
<< " for the number of pieces to connect: ";
cin >> pieces;
}
}
else
cout << "Error." << endl;
}
}*/
r = 6;
c = 7;
pieces = 4;
p.board = new char*[r];
for(int i=0; i < r;i++)
p.board[i] = new char[c];
for(int a =0; a < r; a++){
for(int b = 0; b < c; b++)
p.board[a][b] = ' ';
}
print_board(p, r, c);
gamewon = play(p, gamewon, r, c, pieces);
return 0;
}
bool play(game p, bool gamewon, int r, int c, int pieces){
int col, hold = 0, charsPlaced = 0;
char player = 'y';
while(!gamewon){
if(hold != -1){
if(player =='y'){
cout<<"Player 1, what column do you want to put your piece? ";
player = 'r';
}
else{
cout<<"Player 2, what column do you want to put your piece? ";
player = 'y';
}
}
while(true){
if(charsPlaced == r*c) break;
cin>>col;
col--;
if(col <=r && col>= 0) break;
else cout<< "\nPlease enter a value between 1 and " << c << ": ";
if (cin.fail()){
cin.clear();
char d;
cin>>d;
}
}
if(charsPlaced == r*c) break;
hold = drop(col,player, p, c);
if(hold == -1) cout<<"Column is full!\nPlease enter another number between 1 and " << c << ": ";
else{
gamewon = check(hold, col, p, r, c, pieces);
charsPlaced ++;
print_board(p, r, c);
}
}
if(charsPlaced == r*c){
cout<<"No winner! Game is a draw\n";
return true;
}
if(player == 'y')
cout<<"Player 2 is the winner!\n";
else cout<<"Player 1 is the winner!\n";
return true;
}
void print_board(game p, int r, int c){
cout << endl;
for(int a = 0; a < r; a++){
for(int b = 0; b < c; b++)
cout << "|" << p.board[a][b];
cout << "|";
cout << endl;
for(int i = 0; i < c; i++)
cout << "--";
cout << endl;
}
}
bool check(int a, int b, game p, int r, int c, int pieces){
int vertical = 1, horizontal = 1, diagonalone = 1, diagonaltwo = 1, i , j;
cout << i << " " << b << " " << a << endl;
char player = p.board[a][b];
cout << player << endl;
for(i = a + 1; p.board[i][b] == player && i < r; i++, vertical++);
for(i = a - 1; p.board[i][b] == player && i >= 0; i--, vertical++);
if(vertical >= pieces)
return true;
for(j = b - 1; p.board[a][j] == player && j >= 0; j--, horizontal++);
for(j = b + 1; p.board[a][j] == player && j < c; j++, horizontal++);
if(horizontal >= pieces)
return true;
for(i = a - 1, j = b - 1; p.board[i][j] == player && i >= 0 && j >= 0; diagonalone++, i--, j--);
for(i = a + 1, j = b + 1; p.board[i][j] == player && i <= r && j <= c;diagonalone++, i++, j++);
if(diagonalone >= pieces)
return true;
for(i = a - 1, j = b + 1; p.board[i][j] == player && i >= 0 && j <= c; diagonaltwo++, i--, j++);
for(i = a + 1, j = b - 1; p.board[i][j] == player && i <= r && j >= 0; diagonaltwo++, i++, j--);
if(diagonaltwo >= pieces)
return true;
return false;
}
int drop(int b, char player, game p, int c){
if(b >= 0 && b <= c){
if(p.board[0][b] == ' '){
int i;
for(i = 0; p.board[i][b] == ' '; i++)
if(i == 5){
p.board[i][b] = player;
return i;
}
i--;
p.board[i][b] = player;
return i;
}
else{
return -1;
}
}
else{
return -1;
}
}
You are using
char **board;
in your game struct.
But this 2D array is never allocated and yet, you are working with it.
You are missing something like this:
in C:
board = malloc(10 * sizeof(char *));
for (int i = 0; i < 10; i++)
{
board[i] = malloc(10 * sizeof(char));
}
in C++:
board = new char*[10]
for (int i = 0; i < 10; i++)
{
board[i] = new char[10];
}
For starters, if you are in a Linux environment, valgrind is very helpful in finding where your segmentation fault is. To use it, if your program is called hello, just run it as valgrind hello.
Another method to debug these is to put cout or printf statements throughout your code, and observe what the last output was. You are probably indexing beyond the end of an array. Keep in mind that if you declare int x[5], the valid index values are 0 to 4.
You will probably need to change your for loops to < vs. <= so you aren't reading past the last part of the board (keep in mind that arrays are 0 indexed in c++).