Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 6 years ago.
Improve this question
My name is Eric, and I ran into a problem while programming a basic "dungeon crawler" using c++.
The problem is that when the player moves certain spaces to the left or right, there is another player character generated so that there is two on the screen instead of one.
Here is my code:
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string>
using namespace std;
const int columns = 7, rows = 10;
string gridArray[rows][columns];
bool xIsGenerated = false;
bool gISGenerated = false;
int playerX = 0, playerY = 0;
void displayGrid(int rows, int columns){
for(int i = 0; i < columns; i++){
for(int x = 0; x < rows; x++){
cout << gridArray[i][x];
}
cout << endl;
}
cout << gISGenerated << endl;
return;
}
void generatePieces(int rows, int columns){
int tcount = 0;
for(int i = 0; i < rows; i++){
for(int x = 0; x < columns; x++){
srand(time(NULL) + x + i);
int r = rand() % 5;
if(r == 1 && tcount < 4){
gridArray[i][x] = "T ";
tcount++;
}else if(r == 2 && !xIsGenerated){
gridArray[i][x] = "X ";
xIsGenerated = true;
}
}
}
if(!xIsGenerated){
srand(time(NULL)*3);
int r = rand() % rows+1;
int c = rand() % columns+1;
gridArray[r][c] = "X ";
xIsGenerated = true;
}
return;
}
void generatePlayer(int rows, int columns){
if(!gISGenerated){
srand(time(NULL)*3);
int r = rand() % rows+1;
int c = rand() % columns+1;
gridArray[r][c] = "G ";
playerX = r;
playerY = c;
gISGenerated = true;
}
}
void initGrid(int rows, int columns){
for(int i = 0; i < columns; i++){
for(int x = 0; x < rows; x++){
gridArray[i][x] = ". ";
}
}
generatePieces(rows, columns);
generatePlayer(rows, columns);
return;
}
//i is the rows
//x is the columns
void movePlayer(){
char input = 'x';
cin >> input;
if(input == 'w' && playerX != 0){
gridArray[playerX][playerY] = ". ";
gridArray[playerX-1][playerY] = "G ";
playerX--;
}
if(input == 's' && playerX != 6){
gridArray[playerX][playerY] = ". ";
gridArray[playerX+1][playerY] = "G ";
playerX++;
}
if(input == 'a' && playerY != 0){
gridArray[playerX][playerY] = ". ";
gridArray[playerX][playerY-1] = "G ";
playerY--;
}
if(input == 'd' && playerY != 9){
gridArray[playerX][playerY] = ". ";
gridArray[playerX][playerY+1] = "G ";
playerY++;
}
system("CLS");
displayGrid(rows, columns);
cout << playerX << ": " << playerY << endl;
}
void firstTime(){
displayGrid(rows, columns);
cout << playerX << ": " << playerY << endl;
return;
}
int main()
{
initGrid(rows,columns);
firstTime();
while(true){
movePlayer();
}
return 0;
}
Quick explanation of code:
A multidimensional array will serve as the graphic for displaying what is going on. This array starting with the function "initGrid" will print out ". " strings in the array and on the screen
The Generate Pieces function takes that array filled with ". " strings, and using a random number generator, it places "T " strings and 1 "X " string. This "X " will be the goal while the T's will be traps that kill the player.
Generate Player does the same thing, but instead places only 1 "G " string. This is the player.
After initGrid is called, then inside of the main function is the "firstTime" function, nothing complex, just displays data to the screen.
Then lastly, I have a while loop that calls the function "movePlayer", using the same array, based on what the user inputs, it will move the "G " string accordingly and replace the last location of the g string with an empty ". " string.
I have tried to return the location of the second G string and once I did that I tried to replace it with a ". " string, but it failed as the code didn't remove the second one, and once the second one was out of the array (the second g character moves corresponding to the first g character) the first G character got removed.
I am drawing a blank here as to what I should do next, it seemed to be a simple problem at first, but it is giving me a run for it's money.
Thanks for reading, and I hope to get an answer soon to my problem.
I ran your code with asan and ubsan which told me you have an out of bounds access in line 23 cout << gridArray[i][x]; where you access gridArray[8] which doesn't exist.
Looks like you mixed up rows and columns. I recommend you use sanitizers too.
Related
I'm writing a program to simulate Left Right Center. If you're not familiar, the game involves 3 dice with 1 side "L", 1 side "R", 1 side "C", and 3 sides dots. Everyone starts with $3. If you roll an "L", you pass a dollar to the left. If you roll an "R", you pass a dollar to the right. If you roll a "C", you put a dollar in the center. If you roll a dot, you take no action. Play then passes to the left. Play continues until only 1 player has money remaining, and that player wins everything.
I got the program operating correctly, except for one strange thing. When I run it as below, it runs fine, usually taking 70-150 turns to complete. When I comment out the lines
cout << "In gameOver(). Number of brokeJamokes: " << brokeJamokes;
cin.ignore();
the program takes hundreds of thousands (or millions) of turns to complete. Why would a simple output change that?
Full code follows:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int player[10] = {0};
int bank[10] = {0};
int rollDie() {
srand(time(NULL));
int randNum = rand()%6+1;
//cout << "In rollDie(), die roll is " << randNum << "\n";
//cin.ignore();
return randNum;
}
int distributeCash(int roll, int playerNum) {
if(roll == 1) { //pass left
bank[playerNum]--;
/* if active player is player 10 (player[9]), we need to pass to player 1 (player[0])
instead of the nonexistant player 11, so we change the array value to -1 */
if(playerNum == 9) {playerNum = -1; }
bank[playerNum + 1]++;
return 0;
}
if(roll == 2) { //pass right
bank[playerNum]--;
/* if active player is player 1 (player[0]), we need to pass to player 10 (player[9])
instead of the nonexistant player 0, so we change the array value to 11 */
if(playerNum == 0) {playerNum = 10;}
bank[playerNum - 1]++;
return 0;
}
if(roll == 3) { //pass to center
bank[playerNum]--;
return 0;
}
else {
return 0;
}
return 0;
}
int gameOver() {
int brokeJamokes = 0;
for(int i = 0; i < 10; i++) {
if(bank[i] == 0) { brokeJamokes++; }
}
cout << "In gameOver(). Number of brokeJamokes: " << brokeJamokes;
cin.ignore();
if(brokeJamokes==9) {return 1;}
else return 0;
}
void showWinner() {
for(int i = 0; i < 10; i++) {
if(bank[i] != 0) {
cout << "Player " << (i+1) << " is the winner!\n";
cin.ignore();
return;
}
}
}
int main()
{
int roll[3] = {0};
for(int x = 1; x < 10; x++) { //initialize all banks to 3 except test player (player 1)
bank[x] = 3;
}
bank[0] = 3; //test player bank initialization
int turnCount = 0;
while(!gameOver()){
for(int i = 0; i < 10; i++) {
if(gameOver()) {break;}
for(int j = 0; j < 3; j++) {
roll[j] = rollDie();
if(bank[i] != 0) {
distributeCash(roll[j], i);
}
}
/* cout << "After player " << (i + 1) << "'s roll: \n";
for(int l = 0; l < 10; l++) {
cout << "Player " << (l + 1) << " $" << bank[l] << "\n";
}
cin.ignore();
*/
turnCount++;}
}
showWinner();
cout << "Number of turns: " << turnCount << "\n";
cout << "Game over!\n";
}
As melpomene stated you repeatedly call srand, setting the same seed (as I think it uses time with a second resolution). Therefore you will get thousands or millions of 'random' numbers in a row of the same value until the time changes. Think what happens if everyone gets the same die roll, the game will never end.
When you have the cout line, it will slow the program considerably, so get less of the same roll in a row from setting srand to the same value.
To fix it move the call to srand to the main function so its only called once.
I am working on a program that emulates conways game of life, and it works perfectly with the preset dimensions. However, once i try to use the dynamic dimensions as seen in option e, i start having problems. The main problem is in the "life" function which iterates throughout the array and decides if it should bring to life a cell. I have been debugging for a while and it i enter the dimensions as 50*40, it iterates until 61, 1. This should technically work but it just breaks everytime. Keep in mind that I add 12 to each dimension to account for the buffer zone I put around the edges. Technically it should work then right? If you have any suggestions I would really appreciate it!
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <new> // i havent used this one yet
#include <cmath>
using namespace std;
// REMEMBER: The outside of the array is 6 more than what we show so that nothing interferes
//also that it goes y,x and that x is going to be bigger so that we get a rectange
//we use the copy function to copy an array from eachother, either the current one to the temp one or
//vise versa. This is so that we can alter the cells one step at a time without affecting everything else.
void copy(int **array1, int **array2, int o, int p)
{
for(int j = 0; j < o; j++)
{
for(int i = 0; i < p; i++)
array2[j][i] = array1[j][i];
}
} // the second array sent is assigned the first array sent!
//this array will initialize our arrays so that we can use them later
int** init(int n, int m)
{
int **array;
array = new int*[m]; // x
array = new int*[n]; // y
for (int q=0; q < n; q++)
{
array[q] = new int[n];
for (int w=0; w < m; w++)
{
array[w] = new int[m];
}
}
return array;
}
void populate(int o, int p, int** board){ // THIS FUNCTION HASN'T BEEN USED YET
for(int i=0; i < p; i++)
{
for(int j=0; j < o; j++) // It was in a in-class demo but i dont think i need it
{
board[i][j] = pow(i, j);
}
}
}
//The life function looks at the pieces around the cell and figures out what happens next.
// Probably the most important in the entire program, feast your eyes!
void life(int **array, int o, int p)
{
//Copies the main array to a temp array so changes can be made without affecting anyone else
int **temp;
temp = init(o, p);
copy(array, temp, o, p);
for(int j = 1; j < o; j++)
{
for(int i = 1; i < p; i++)
{
// checks all 8 cells surrounding it
int count = 0;
cout << " j is " << j << " and i is " << i << endl;
// cout << array[j][i]; // DEBUGGING
count =
array[j-1][i] + array[j-1][i-1] +
array[j][i-1] + array[j+1][i-1] +
array[j+1][i] + array[j+1][i+1] +
array[j][i+1] + array[j-1][i+1];
//cell dies.
if(count < 2 || count > 3)
{
temp[j][i] = 0;
}
//nothing happens.
if(count == 2)
{
temp[j][i] = array[j][i];
}
//now the cell will be born, or if it already is alive then it stays that way.
if(count == 3)
{
temp[j][i] = 1;
}
}
}
//Copies the temp array back to the main array.
copy(temp, array, o, p);
}
//This function prints the 40 x 50 part of the array, a 1 means that there will be a cell there,
//otherwise it will just be an empty space.
void print(int **array, int o, int p)
{
// WE ONLY CHECK WHAT WE SEE, WHICH IS 6 LESS THAN THE ARRAY!!!
for(int j = 6; (j < (o-6)); j++)
{
for(int i = 6; (i < (p-6)); i++)
{
if(array[j][i] == 1 )
cout << '*';
else
cout << '.';
}
cout << endl;
}
}
//I read somewhere it would be a good idea to make sure to end the program early if it somehow
//became stable by itself early. so this compares the old array with the new one to check if they
//are the same. This commonly occurs if a glider runs off the screen for example.
bool compare(int **array1, int **array2,int o,int p)
{
int counter = 0;
for(int j = 0; j < o; j++)
{
for(int i = 0; i < p; i++)
{
if(array1[j][i]==array2[j][i])
counter++;
}
}
if(counter == o*p)
return true;
else
return false;
}
int main()
{
int o= 52, p=62;
int **firstgen;
int **next;
int **backup;
// 40 + 12, 50 + 12
int x, y;
char starty;
char again;
char cont;
bool comparison;
//Here is where we initialize our arrays
firstgen = init(o,p);
next = init(o,p);
backup = init(o,p);
cout << endl << "Welcome to John Conway's Game of Life." << endl;
//This loop is for if we are still simulating, don't get confused!
do
{
//this loop checks for inputs.
do
{
menu: //this is a goto we use for if we change dimensions
x = 0, y = 0;
//now we get the menu
cout << endl << "--- Choose an option Below ---" << endl;
cout << "(a) Glider" << endl;
cout << "(b) Gosper Gilder gun" << endl;
cout << "(c) R Pentomino Pattern" << endl;
cout << "(d) Oscillator" << endl;
cout << "(e) Change the dimensions (it defaults to (50*40)" << endl;
cin >> starty;
}while(starty != 'a' && starty != 'b' && starty != 'c' && starty != 'd' && starty != 'e');
int i = 0;
//we need to assign firstgen in this area
//choose a glider position
if (starty == 'a'){
x= 0, y= 0;
cout << " X dimension: ";
cin >> x;
cout << " Y dimension: ";
cin >> y;
if (x < 0 || x > p || y < 0 || y > o){
cout << endl << "you entered invalid dimensions" << endl;
goto menu;
}
x = x+6; //we add 6 because there are six spots to the left that aren't shown we need to account for
y = y+6;
//creates the glider
firstgen[y][x] = 1;
firstgen[y][x+1] = 1;
firstgen[y][x+2] = 1;
firstgen[y-1][x] = 1;
firstgen[y-2][x+1] = 1;
}
else if (starty == 'b'){
x= 0, y= 0;
cout << "Your dimensions are based on the farthest left point" << endl;
cout << " X dimension: ";
cin >> x;
cout << " Y dimension: ";
cin >> y;
if (x < 0 || x > p || y < 0 || y > o){
cout << endl << "you entered invalid dimensions" << endl;
goto menu;
}
//this is because we have the buffer zone of 6
x = x+6;
y = y+6;
//Gosper gun
//box on left
firstgen[y][x] = 1;
firstgen[y][x+1] = 1;
firstgen[y+1][x] = 1;
firstgen[y+1][x+1] = 1;
//left circle starting in top of the left curve (flat part)
firstgen[y][x+10] = 1;
firstgen[y-1][x+11] = 1;
firstgen[y-2][x+12] = 1;
firstgen[y-2][x+13] = 1;
firstgen[y+1][x+10] = 1;
firstgen[y+2][x+10] = 1;
firstgen[y+3][x+11] = 1;
firstgen[y+4][x+12] = 1;
firstgen[y+4][x+13] = 1;
//dot in middle
firstgen[y+1][x+14] = 1;
//arrow thing on the right
firstgen[y-1][x+15] = 1;
firstgen[y][x+16] = 1;
firstgen[y+1][x+16] = 1;
firstgen[y+1][x+17] = 1;
firstgen[y+2][x+16] = 1;
firstgen[y+3][x+15] = 1;
//boomerang bit on the far right section
firstgen[y][x+20] = 1;
firstgen[y][x+21] = 1;
firstgen[y-1][x+20] = 1;
firstgen[y-1][x+21] = 1;
firstgen[y-2][x+20] = 1;
firstgen[y-2][x+21] = 1;
firstgen[y-3][x+22] = 1;
firstgen[y-3][x+24] = 1;
firstgen[y-4][x+24] = 1;
firstgen[y+1][x+22] = 1;
firstgen[y+1][x+24] = 1;
firstgen[y+2][x+24] = 1;
//tiny box on farthest right, almost done!
firstgen[y-1][x+34] = 1;
firstgen[y-1][x+35] = 1;
firstgen[y-2][x+34] = 1;
firstgen[y-2][x+35] = 1;
}
else if (starty == 'c')
{
x= 0, y= 0;
cout << "Your dimensions are based on the farthest left point" << endl;
cout << " X dimension: ";
cin >> x;
cout << " Y dimension: ";
cin >> y;
if (x < 0 || x > p || y < 0 || y > o){
cout << endl << "you entered invalid dimensions" << endl;
goto menu;
}
x = x+6;
y = y+6;
//creates R Pentamino pattern
firstgen[y][x] = 1;
firstgen[y][x+1] = 1;
firstgen[y+1][x+1] = 1;
firstgen[y-1][x+1] = 1;
firstgen[y-1][x+2] = 1;
}
// creates the simple oscillator
else if (starty == 'd')
{
x= 0, y= 0;
cout << "Your dimensions are based on the top of the oscillator" << endl;
cout << " X dimension: ";
cin >> x;
cout << " Y dimension: ";
cin >> y;
if (x < 0 || x > p || y < 0 || y > o){
cout << endl << "you entered invalid dimensions" << endl;
goto menu;
}
x = x+6;
y = y+6;
firstgen[y][x] = 1;
firstgen[y+1][x] = 1;
firstgen[y+2][x] = 1;
}
// allows you to choose your dimensions
else if (starty == 'e')
{
o= 0, p= 0;
x= 0, y= 0;
cout << "choose the height and width of your field, between 0 and 100" << endl;
cout << " X dimension: ";
cin >> x;
cout << " Y dimension: ";
cin >> y;
if (x < 0 || x > 100 || y < 0 || y > 100){
cout << endl << "Please keep dimensions between 0 and 100" << endl;
goto menu;
}
// the problem is that it is adding my x dimension and my placement choice together and then
// starts to run the program, which threadbreaks. I need to find out why these two values are
// adding together and fix it
x = x+12;
y = y+12; // plus twelve so that we have 6 around all sides
p = x;
o = y;
firstgen = init(o,p);
next = init(o,p);
backup = init(o,p);
// is this part below necessary?
//firstgen[o][p];
// next[o][p];
// backup[o][p];
// idk
// cout << "y value is: " << o << " and the x value is " << p << endl; // debugging
goto menu;
}
//Loop that does the simulation.
do
{
//Prints the generation. If i == 0, the firstgen array is copied to the
//next array, and is printed before any functions act upon it.
cout << endl << "Generation " << i << ":" << endl << endl;
//Initializes the arrays by copying the firstgen array to the next array.
if(i == 0)
copy(firstgen, next, o, p);
//this stuff below happens in every cycle
cout << "the x/p value is" << p << "and the y/o value is " << o << endl;
copy(next, backup, o, p);
print(next, o, p);
life(next, o, p);
i++;
//Pauses the system .2 seconds so that it doesn't flash past you super fast and you
// can't appreciate its beauty
system("sleep .2");
//Checks whether the generation is a multiple of 100 to ask
//the user if they want to continue
if(i % 100 == 1 && i != 1)
{
cout << endl;
//Loop to check for proper inputs.
do
{
cout << "Continue? (y or n): ";
cin >> cont;
}while(cont != 'y' && cont != 'n');
if(cont == 'n')
break;
}
//Compares the current generation with a backup generation.
//The idea is that if it is the same with the backup generation then
//something boring is going on or smething went wrong. It will end if that
//is the case.
comparison = compare(next, backup, o, p);
if(comparison == false)
// system("clear");
//cout << string( 10, '\n' );
if(comparison == true)
cout << endl;
}while(comparison == false);
//Loop to check if we want to keep going.
do
{
cout << "Run another Simulation? (y or n): ";
cin >> again;
}
while(again != 'y' && again != 'n');
//this is where we clean out all our firstgen values
//i used to have this at the top but didn't really need it
for(int y = 0; y < o; y++)
{
for(int x = 0; x < p; x++)
{
firstgen[y][x] = 0;
}
}
}
while(again == 'y');
return 0;
}
I figured it out!
The thing to take away from this is to make sure that your initiation function creates the array with the same size as the one you will be accessing. I was trying to get values from array[52][1] which didn't exist because in my init function i only had the for loop running while n < o, which means it didn't create the 52nd row. what a relief!
I'm almost done with my Bulls and Cows project however if I enter a word or a sequence of numbers with an alphabet or number repeating, the 'cow' portion of the code messes up. As an example: consider the following
Enter something that you want someone to guess: cool
Time to guess! The code is of size 4. book
COWS: 0 BULLS: 2
ozzo
COWS: 4 BULLS: 0
As you can see, after entering "ozzo", the cow value should be 2, not 4.
How can I fix this without having to change the entire code?
for (size_t i = 0; i != startg.getSize(); ++i){
if (guess[i] == origWord[i]){
bullCtr++;
} else {
for (size_t j = 0; j != startg.getSize(); ++j){
if (origWord[i] == guess[j]){
cowCtr++;
}
}
}
}
Code after applying fix:
for (size_t i = 0; i != startg.getSize(); ++i){
if (guess[i] == origWord[i]){
bullCtr++;
} else {
for (size_t j = 0; j != startg.getSize(); ++j){
if (origWord[i] == guess[j]){
origWord[i] = 'X';
cowCtr++;
}
}
}
origWord = origWordcpy;
}
Your cow checking is problematic.
What I would do for the sake of ease (not exactly) is this (I'm talking about the else statement only):
for(unsigned int j = 0 ; j != startg.getSize() ; j++)
{
if(origWord[i] == guess[j])
{
origWord[i] = 1; //Just assigning a certain value there to mark that we've already did something with it
cowCtr++;
}
}
And that should do the work.
EDIT:
You should obviously have a temporary string instead of origWord because changing it would affect the next iteration of the outer loop (getting the guess and comparing again) - I only showed you the way.
Here is one possible implementation of the Bulls & Cows game:
// used constants; numbers to be guessed
const int first_num = 2;
const int second_num = 4;
const int third_num = 1;
const int forth_num = 5;
int main(){
// vector holding the values to be guessed
vector<int>gamenum(4);
gamenum[0] = first_num;
gamenum[1] = second_num;
gamenum[2] = third_num;
gamenum[3] = forth_num;
// prompt message; input cycle till perfect guess (4 bulls)
int bulls = 0;
while (!(bulls == 4)){
// vector holding the guesses
vector<int>guesses;
// vector input values
int guess1(0), guess2(0), guess3(0), guess4(0);
cout << "\t\tPlay the game ""Bulls and Cows\n""" << endl;
cout << "Enter a set of four numbers, separated by whitespace space: ";
cin >> guess1 >> guess2 >> guess3 >> guess4;
guesses.push_back(guess1);
guesses.push_back(guess2);
guesses.push_back(guess3);
guesses.push_back(guess4);
// input confirmation; show your guess
cout << "\nYour guess is: ";
for (int i = 0; i < guesses.size(); ++i){
cout << guesses[i];
}
// bulls criterion
for (int j = 0; j < guesses.size(); ++j){
if (guesses[j] == gamenum[j]) ++bulls;
}
// cows criterion
int cows = 0;
for (int gue = 0; gue < guesses.size(); ++gue){
for (int gam = 0; gam < gamenum.size(); ++gam){
if (guesses[gue] == gamenum[gam] && gue != gam) ++cows;
}
}
// print result
if (bulls < 4){
cout << "\nBulls: " << bulls << " and Cows: " << cows <<endl;
cout << "\n\n\n" << endl;
// reset bulls
bulls = 0;
}
// empty guesses vector
guesses.clear();
// reset cows
cows = 0;
}
// print success
cout << "\nPerfect Guess!" << endl;
cout << "Bulls: " << bulls << endl;
cout << "\n\n\n" << endl;
keep_window_open();
return 0;
}
Not optimal by any means, rudimentary, but working. You can use it as benchmark.
Closed. This question needs debugging details. It is not currently accepting answers.
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.
Closed 8 years ago.
Improve this question
I've been looking over my code for awhile now, and I can't figure out why this error keeps coming up. It's probably something really simple, but I just can't figure it out...
"Unhandled exception at 0x00FB59E6 in program.exe: 0xC0000005: Access violation writing location 0x00000009."
It happens on the third time of repeating the program
main.cpp
#include <iostream>
#include <string>
#include "functions.h"
using namespace std;
int main(){
RandomArray();
MinMaxArray();
SortedArrays();
cout << "\n\nWould you like to re-run? (Y/N): ";
cin >> y;
if (y == "Y" || y == "y"){
system("CLS");
main();
}else{
system("PAUSE");
}
return 0;
}
functions.h
#include <iostream>
#include <time.h>
using namespace std;
int array[50], used[50], sortedArray[50];
int buildSort = 1, genNum, mx = 0, mn = 100;
bool x;
string y;
int RandomArray(){
srand(time(0));
for(int a = 0; a < 50; a++){ //array generator
do{
genNum = (1+rand()%100); //generate a # between 1-100
x = false;
for(int b = 0; b < 50; b++){
if(genNum == used[b]){ //if the number is already used...
x = true;
}
}
}while(x == true);
used[a] = genNum;
array[a] = genNum;
}
cout << "Random array: " << endl;
for(int c = 0; c < 50; c++){
cout << array[c] << " "; //display the random array
}
cout << endl << endl;
return 0;
}
int MinMaxArray(){
for(int d = 0; d < 50; d++){ //for each number in the array
if(array[d] > mx){ //check to see if each number is greater than mx
mx = array[d]; //the max equals that number it picked out
}
if(array[d] < mn){ //check to see if theres a number is less than mn
mn = array[d]; //the minimum equals that number it picked out
}
}
cout << "Maximum: " << mx << endl; //display the max
cout << "Minimum: " << mn << endl << endl; //display the min
return 0;
}
int SortedArrays(){
sortedArray[0] = mn;
for(int e = mn + 1; e <= mx; e++){ //goes through 1-100 and adds each number to another array in order
for(int f = 0; f < 50; f++){
if(array[f] == e){
sortedArray[buildSort] = array[f];
buildSort++;
}
}
}
cout << "Sorted array: " << endl;
for(int g = 0; g < 50; g++){
cout << sortedArray[g] << " "; //display sorted from lowest to highest
}
cout << endl << endl;
cout << "Reverse sorted: " << endl;
for(int h = 49; h >= 0; h--){
cout << sortedArray[h] << " "; //display sorted from highest to lowest
}
return 0;
}
You are using some variables that you are initializing just the 1st time: buildSort, mx and mn;
Add at the beginning of your main something like
int main()
{
buildSort = 1;
mx = 0;
mn = 100;
RandomArray();
MinMaxArray();
SortedArrays();
}
And try again.
Your buildSort makes you run out of the array.
Just a suggestion: try to write your code better! Is almost unreadable!!!
Don't use global variable (at least not like this!)
There is not need to use system function for basic features like CLS and PAUSE, you may use clrscr() or getch() (or appropriate functions)
Don't recurse main - it it not meant for this purpose. Though no compiler will complain, it is bad approach.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I'm having difficulty commenting on my code for a blackjack app for c++. I have coded it but now I am confused as to what to put in for comments, my instructor is frugal when it comes to commenting.
Thanks for any and all help! :)
here is my code:
#include <iostream> // in/out for form
#include <ctime> // uses time for randomizing
#include <Windows.h> //
using namespace std; // prevents redundancey of ::STD
char enter[1]; //
int hand[52] = {}, dealer[52]; // array of 52 for 52 cards that holds zero
int GetScore(int param) // function prototype that calls getscore
{
int score = 0; //
int temp[52]; //
if(param == 0) for(int i = 0; i < 52; i++) temp[i] = hand[i]; //
if(param == 1) for(int i = 0; i < 52; i++) temp[i] = dealer[i]; //
for(int i = 0; i < 52; i++) //
{
if(temp[i] == 0) break; //
if(temp[i] != 11)
{
score += temp[i];
}
}
for(int i = 0; i < 52; i++) // simple loop to ....
{
if(temp[i] == 0) break;
if(temp[i] == 11)
{
if(temp[i] + score <= 21)
{
score += 11;
}
else
{
score += 1;
}
}
}
return score;
}
void ShowDealersHand(int show) //
{
cout << "\n Dealer's hand: "; //
if(show == 1) //
{
if(dealer[0] == 11)
{
cout << "A [Not Shown]";
}
else
{
cout << dealer[0] << " [Not Shown]";
}
}
else
{
for(int i = 0; i < 52; i++)
{
if(dealer[i] == 0) break;
if(dealer[i] == 11)
{
cout << "A ";
}
else
{
cout << dealer[i] << " ";
}
}
}
}
void Blackjack()
{
for(int i = 0; i < 2; i++) //
{
int num, temp;
if(hand[0] == 0) temp = 0;
else temp = 1;
num = rand() % 10 + 2;
hand[temp] = num;
num = rand() % 10 + 2;
dealer[temp] = num;
}
ShowDealersHand(1); //
cout << endl << endl << " Your hand: "; //
for(int i = 0; i < 52; i++) //
{
if(hand[i] == 0) break;
if(hand[i] == 11)
{
cout << "A ";
}
else
{
cout << hand[i] << " ";
}
}
cout << endl << " Your score: " << GetScore(0) << endl << endl;
while(GetScore(0) <= 21)
{
cout << " Hit(h) or stand(s): ";
cin >> enter;
if(strcmp(enter, "h") == 0)
{
int card = rand() % 10 + 2;
for(int i = 0; i < 52; i++)
{
if(hand[i] == 0)
{
hand[i] = card;
break;
}
}
cout << " Your hand: ";
for(int i = 0; i < 52; i++)
{
if(hand[i] == 0) break;
if(hand[i] == 11)
{
cout << "A ";
}
else
{
cout << hand[i] << " ";
}
}
cout << endl << " Your score: " << GetScore(0) << endl << endl;
if(GetScore(0) > 21)
{
cout << " - ..BUST.. -" << endl ;
cout << "\n - !!House Wins!! -";
goto end;
break;
}
}
else if(strcmp(enter, "s") == 0)
{
cout << endl;
break;
}
system("pause > nul");
}
Sleep(2000);
ShowDealersHand(0);
cout << endl << " Dealer score: " << GetScore(1) << endl << endl;
if(GetScore(1) < GetScore(0))
{
while(GetScore(1) < 17 && GetScore(0) <= 21)
{
Sleep(2000);
int card = rand() % 10 + 2;
for(int i = 0; i < 52; i++)
{
if(dealer[i] == 0)
{
dealer[i] = card;
break;
}
}
cout << " Dealer's hand: ";
for(int i = 0; i < 52; i++)
{
if(dealer[i] == 0) break;
if(dealer[i] == 11)
{
cout << "A ";
}
else
{
cout << dealer[i] << " ";
}
}
cout << endl << " Dealer score: " << GetScore(1) << endl << endl;
if(GetScore(1) >= GetScore(0)) break;
}
}
end:
if(GetScore(1) > GetScore(0) && GetScore(1) <= 21)
{
cout << " - !!House Wins!! -";
}
else if(GetScore(1) == GetScore(0) && GetScore(0) <= 21)
{
cout << " * Tie * - !!House Wins!! -";
}
else if(GetScore(0) <= 21)
{
cout << " - !!!You win!!! -"; // outputs if you win
}
system("pause > nul");
system("cls");
}
void main() // no return on main for form to start
{
srand((unsigned int)time(0)); // randomizer unasigned initializer
cout << " *-*-*-*-*Zachattack's Blackjack*-*-*-*-*" << endl << endl; // Name of program outputs to user
Blackjack();
}
As they are, you comments are useless. Take, for example, this:
int hand[52] = {}, dealer[52]; // array of 52 for 52 cards that holds zero
Anyone that uses C/C++ is expected to know what that line is doing, without having to read the comment.
Instead of commenting what your code does ("this line declares an int"), comment why the code does what it does (what you were thinking when you wrote that code), or, if the algorithm is complicated, comment on how it does something, or document how to use your functions.
For example, your GetScore function takes has a parameter called param. I've no idea what values I am expected to give to param, so you should explain it: "when param is 1, this happens, when it is 0, that happens".
Another example: in your code you have a line Sleep(2000). Why did you use that function? Explain it in a comment:
// Sleep 2 seconds to make the game more exciting
Sleep(2000);
Always assume that the person reading your code knows how to use the language. Never assume that the person reading your code is able to understand your way of thinking about a certain problem.
Comments should explain why, not what.
So your comment for using namespace std; is unnecessary, because any C++ programmer will already know what the using keyword does.
However, for the GetScore() function, you've omitted to give the rules for totalling the score.
The comments should add value, not just duplicate things that are obvious from even a cursory look at the code.
Assume the person reading the code is familiar with the programming environment, but wasn't party to what was going on in your mind as you wrote it.
Here's an example I sometimes use - a piece of code with useless comments (can you work out what is going on here, and why?):
// Is the new selection end above the selection start?
if newSelEnd.Line < FSelection.SelStart.Line then
begin
// Is the selection start at the left margin and above the selection end?
if (FSelection.SelStart.Line < FSelection.SelEnd.Line) and
(FSelection.SelStart.Column = 0) then
begin
// Move the selection start down one line
Inc(FSelection.SelStart.Line);
And with helpful comments:
if newSelEnd.Line < FSelection.SelStart.Line then
begin
// The new selection end is above the selection start, so will become the
// top of the new selection.
if (FSelection.SelStart.Line < FSelection.SelEnd.Line) and
(FSelection.SelStart.Column = 0) then
begin
// The start of the selection was at the top of the old selection and the
// new line is above this, so the selection is about to change direction.
// Since the start column is 0 we assume the original selection was an
// entire line, so we keep the original line selected by moving the start
// position down one line.
Inc(FSelection.SelStart.Line);
Function/method purpose with parameters purposes
Magic numbers
Those are my most important rules about commenting. Optional is "why am I iterating/what am I looking for" about loops. Magic numbers is every declaration/condition that uses const values like GetScore(0) <= 21, or hand[52].
Those are places that should be commented even for yourself... It feels realy good when you look at your code after year or more and still read it without any problem.
Apart from the other answers, often, it is a good idea to get rid of a comment by replacing it with a named function:
// Find top-scorers:
for (Iter it=scorers.begin(), end=scorers.end(); it!=end; ++it) {
...
{
top.push_back (*it);
}
}
Instead, do:
const std::vector<Scorer> top = find_top_scorers (scorers.begin(),
scorers.end());
This decreases miss-maintenance (comments are not enforced and may get out-of-date) and reusability. Personally, I always endeavour for commentless code, as I am sick of out-of-date comments, when possible and sane.
Of course, in the example above, you should probably use std::partial_sort, std::partition or std::stable_partition.
Also, magic numbers should be replaced by constants instead, with the same argumentation about miss-maintenance and reusability:
const float x = radius * 3.14159...; // radius * pi
const float pi = 3.14159...,
x = radius * pi;