i have this program that prints th2 52 cards of a deck in order and then should print them randomly shuffled. I tried using many ways, but this one looked the most logically correct for me so Can you please tell me my mistake in shuffling and a solution to fix it, so my program will print the 52 cards shuffled.
#include <stdio.h>
#define DECK_SIZE 52
#define SUIT_SIZE 4
#define FACE_SIZE 13
char* suit[SUIT_SIZE] = {"Hearts", "Diamonds", "Clubs", "Spades"};
char* face[FACE_SIZE] = {"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen", "King"};
char* deck[SUIT_SIZE][FACE_SIZE];
char * card_name_create(char* face, char* suit){
size_t face_len = strlen(face);
size_t suit_len = strlen(suit);
size_t of_len = 4;
char of[5] = " of ";
// The size id the size of two strings, than the size of " of " and the '\0'
char * full_name = malloc(sizeof(char)*(face_len+suit_len+of_len+1));
for (size_t i = 0; i < face_len; i++){
full_name[i] = face[i];
}
for (size_t i = face_len; i < face_len+of_len; i++){
full_name[i] = of[i-face_len];
}
for (size_t i = face_len+of_len; i < face_len+of_len+suit_len; i++){
full_name[i] = suit[i - (face_len+of_len) ];
}
full_name[face_len+of_len+suit_len] = '\0';
return full_name;
}
void initialiseDeck(){
for (int i = 0; i < SUIT_SIZE; i++){
for (int j = 0; j < FACE_SIZE; j++){
char * c = card_name_create(face[j],suit[i]);
deck[i][j] = c;
}
}
}
void display(){
for(int i = 0; i < SUIT_SIZE; ++i)
for(int j = 0; j < FACE_SIZE; ++j)
printf("%s\n", deck[i][j]);
}
void shuffleDeck(){
int size = DECK_SIZE;
if (size > 1){
int i;
for (i = 0; i < size - 1; i++){
int j = rand() % DECK_SIZE;
const char* temp = deck[j];
deck[j] = deck[i];
deck[i] = temp;
}
}
}
int main(){
initialiseDeck();
printf("=========================");
printf("Cards Without Shuffling - ");
printf("=========================\n");
display();
srand (time(NULL));
shuffleDeck();
printf("cards after shuffling\n");
int p;
for (p = 0; p < DECK_SIZE; p++) {
printf("%i: %s\n", p, deck[p]);
}
return 0;
}
If you are going to be shuffling anyway, there is no point in separating the cards by suit and rank... you should just have a 1-dimensional array int deck[DECK_SIZE];, and you can shuffle it with a function like this:
// Caller should seed the PRNG before calling this function, using srand
int *shuffle(int deck[], const int size)
{
for (int i = 0; i < size; ++i) {
int j = rand() % (size - i) + i;
int tmp = deck[i];
deck[i] = deck[j];
deck[j] = tmp;
}
return deck;
}
Related
Im trying to initialize a 2d array representing a deck of cards from 2 char pointer arrays called faces and suit representing the faces and suits of cards. I'm getting various errors shown below and cannot work out how to properly add values to my deck as well display my deck. Could anyone point out to me what needs to change in order for my code to work? Thank you.
#include <stdio.h>
#include <string.h>
#include "functions.h"
char **deck[4][13];
char *suit[] = {
"Hearts",
"Diamonds",
"Clubs",
"Spades"};
char *faces[] = {
"Ace",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Jack",
"Queen",
"King",
};
char** initializeDeck(char** arr)
{
char addToString[] = " of ";
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
arr[i][j] = *faces[j], addToString, *suit[i]
}
}
return arr;
}
void displayDeck(char** arr){
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
printf("[%s] ", **arr[i][j]);
}
printf("\n");
}
}
errors:
functions.c:35:37: warning: expression result unused [-Wunused-value]
arr[i][j] = *faces[j], addToString, *suit[i];
^~~~~~~~~~~
functions.c:35:50: warning: expression result unused [-Wunused-value]
arr[i][j] = *faces[j], addToString, *suit[i];
^~~~~~~~
functions.c:46:30: error: indirection requires pointer operand ('int' invalid)
printf("[%s] ", **arr[i][j]);
arr[i][j] = *faces[j], addToString, *suit[i] is not contcatenating the strings together.
Here you have some code but I do not think that your teacher will belive that is your code
char *myconcat(const char *s1, const char *s2, const char *s3)
{
size_t len = strlen(s1) + strlen(s2) + strlen(s3);
char *newstr = malloc(len + 1);
if(newstr)
{
strcpy(newstr, s1);
strcat(newstr, s2);
strcat(newstr, s3);
}
return newstr;
}
char *(*initializeDeck(void))[13]
{
char *(*cards)[13] = malloc(4 *sizeof(*cards));
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
cards[i][j] = myconcat(faces[j], " of ", suit[i]);
}
}
return cards;
}
void displayDeck(char *(*cards)[13]){
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
printf("[%s] ", cards[i][j]);
}
printf("\n");
}
}
int siralama(int liste[], int size) {
int i, j;
int element;
for (i = size - 2; i >= 0; i--) {
element = liste[i];
j = i + 1;
while (j < size && liste[j] > element) {
liste[j - 1] = liste[j];
j++;
}
liste[j - 1] = element;
}
}
I'm sorting some numbers with the above function, but these numbers have string equivalents and I want to sort strings.
Example:
int arr2[4] = {3,5,4,7} => {7,5,4,3} ( I can)
char arr1[4][2] = {{"a"},{"b"},{"c"},{"d"}} => {{"d"},{"b"},{"c"},{"a"}} ( I can't)
When you sort the elements in the int array, you refer to them through an index. Just use the same indexes to so sort the char array.
#include <stdio.h>
void printThem( int n[], char s[] );
int main() {
int num[4] = {3, 5, 4, 7}, hold;
char str[] = "abcd";
printThem( num, str );
hold = num[0];
num[0] = num[3];
num[3] = hold;
hold = str[0];
str[0] = str[3];
str[3] = hold;
printThem( num, str );
return 0;
}
void printThem( int n[], char s[] )
{
for(int i = 0; i < 4; i++) {
printf("%d ", n[i]);
}
printf(" --> ");
for(int i = 0; i < 4; i++) {
printf("%c ", s[i]);
}
puts("\n");
}
I'm actually trying, with a bi-dimensionnal array of string ( It could bi tri-dimensionnal in fact ), to exchange two "cells" of the array.
Before, i used memcpy but when comes long string, comes long execution time so I thought it was possible to simply exchange the pointers of the array but I don't know how to do :(
Here's my code:
#include <stdio.h>
#include <stdlib.h>
void fonction(unsigned char*** tab);
int main()
{
unsigned char*** tab;
tab = malloc(sizeof(unsigned char**) * 3);
if (tab == NULL)
exit(0);
for (int line = 0; line < 3; line++)
tab[line] = malloc(sizeof(unsigned char*) * 3);
for (int line = 0; line < 3; line++)
for (int column = 0; column < 3; column++)
tab[line][column] = malloc(sizeof(unsigned char) * 5);
for (int line = 0; line < 3; line++)
for (int column = 0; column < 3; column++)
for (int cell = 0;cell < 5;cell++)
tab[line][column][cell] = line * 3 * 5 + column * 5 + cell;
for (int i = 0;i < 32;i++)
fonction(tab);
for (int line = 0; line < 3; line++)
for (int column = 0; column < 3; column++)
free(tab[line][column]);
for (int line = 0; line < 3; line++)
free(tab[line]);
free(tab);
return 0;
}
void fonction(unsigned char*** tab)
{
unsigned char temp[5] = { 0, 0, 0, 0, 0 };
int alea = 0;
int alea2 = 0;
int alea3 = 0;
int alea4 = 0;
srand(58);
for (int line = 0; line < 3; line++)
{
for (int column = 0; column < 3; column++)
{
alea = rand() % 3;
alea2 = rand() % 3;
alea3 = rand() % 3;
alea4 = rand() % 3;
*temp = tab[alea][alea2];
tab[alea][alea2] = tab[alea3][alea4];
tab[alea3][alea4] = *temp;
}
}
}
Errors come when freeing tab and this is expectable because fonction does any old thing :)
Thanks in advance !
I am not sure why you are using
unsigned char temp[5] = { 0, 0, 0, 0, 0 };
Just use
char* temp;
And do swapping as
temp = tab[alea][alea2];
tab[alea][alea2] = tab[alea3][alea4];
tab[alea3][alea4] = temp;
I couldn't really get what you were trying to do with your code, but here's a working example of moving string pointers around:
#include <stdio.h>
#include <stdlib.h>
#define STR_NUM 3
int main(void)
{
char * str1[STR_NUM] = {"one", "two", "three"};
char * str2[STR_NUM];
int i;
for (i = 0; i < STR_NUM; ++i)
puts(str1[i]);
for (i = 0; i < STR_NUM; ++i)
str2[i] = str1[i];
for (i = 0; i < STR_NUM; ++i)
puts(str2[i]);
return 0;
}
int ** ARR;
int LENGTH = 1;
int DEPTH = 1;
void loadt(int ** terr)
{
terr = (int**)malloc(sizeof(int*) * (LENGTH + 1));
int i, j;
for(i = 1; i <= LENGTH; i++)
terr[i] = (int*)malloc(sizeof(int) * (DEPTH + 1));
for(i = 1; i <= LENGTH; i++)
for(j = 1; j <= DEPTH; j++)
scanf("%d", &terr[i][j]);
}
void freet(int ** terr)
{
int i;
for(i = 1; i <= LENGTH; i++){
free(terr[i]);
}
free(terr);
}
int main(int argc, char* argv[])
{
loadt(ARR);
freet(ARR);
return 0;
}
Hello. I probably miss sth really basic here but after I run the program it crashes."Segmentation fault (core dumped)" Why?
Because in c arguments to functions are always passed by value, so your unecessarily global variable is not getting reassigned inside the function since you are passing it as a parameter and hence a copy of it is made, which is the one that is actually reassigned.
So you are calling free() on an uninitialized poitner.
Try like this
int **loadt(int LENGTH, int DEPTH)
{
int **terr;
int i, j;
terr = malloc(sizeof(int*) * (LENGTH + 1));
if (terr == NULL)
return NULL;
for (i = 1; i <= LENGTH; i++) {
terr[i] = malloc(sizeof(int) * (DEPTH + 1));
if (terr[i] == NULL) {
for (j = i ; j >= 0 ; --j) {
free(terr[j]);
}
free(terr);
return NULL;
}
}
for (i = 1; i <= LENGTH; i++) {
for (j = 1; j <= DEPTH; j++) {
scanf("%d", &terr[i][j]);
}
}
return terr;
}
void freet(int **terr)
{
int i;
if (terr == NULL)
return; // `free()' also accepts NULL pointers
for (i = 1; i <= LENGTH; i++) {
free(terr[i]);
}
free(terr);
}
int main(int argc, char* argv[])
{
int **ARR;
int LENGTH = 1;
int DEPTH = 1;
ARR = loadt(LENGTH, DEPTH);
freet(ARR);
return 0;
}
Another problem, is that you start your loops at i = 1, which is fine because you are allocating enough space, but it's not the way you should do it. Instead for (i = 0 ; i < LENGTH ; ++i) would be how a c programmer would do it. Note that you are wasting the first element of your array.
I have some array with numbers. When I want to write all combination with 3 digits I wrote this. But now I need edit this code to return all combination with 1 to numbers.size digits. How should I edit it ?
int items[] = {1, 2, 3, 4, 5};
int itemSize = 5;
for (int i = 0; i < itemSize - 2; i++) {
for (int j = i + 1; j < itemSize - 1; j++) {
for (int k = j + 1; k < itemSize; k++)
printf("%d%d%d\n", items[i], items[j], items[k]);
}
}
it is not perfect solution, but it is well enough to work. you can get all sub array from an array, from 1 element to length array
void permute(char* previous, char *a, int i, int n,int nmax)
{
int j;
if (i == n)
{
char c = a[nmax];
a[nmax] = 0;
if (strstr(previous,a) == 0)
{
printf("%s\n", a);
strncpy(previous,a,n);
}
a[nmax] = c;
}
else
{
for (j = i; j < n; j++)
{
char c = a[i];
a[i] = a[j];
a[j] = c;
permute(previous,a, i+1, n,nmax);
c = a[i];
a[i] = a[j];
a[j] = c;
}
}
}
void subarrays(char *a, int len)
{
int i=1;
char *previous = strdup(a);
*previous = 0;
for(i=1;i<len+1;i++)
{
permute(previous,a,0,len,i);
}
}
int main(void) {
char *arr = strdup("abcde");
subarrays(arr,strlen(arr));
return EXIT_SUCCESS;
}
Since you're already doing a web search for this, here is a generic solution.
#include <stdio.h>
int next_combination(size_t *I, size_t k, size_t n)
{
size_t i, j;
i = k-1; /* find next element to increment */
while(I[i] == (n-k+i)){
--i;
if(i == (size_t)-1){ /* if done */
for(i = 0; i < k; i++) /* return with initial combination */
I[i] = i;
return(0);
}
}
I[i] += 1; /* increment element */
for(j = i+1; j < k; j++) /* create increasing string */
I[j] = I[i]+j-i;
return(1); /* return with new combination */
}
int main(int argc, char **argv)
{
int A[5] = {1, 2, 3, 4, 5};
size_t I[5];
size_t i, k, n;
n = sizeof(A)/sizeof(A[0]); /* n things */
for(k = 1; k <= n; k++){ /* n things k at a time */
for(i = 0; i < k; i++) /* create initial combination */
I[i] = i;
do{ /* display combinations */
for(i = 0; i < k; i++)
printf("%2d", A[I[i]]);
printf("\n");
}
while(next_combination(I, k, n));
}
return(0);
}