I have a class "CardT" the contains a suit and number stored by an enum value. For the use of solitaire i create a deck of 52 of these cards with each value. I also have a "tableau" class that stores a set of these cards for the solitaire tableau, my board class contains an array of 8 of these. After placing the values in the array and printing to check for correctness, it gives a correct output. But if i then call another function right after that prints the exact same thing, i get very different values.
int main(){
Board b;
b.setUp(); //setUp deck and add to tableau arrays
b.printTab(4); //print the fourth one again
}
Where deck gets setup
void Board::setUp(){
//here i setup all 52
CardT deck[52];
int c = 0;
for (int i = 0; i <= 3; i++)
for (int j = 1; j <=13;j++){
deck[c] = CardT(static_cast<CardSuit>(i),static_cast<CardNum>(j));
c++;
}
//shuffle
std::random_shuffle(&deck[0],&deck[52]);
CardT tabls[8][13];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 8; j++)
tabls[i][j] = deck[j + i*8]; //the first 4 piles that contain 8 cards
for (int i = 4; i < 8; i++)
for (int j = 0; j < 7;j++)
tabls[i][j] = deck[j + i*8]; //last four with seven
for (int i = 0; i < 4; i++)
this->tableauPiles[i] = TableauPileT(tabls[i],8); //place first four, (second param is size)
for (int i = 4; i < 8; i++)
this->tableauPiles[i] = TableauPileT(tabls[i],7); //place second four
for (int i = 0; i < 4;i++)
this->foundationPiles[i] = FoundationPileT(); //just intialize
//FOR testing
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
//printed twice for assurance, both print as expected
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,-,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
}
Heres where i then print the exact same thing again:
void Board::printTab(int i){
for (int j = 0; j < 13; j++){
if (this->tableauPiles[4].cardAtIndex(j)){
std::cout << this->tableauPiles[4].getCardByIndex(j).getNum() << ",,Third,," << this->tableauPiles[4].getCardByIndex(j).getSuit() << std::endl;
}
}
}
The header for the board
#ifndef BOARD_H
#define BOARD_H
class Board{
private:
CardT freeCells[4];
bool freeCellsOpen[4] = {false,false,false,false};
FoundationPileT foundationPiles[4];
TableauPileT tableauPiles[8];
int cardPosition(CardNum n, CardSuit s);
int emptyFreeCell();
public:
Board();
void setUp();
void moveToFreeCell(CardNum n, CardSuit s);
void moveToTableau(CardNum n, CardSuit s, int tableau);
void moveToFoundation(CardNum n, CardSuit s);
void printBoard();
void printTab(int i);
};
#endif
And finally this is then the output im given
1,,,,1
12,,,,2
4,,,,0
4,,,,1
4,,,,2
5,,,,3
10,,,,0
1,,-,,1
12,,-,,2
4,,-,,0
4,,-,,1
4,,-,,2
5,,-,,3
10,,-,,0
1,,Third,,1
0,,Third,,1
0,,Third,,0
32545,,Third,,1284192187
0,,Third,,10
32767,,Third,,1922833024
0,,Third,,0
The printed values are stored as enum.
Clearly changed between print statements, very new to c++ but have c experience among others. Any help is greatly appreciated as im going out of my mind.
Also im printing the 4th pile, i believe the 0-3 pile all print correctly, just 4+ are getting messed.
Also of note, the large unexpected values are changing between executions, rest stay constant.
Your card tables (CardT tabls[8][13];) are declared on the stack on your Board::setUp() method.
You then store pointers to these in your TableauPileT objects.
This works fine for your debug code because they are still on the stack,
but at the time you call the printTab function they have been deallocated.
So you're just reading whatever is left over in memory at that point, meaning you're getting undefined behaviour.
2nd loop after shuffle: why do you multiply i by 8 while the pile is just 6 cards? Obviously going out of array bounds. Should be [j+4+i*6]. By the way, the first 4 piles are only 7 cards long and multiplication of i by 8 is wrong. In those table initiating loops, j should be less than 7 and 6 respectively instead of 8 and 7.
Related
This question already has answers here:
srand() — why call it only once?
(7 answers)
Closed 4 years ago.
I am having trouble with shuffling a deck of cards in C++.
I have a deck of cards class. Within the class I have a vector of objects, which are the cards within the deck, and I am trying to shuffle the elements within the vector to shuffle the cards. However, the function I wrote to do it appears to be just shifting everything over every iteration instead of swapping it with another random element within the vector. I'm sure its something really simple and stupid that I am missing, but I just haven't been able to figure it out yet. Any help would be greatly appreciated.
Thanks.
void shuffle(int seed = 0)
{
for (int i = 0; i < 100; i += 1)
{
for (unsigned int i = 0; i < deck.size(); i++)
{
card *swap = deck[i];
srand(time(NULL) + seed);
int temp = rand() % 52;
deck[i] = deck[temp];
deck[temp] = swap;
}
cout << "shuffled deck: ";
for (unsigned int i = 0; i < deck.size(); i++)
cout << deck[i]->compare() << " ";
cout << endl;
}
}
This is being called within a probability function I made, inside a loop. The seed for the shuffle function is the iteration of the loop.
This is a sample of part of the output in one iteration
Initialize your RNG just once, for example in your main() function
srand(time(NULL));
Then one of simplest methods of shuffling is just swap each item from the end to the beginning with a random element from those preceding it. Note the item to swap can be the same to be swapped – this way the item can also stay where it already is.
void shuffle()
{
for (int i = 0; i < 100; i ++)
{
for (unsigned int n = deck.size(); n > 1; --n)
{
unsigned swapPosition = rand() % n;
card *swap = deck[n-1];
deck[n-1] = deck[swapPosition];
deck[swapPosition] = swap;
}
cout << "shuffled deck: ";
for (unsigned int n = 0; n < deck.size(); n++)
cout << deck[n]->compare() << " ";
cout << endl;
}
}
Disclaimer: I know that parallel arrays are awful and should be avoided and that selection sort is not the most efficient sort, but in this case that's the way the boss man wants it done. I have looked at a lot of different websites and none that really seem to nail down an answer. Also, it is probably good to point out that I am new to C++ and only know fairly basic coding and debugging.
I have two simple parallel arrays and am trying to design a simple selection sort that sorts one of the arrays, and then swaps the elements in the second array accordingly. I have the selection sort part working, but it does not seem to swap the elements in my second array correctly.
Here is what my output looks like:
1 (jibberish)
2 (jibberish)
3 (jibberish)
4 (jibberish)
5 (jibberish)
Where I have (jibberish) the console does not form any identifiable letter, just odd shapes (if it's helpful, the last element that is output is a heart).
Here's what it is supposed to look like:
1 a
2 b
3 c
4 d
5 e
Now I realize that I could easily run a selection sort on the second array in this scenario, but my point is to get the second array to swap elements respective to what the selection sort does to the first array.
Is there any way to keep these arrays lined up correctly? I've been trying to solve this issue for most of the day and I'm sure it's a fairly simple thing to figure out, but my brain is shot.
Below is my code, thanks in advance for looking at it.
#include "stdafx.h"
#include <iostream>
using namespace std;
//Function Prototypes
void sort(int num[], char alph[], int size);
//Selection sort function
void sort(int num[], char alph[], int size)
{
int startScan;
int minIndex;
int minValue;
for (startScan = 0; startScan < (size - 1); startScan++) //Moves through the elements
{
minIndex = startScan;
minValue = num[startScan];
int index = 0;
for (index = startScan + 1; index < size; index++) //Compares the elements
{
if (num[index] < minValue)
{
minValue = num[index];
minIndex = index;
}
}
num[minIndex] = num[startScan];
num[startScan] = minValue;
alph[minIndex] = alph[startScan];
alph[startScan] = alph[index];
}
}
//Main
int _tmain(int argc, _TCHAR* argv[])
{
int num[] = {5, 3, 1, 4, 2};
char alph[] = { 'e', 'c', 'a', 'd', 'b' };
int const SIZE = 5;
//Prints out unsorted array
cout << "This is the unsorted arrays." << endl;
cout << endl;
for (int count = 0; count < SIZE; count++)
{
cout << num[count] << " \t ";
cout << alph[count] << endl;
}
cout << endl;
cout << endl;
//Calls the sort function
sort(num, alph, SIZE);
//Prints out the sorted array
cout << "This is the sorted array." << endl;
cout << endl;
for (int count = 0; count < SIZE; count++)
{
cout << num[count] << " \t";
cout << alph[count] << endl;
}
//Pause
char temp[50];
cin >> temp;
return 0;
}
EDIT: I edited the
alph[minIndex] = num[startScan]
issue so it reads correctly now as:
alph[minIndex] = alph[startScan]
I am now getting this as an output:
1 (jibberish)
2 (jibberish)
3 (jibberish)
4 (jibberish)
5 e
EDIT 2: I edited the line of code under my previous edit and the arrays are now lining up properly and I am no longer getting a bunch of jibberish for outputs. Below is the edited sort function of my code:
//NOTICE temp VARIABLE CHANGES!
void sort(int num[], char alph[], int size)
{
int startScan;
int minIndex;
int minValue;
int temp;
for (startScan = 0; startScan < (size - 1); startScan++) //Moves through the elements
{
minIndex = startScan;
minValue = num[startScan];
temp = alph[startScan];
int index = 0;
for (index = startScan + 1; index < size; index++) //Compares the elements
{
if (num[index] < minValue)
{
minValue = num[index];
minIndex = index;
temp = alph[index];
}
}
num[minIndex] = num[startScan];
num[startScan] = minValue;
alph[minIndex] = alph[startScan];
alph[startScan] = temp;
}
}
The best solution might be to change your
num[minIndex] = num[startScan];
num[startScan] = minValue;
char temp=alph[minIndex];
alph[minIndex] = alph[startScan];
alph[startScan] = temp;
to this which does the job and really can't be made any simpler.
std::swap(num[minIndex], num[startScan]);
std::swap(alph[minIndex],alph[startScan]);
See this line:
alph[minIndex] = num[startScan];
Second faulty line:
alph[startScan] = alph[index];
It should be:
alph[startScan] = alph[minIndex];
By the time the code exits of the inner loop, size has a value of one beyond the array size.
My advice: Use an IDE and the debugger to follow up code execution and examine variables. Also, my first hint should have gotten you looking at incorrect indexes. C++ does not care to check array bounds by default. You usually get garbage when getting out of bounds or following a incorrect pointer. You can remedy the first problem by selecting a compiler option to check for array bounds. That will slow down your application during development time but can be removed once everything works correctly.
I am trying to create a nested for loop that fills in values in an array from 1 to 20.
IE) array = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
int array[20];
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
Supposedly, The array index should count up with "i", and should be equated to "j" which is also counting up. The array element is printed to the console as it is filled.
I expected 1 -20 to be printed out once, but when I run the code, 1-20 prints out multiple times. Can someone tell me the problem? Thanks!
Your outer for loop runs 21 times, your inner for loop runs 20 times each of the outer for loop iterations, so you have a total of 21 * 20 = 420 print statements.
You can simply do
for(int i = 0 ; i < array.length ; i++)
{
array[i] = i + 1;
cout << array[i] << endl;
}
If you look at your array when you're done, it will also be just a series of 20s. The first loop is saying "do this 20 times" and then the second loop is saying "set and print the value of that array element 20 times." What you need to do is include a check for whether you're assigning the correct j value to the correct array[i] value, and only set the value in that case. Something like:
if (j == i + 1) array[i] = j;
Why do you need a nested loop?
for(int i = 0; i<20; i++)
{
array[i] = i + 1;
cout<< array[i];
}
yes, you have two loops when you only need one:
for(int i = 0; i<21; i++)
{
array[i] = i + 1;
cout<< array[i];
}
In order to fill the array and to print the result you just need two simple for loops
for(int i = 0; i<20; i++)
{
array[i] = j;
}
for(int j =0; j<20; j++)
{
cout<< array[i];
}
The nested loop that you created above will do exactly what you described.
For each loop of the outer for loop it will execute the full 20 loops of the inner loop.
so in total you will execute it 21 * 20 times.
Also be careful with your index. You want to start with int i = 0 to i < 20 which loops exactly 20 times.
I don't know why you are attempting to print a single element in you array, but it isn't necessary to use nested loops here; in fact, a loop isn't required at all:
// vector version
std::vector<int> vec(20);
std::iota(vec.begin(), vec.end(), 1);
// array version
int arr[20];
std::iota(std::begin(arr), std::end(arr), 1);
If you want to print out the whole array after you've initialized it:
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\n"));
I see a lot of people answered about this question, so I will not repeat them, I'll just mention that you are writing outside the array size.
if you have int array[20], you should loop
for(int i = 0; i<20; i++)
the last index is 19
The outer loop 21 times repeats the inner loop
for(int i = 0; i<21; i++)
{
for(int j =1; j<21; j++)
{
array[i] = j;
cout<< array[i];
}
}
The inner loop does the same operation that is assigns elements of the array sequantial numbers. Moreover your code has a bug because due to the outer loop youare trying to access element array[20] that does not exist, because if the array was defined as
int arrat[20];
then the valid indicies are 0 - 19.
That do not bother about writing correctly required loop or loops you could use standard algorithm std::iota
For example
#include <iostream>
#include <numeric>
#include <iterator>
#include <algorithm>
int main()
{
const size_t N = 20;
int array[N];
std::iota( std::begin( array ), std::end( array ), 1 );
std::copy( std::begin( array ), std::end( array ), std::ostream_iterator<int>( std::cout, " " ) );
}
Or instead of the algorithms you could use the range based for statement. For example
#include <iostream>
int main()
{
const size_t N = 20;
int array[N];
int i = 1;
for ( int &x : array )
{
x = i++;
std::cout << x << ' ';
}
}
If you really want to use nested solution, (for example game board coordinates) then this is my solution.
// nesting arrays for example game board coordinates
#include <iostream>
int main(){
int x = 20;
int y = 40;
int array[x][y];
// initialize array of variable-sized.
for(int i = 0; i < x; ++i){
for(int j = 0; j < y; ++j){
array[i][j] = 0; // or something like i + j + (i * (y-1)) if you wish
// and send it to cout
std::cout << array[i][j] << " ";
}
std::cout << std::endl;
}
//notice, that when sent to cout like this, x and y flips on screen, but
//logics of coordinates is ok
// and then do something usefull with it
return EXIT_SUCCESS;
}
int size = 20;
for (int i = 0; i < size; i++)
{ int array[i];
array[i] = i + 1;
cout << array[i]<< " ";
}
You could populate your array with 1 for loop, and gauge the size of your array like stated above.
well ive been trying to edit the element of an array so lets assume that we have a 2d array
so
a 2d array 9 x 9;
for(... ... ... ++)
{
for(.. ... ...++){}
}
lets say that the code will use another set of for loops to display the 2d array its a simple array nothing fancy
00000000
00000000
00000000...
so if i wanted to to display an E from elements[1][0] to [2][3] how would i do that?
00000000
eeeeeeee
eeee0000
00000000
what i had in mind was something like while(x < y)
{ array[x++][y];}
but this idea doesnt seem to work.
would gladly take any help. thx
for(int i=0; i<9; i++) //This loops on the rows.
{
for(int j=0; j<9; j++) //This loops on the columns
{
board[i][j] = grid; // set the array to the char on grid '0'.
}
}
board[s_col][s_row] = 'Z';
while(s_col < e_col)//s_col is the start of the rows and columns
//{
//if(s_col != e_col)
{
++s_col;
board[s_col][s_row];
}
//}
//cout << board[s_col][s_row++] <<endl;
// display the array
for(int i=0; i<9; i++) //This loops on the rows.
{
for(int j=0; j<9; j++) //This loops on the columns
{
cout << board[i][j] << " ";
}
cout << endl;
}
You were on the right track with the approach:
for(... ... ... ++)
{
for(.. ... ...++){}
}
Here is some code that should help you:
#include <stdio.h>
#include <memory.h>
#define MAX_ROW 4
#define MAX_COL 8
void fillRange(char fillChar, int startRow, int startCol, int count);
char myArray[MAX_ROW][MAX_COL];
void printArray();
int main(int argc, char *argv[])
{
memset(myArray, '0', sizeof(myArray));
printf("\nBefore:\n");
printArray();
fillRange('e', 1, 0, 12);
printf("\nAfter:\n");
printArray();
}
void fillRange(char fillChar, int startRow, int startCol, int count)
{
int i, j, filledChars = 0;
for(i = startRow; i < MAX_ROW; i++)
{
for(j = startCol; j < MAX_COL; j++)
{
myArray[i][j] = fillChar;
if(++filledChars == count)
return;
}
}
}
void printArray()
{
int i, j;
for(i = 0; i < MAX_ROW; i++)
{
for(j = 0; j < MAX_COL; j++)
putchar(myArray[i][j]);
printf("\n");
}
}
If you instead wanted to end at a particular point in the array then you just need to change the condition that triggers the return.
This is one of the many reasons why the more coding you do the more you tend to avoid 2D arrays of the sort you have.
Instead you use a 1D array like this: board[i][j] == board_1D[i*num_columns+j]. That also means you can just iterate through the entire board in a single for loop.
Now you simply calculate the begin and end indices of your e range, and simply test if your counter is within that range. In other words, you have a single if statement inside your inner-most loop.
You can, of course, convert your i,j 2D indices into the equivalent 1D index and take the same approach. index_1D = i*9+j;
I'll leave the code to you.
Dealing with a sequence of adjacent values is easiest done when you have an underlying contiguous array and you don't need to deal with double indexing (see Adam's answer on that). However, in your simple case it also quite doable:
You'd initialize your row and column variables with the start row and column (in your case 0 and 1). You then walk with your column until you reached either the target column (2) and you are on the target row (3) or you reached the end of the matrix in which case you set the column to 0 and increment the row.
I'll be pretty honest/upfront here- I'm both a noob to C++, to computer programming in general, and additionally, to this site as well. I'll just preface my question by saying that I did in fact look at other questions possibly related to my own, but it just felt like they were outside of my scope. With that said, here's my problem:
I get this error message:
"Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted."
Here's my code. It's just a basic little thing for some array practice. The function multiTable outputs a multiplication table:
#include <iostream>
#include <iomanip>
using namespace std;
void multiTable();
int main()
{
multiTable();
return 0;
}
//Prints a 9 by 9 multiplication table;
void multiTable()
{
const int row = 9, col = 9;
int arr[row][col];
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
arr[i][j] = j * i;
cout << setw(3);
cout << arr[i][j];
}
cout << endl;
}
}
I also want to mention that instead of the function call, had I just included all of the code contained within the function body in main, I don't get the run-time error. Why is it that when it's contained within a function, I get the runtime error, but when it's just in main, I don't get the error? And of course, what would I have to change in order for the function call to not produce the error?
Those are your problems: for(int i = 1; i <= row; i++) and for(int j = 1; j <= col; j++) array counting starts from 0. So your for loops should be like this (starting from 0 and omitting the = part from <=):
for(int i = 0; i < row; i++) and for(int j = 0; j < col; j++)