Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm learning C++ and whilst I have a reasonable understanding of C# I've never run into this issue before. With a simple program that places chess pieces on an imaginary board (an enumerated array) and then assigns the squares which would have pieces at the start their pieces, you are then asked for coordinates and the program returns what is on that square. It displays the correct piece yet will always crash in non-debugging mode and display a buffer overrun in Visual Studio debugging. It's quite short so I'll show all the code.
#include <iostream>
#include <string>
using namespace std;
int main() {
enum Chessboard {
Blank,
Pawn,
Rook,
Knight,
Bishop,
King,
Queen
};
Chessboard board[8][8] = { Blank };
for (int x = 1; x < 8; x++)
{
board[1][x] = Pawn;
board[8][x] = Pawn;
}
board[7][0] = Rook;
board[7][1] = Knight;
board[7][2] = Bishop;
board[7][3] = King;
board[7][4] = Queen;
board[7][5] = Bishop;
board[7][6] = Knight;
board[7][7] = Rook;
board[0][0] = Rook;
board[0][1] = Knight;
board[0][2] = Bishop;
board[0][4] = King;
board[0][3] = Queen;
board[0][5] = Bishop;
board[0][6] = Knight;
board[0][7] = Rook;
int X = 0;
int Y = 0;
bool Error = false;
cout << "Enter the coordinates of a square on a chessboard to see what is on there at the start of the game (1 number at a time)" << endl;
do {
cin >> X;
X--;
Error = false;
if (X < 0 || X > 7)
{
cout << "That's not on the board" << endl;
Error = true;
}
} while (Error = false);
do {
cin >> Y;
Y--;
Error = false;
if (Y < 0 || Y > 7)
{
cout << "That's not on the board" << endl;
Error = true;
}
} while (Error = false);
string Name = "";
Chessboard Piece = board[X][Y];
switch (Piece)
{
case Blank: Name = "nothing";
break;
case Pawn: Name = "a Pawn";
break;
case Rook: Name = "a Rook";
break;
case Knight: Name = "a Knight";
break;
case Bishop: Name = "a Bishop";
break;
case King: Name = "a King";
break;
case Queen: Name = "a Queen";
break;
default: Name = "Somehow you missed the board";
break;
}
cout << "On " << ++X << "," << ++Y << " there is " << Name << endl;
return 0;
}
You'll certainly get an overrun here:
Chessboard board[8][8] = { Blank };
for (int x = 1; x < 8; x++)
{
board[1][x] = Pawn;
board[8][x] = Pawn;
}
There's no board[8][]. You have board[0][] through board[7][] available.
You are going outside the boundaries of your matrix
board[1][x] = Pawn;
board[8][x] = Pawn;
You declared it 8x8 so index 0..7 are to be used.
In C, C++ and C# indices of arrays start from 0 to size of the array - 1. So for example this loop
for (int x = 1; x < 8; x++)
{
board[1][x] = Pawn;
board[8][x] = Pawn;
}
has to be rewritten as
for ( int x = 0; x < 8; x++)
{
board[1][x] = Pawn;
board[6][x] = Pawn;
}
provided that the array is defined as
Chessboard board[8][8] = { Blank };
Also it would be a good idea to introduce a mnemonic name for magic number 8 and use this name everwhere instead of the number.
for (int x = 0; x < 8; x++)
{
board[0][x] = Pawn;
board[7][x] = Pawn;
}
I think 7 is the maximum for this array.
As stated by everybody else, its the board[8][x] = Pawn that is causing the error.
Though this appears to be a test program rather than something that will go into production but still one word of caution that I would like to advise, always try to avoid numbers / hard coded strings/integers or anything else, in your code for reason that you usually end up doing things like this. And one day when project goes into production and may be your boss will decide to change the value to say, 100 x 100, you will have a very hard time doing things.
Good Ways to do this :
static const int BoardSize = 10;
or
#define BoardSize 10;
Related
Could anyone point the flaw in the code?
The idea that I used is backtracking with recurrence and I would like to stick to this way of sloving the given problem. When the variable moves is <= 60 couple of answers are printed instantly though the program is still running. If moves = 61,62 it takes couple of minutes to print some solutions and if moves = 63 no solution is printed within 15 mins in both cases the program is still running.
Here is the code:
//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;
void solve()
{
//printing one solution
if(moves==63)
{
for(int k = 0; k < 8; k++)
{
for(int n = 0; n < 8; n++)
cout << setw(2) << board[k][n] << " ";
cout << "\n";
}
cout << "--------------------\n";
return;
}
else
{
for(int i = 0; i < 8; i++)
{
//checking if knight is not leaving the board
if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
continue;
//moving theknight
x+=move_to[i][0];
y+=move_to[i][1];
//increasing the moves count
moves++;
//marking the square to be visited
board[x][y] = moves+1;
//backtracking
solve();
board[x][y] = 0;
x-=move_to[i][0];
y-=move_to[i][1];
moves--;
}
}
}
int main()
{
solve();
return 0;
}
I remember this problem from study. I do not fix them but I change initial position then the first path is found faster (that is how I passed this lab ;P). It is normal because
the number of path is too big.
But you can:
choose from move_to in random order
use multiple threads
Other hand you can read about "Constraint Programming"
Sorry if the code is too long. I just wanted to give a detailed description of the situation I am facing
I'm coding a game called Battle Ship. The following code is a simpler version, I did eliminate all the unnecessary logic, cause I just want to indicate the problem with the magic numbers.
Here are my struct and enum
// the dimension of the 10 + 2 game grid for detection of the neighboring ship
// (its usage comes later in the game, not at this stage)
const int SIZE = 12;
// the number of warships
const int NBSHIP = 5;
string ships[NBSHIP] = {"Carrier", "Cruiser", "Destroyer", "Submarine", "Torpedo" };
// available warships and their size on the grid
enum Ship {
CARRIER=5,
CRUISER=4,
DESTROYER=3,
SUBMARINE=3,
TORPEDO=2,
NONE=0
};
// the different states that a grid cell can take and their display
enum State {
HIT='x',
SINK='#',
MISS='o',
UNSHOT='~'
};
// a grid cell
// the ship present on the space
// the state of the box
struct Cell {
Ship ship;
State state;
};
// the player with
// his name
// his score to determine who lost
// his game grid
struct Player {
string name;
int score;
Cell grid[SIZE][SIZE];
};
// the coordinates of the cell on the grid
// its column from 'A' to 'J'
// its line from 1 to 10
struct Coordinate {
char column;
int line;
};
// the placement of the ship on the grid
// its coordinates (E5)
// its direction 'H' horizontal or 'V' vertical from the coordinate
struct Placement {
Coordinate coordi;
char direction;
};
Basically, at the beginning of the game, I have to initialize a grid with the appropriate state for each cell (in this case, UNSHOT and NONE). Then I have to display the grid and start placing the ships. The weird thing here is I have to use "magic numbers" to place the ships in the correct position according to the player's input. But I don't even know why I need it as well as how to get rid of it.
Utilization of magic number appears in placeShip function.
void initializeGrid (Cell aGrid[][SIZE])
{
for (int i = 0; i < SIZE - 2; i++)
{
for (int j = 0; j < SIZE - 2; j++)
{
aGrid[i][j].ship = NONE;
aGrid[i][j].state = UNSHOT;
}
}
}
void displayGrid(Player aPlayer)
{
cout << endl;
cout << setw(10) << aPlayer.name << endl;
// Letter coordinates
char a = 'A';
cout << " ";
for (int i = 0; i < SIZE - 2 ; i++)
{
cout << " " << char (a+i);
}
cout << endl;
// Number coordinates
for (int i = 0; i < SIZE - 2; i++)
{
// Player
if(i + 1 >= 10) // To align the first column
cout << i + 1;
else
cout << " " << i + 1;
for (int j = 0; j < SIZE - 2; j++)
{
if (aPlayer.grid[i][j].ship) // Check if there are ships
cout << " " << (aPlayer.grid[i][j].ship);
else
cout << " " << char (aPlayer.grid[i][j].state);
}
cout << endl;
}
}
void placeShip(Cell aGrid[][SIZE], Placement aPlace, Ship aShip)
{
if (aPlace.direction == 'h' || aPlace.direction == 'H')
{
for (int i = 0; i < aShip; i++) // To change the value of a cell according to the size of the boat
{
// Utilization of magic number
aGrid[aPlace.coordi.line - 9][aPlace.coordi.column + i - 1].ship = aShip; // Horizontal so we don't change the line
}
}
else if (aPlace.direction == 'v' || aPlace.direction == 'V')
{
for (int i = 0; i < aShip; i++)
{
// Utilization of magic number
aGrid[aPlace.coordi.line + i - 9][aPlace.coordi.column - 1].ship = aShip; // Vertical so we don't change the column
}
}
}
void askPlayerToPlace(Player& aPlayer)
{
Ship battleships[NBSHIP] = { CARRIER, CRUISER, DESTROYER, SUBMARINE, TORPEDO};
for (int i = 0; i < NBSHIP; i++)
{
string stringPlace;
string stringShip = ships[i];
Ship aShip = battleships[i];
string inputDirection;
Coordinate coordi;
cout << "\n" << aPlayer.name << ", time to place your carrier of length "
<< to_string(battleships[i])
<< " (" << ships[i] << ")\n"
<< "Enter coordinates (i.e. B5): ";
cin >> stringPlace;
coordi = { stringPlace[0], int(stringPlace[1]) - 48 };
cout << "Direction: ";
cin >> inputDirection;
Placement aPlace = {
coordi,
inputDirection[0]
};
placeShip(aPlayer.grid, aPlace, aShip);
displayGrid(aPlayer);
}
}
int main()
{
Player aPlayer;
cout << "Player's name: ";
getline (cin, aPlayer.name);
initializeGrid(aPlayer.grid);
displayGrid(aPlayer);
askPlayerToPlace(aPlayer);
return 0;
}
The weird thing here is I have to use "magic numbers" to place the ships in the correct position according to the player's input.
If these are numbers, which tend to appear frequently you should define another constant for these like:
const int GRID_SIZE_MARGIN = 2;
and use it
void initializeGrid (Cell aGrid[][SIZE]) {
for (int i = 0; i < SIZE - GRID_SIZE_MARGIN; i++) {
for (int j = 0; j < SIZE - GRID_SIZE_MARGIN; j++) {
aGrid[i][j].ship = NONE;
aGrid[i][j].state = UNSHOT;
}
}
}
If there are other numbers, which appear in calculations, but can't be reasonably named, it's OK to leave the numeric values. I'll try to give you an example:
The formula to calculate degrees from radians is
deg = rad * 180° / π
For π we have a constant definition (PI), but is 180 a magic number which deserves a constant definiton?
How should we name it? HUNDREDEIGHTY_DEGREES??
So it's not always reasonable to get rid of numeric constants appearing in code.
But I don't even know why I need it as well as how to get rid of it.
That's probably part ot the task, to find out.
I am currently working on a project to create a game of Mastermind. The user must input 3 colors and the program will compare which are the correct color and in the proper place,which are the correct color but in the wrong place, and which are the wrong color. All seems well except I'm unable to properly compare the info within the randomly generated array with the user filled array. I'm sure I'd have to use a loop to accomplish this.
-Things that I feel may be the issue:
*The information within both arrays are not being stored properly.
*conflicting types.
void gameS() {
int close, right, attempts = 0;
string choice[3],code; // holds user input
const int arrySize = 5;
srand(time(0)); //random numbers
string ranColor[arrySize] = { "R", "B", "W", "Y", "G" }; // possible color options
for (int i = 0; i < arrySize - 2; i++) //generat random colors
{
int rcolor = rand() % arrySize;
code = ranColor[rcolor];
cout << code << endl;
}
while (attempts < 10) {
cout << "You should input your color choices below. Your options are - R : Red, B : Blue, W : White, Y : Yellow, G : Green.\n" << "Please choose 3 for your " << attempts+1 << " attempt.\n" << "******************************************************\n\n";
cout << "\n\nPlease enter the color of the first peg: "; //user input to choice array spot : 1
cin >> choice[0];
cout << "\nPlease enter the color of the second peg: "; //user input to choice array spot : 2
cin >> choice[1];
cout << "\nPlease enter the color of the third peg: "; //user input to choice array spot : 3
cin >> choice[2];
attempts++; // proceeds to next turn/attempt
//checks for correct colors in correct places
for (int i = 0; i < 3; i++)
{
if (code == choice[i])
{
right++;
choice[i] = "X";
}
}
//Determin the number of right colors in the wrong place
for (int i = 0; i < 3; i++)
{
for (int y = 0; y < 3; y++) {
if (code[i] == choice[y]) {
close++;
choice[i] = "Y";
}
}
}
}
}
I receive errors for the following lines:
*'argument':conversion from tim_t to unsigned in' possible loss of data
srand(time(0));
*Using uninitialized memory 'right'
`if (code == choice[i])
{
right++;
choice[i] = "X";
}`
*Using uninitialized memory 'close'
`for (int i = 0; i < 3; i++)
{
for (int y = 0; y < 3; y++) {
if (code == choice[y])
{
close++;
choice[i] = "Y";
}
}
}
*no operator "==" matches these operands.
*Binary '==':o global operator found which takes type 'std::string'(or there is no acceptable conversion)
`for (int y = 0; y < 3; y++) {
if (code[i] == choice[y])
{
close++;
choice[i] = "Y";
}`
Any tips would be appreciated.
From what I can see there is some initialization problems.
First
int close, right, attempts = 0;
Will leave close and right empty, simply initialize them properly
int close = 0, right = 0, attempts = 0;
It looks like you want to use code as an array, but the problem is, it is not initialized as an array
string choice[3],code; // holds user input
A quick fix is
string choice[3],code[3]; // holds user input
Now, where you generate the answer, there is another syntax problem
code = ranColor[rcolor];
since you want to store the answer in the code array, an index must be specified, in this case
code[i] = ranColor[rcolor];
The final problem lies in
//checks for correct colors in correct places
for (int i = 0; i < 3; i++)
{
if (code == choice[i])
{
right++;
choice[i] = "X";
}
}
Since code is an array now, simply change the condition statement to
if (code[i] == choice[i])
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I want to create a 5x5 array of '' with a hashtag in the center instead of '', but only when the user inputs either 'a' or 'b.' On the area I marked "RIGHT HERE" it doesn't work unless its ONLY 'a' / ONLY 'b', so what do I do? Thank you in advance!
#include <iostream>
using namespace std;
int main()
{
while (true){
///Variables:
char array[4][4]; //Playing field 5x5
char direc; //Direction player moves
for (int x = 0; x <=4; x++){
for (int y = 0; y <= 4; y++){
array[x][y] = '_';
if (direc != 'a' || 'b'){ ///RIGHT HERE!
array[2][2] = '#';
}
cout << array[x][y]; //Starts printing Board
if (y == 4){
cout << endl; //Cuts to next line on print if 4 in a column row
}
}
}
cin >> direc;
cin.get();
}
}
Did not check the required logic of your statement or of the other parts of your program, but your marked statement should be written as
(direc != 'a' || direct != 'b')
Your statement (direc != 'a' || 'b') will always evaluate to true, since 'b' as the second operand of the logical or operator || is an integer value > 0 (representing character b in some encoding) and therefore treated as true.
As Neil mentioned in the comment, ur 5x5 field is in fact 4x4, so u are only able to access array[0][0] up to array[3][3], while your X and Y are 4 at some point. You should use this instead:
char array[5][5]
so that u can access your array up to index 4
hope that helps you
#include <iostream>
using namespace std;
int main()
{
///Variables:
char array[5][5]; //Playing field 5x5
char direc; //Direction player moves
char player;
while (true) {
//get direc
cin >> direc;
cout << direc << "\n";
if (direc == 'a' || direc == 'b') { ///RIGHT HERE!
player = '_';
}
else {
player = '#';
}
for (int x = 0; x <= 4; x++) {
for (int y = 0; y <= 4; y++) {
array[x][y] = '_';
if (x == 2 && y == 2) {
array[x][y] = player;
}
cout << array[x][y]; //Starts printing Board
if (y == 4) {
cout << endl; //Cuts to next line on print if 4 in a column row
}
}
}
}
}
EDIT: Posting everything, because it gets really weird.
using namespace std;
int main()
{
int doors = -1;
int jumper = 1;
bool isOpen[100];
string tf;
for(int i = 0 ; i < 100; i++){
isOpen[i] = false;
}
while(jumper < 100){
while(doors < 100){
if(isOpen[doors + jumper] == true){
isOpen[doors + jumper] = false;
}
else{
isOpen[doors + jumper] = true;
}
doors += jumper;
cout << doors << endl;
}
doors = -1;
jumper+=1;
}
for(int i = 0; i < 100; i++){
if(isOpen[i]){
tf = "open";
}
else{
tf = "closed.";
}
cout << "Door " << i << " is " << tf << endl;
}
return 0;
}
So I'm having a very odd problem with this piece of code.
It's supposed to go through an array of 100 items. 0 - 99 by ones then tows then threes, etc. However, after a = 10, it shoots up to 266.
Can anyone tell me why?
Edit:
This problem only happens when the for loop is commented out. When it is left in the code, it does the same thing, but it doesn't happen until 19.
If I comment out the "string tf;" as well, it continues to loop at 99.
This is all based on the doors count.
I'm unsure why either of these should be a factor to the loop that neither are connected to.
According to your description this is what you should do:
for(int adv = 1, i = 0; adv < 100;)
{
// i is array index (your b) -> use it somehow:
doSomething(arr[i]);
i += adv;
if(i >= 100)
{
i = 0;
adv++;
}
}
The (probable) reason you got weird behavior (including the 266 value) is that your code overruns the buffer. When b will be high enough (say 99), you'd write to isOpen[b + a] which will be 100 or higher (100 if a is 1, and that's just the first iteration, later iterations will go much further). If the compiler allocates isOpen before the ints you'll be overwriting them.