2017-11-03 8 views
-1

초보 프로그래머입니다. Xcode를 사용하여 카드 전쟁 게임을 만들고 있습니다. 그러나, 내 prof는 code :: blocks을 사용하여 등급을 매긴다. Xcode에서 코드를 실행할 때 완벽하게 실행되지만 code :: blocks에서 실행하면 오류가 발생합니다. 프로세스가 -1 (0xFFFFFFF)을 반환했습니다. 아무도 무슨 일이 일어나고 있고 왜 한 IDE에서 다음 IDE로 실행되지 않는지 말할 수 있습니까? 그게 내가 등급을 매길 것이기 때문에 코드 블럭에서 실행되도록하는 것이 중요합니다. 당신이 memset을 수행 할 때내 프로그램이 Xcode에서는 실행되지만 코드 블록에서는 실행되지 않는 이유는 무엇입니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include <string.h> 
#include <time.h> 

#define DECK_SIZE 52 

unsigned int rounds_played = 0 ; 
unsigned int wars_played = 0 ; 

/* 
Base data structure: deck. It's a stack that can hold up to 
deck_size cards. 

A card is represented as a nunmber from 2 to 14. 14 is an Ace. 

*/ 
typedef struct { 
    // basically a stack 
    char* slots ; 
    unsigned int slot_pointer ; 
    unsigned int deck_size ; 
} Deck ; 

/* Operations on deck: 

make_deck: creates and initialize a deck that can hold up to *size* 
cards. 

enqueue(deck, item): puts a card on top of the stack 
dequeue(deck): draws a card from the stack 
dump_deck(d): views content of deck d. free slots will have value 
       of zero (0) 
deck_empty(d): inspects a deck to see whether a deck holds any card 

*/ 
Deck* make_deck(unsigned int size) ; 
void enqueue(Deck* deck, char item); 
char dequeue(Deck* deck) ; 
void dump_deck(Deck *d); 
int deck_empty(Deck *d) ; 

/* make_initial_deck: sets up a 52-card deck, shuffled */ 
Deck *make_initial_deck() ; 

/* deal: cards from deck *sorce get split evenly between decks 
     *d1 and *d2 
*/ 
void deal(Deck *source, Deck *deck1, Deck *deck2); 


void play(Deck* d1, Deck* d2, Deck* tmp); 
bool game_won(Deck* d1, Deck* d2) ; 
unsigned int deck_cards_number(Deck* d) ; 
char* print_card(char card) ; 

int main(int argc, char **argv) { 

    srand(time(NULL)); 

    Deck* initial_deck = make_initial_deck() ; 
    Deck* d1 = make_deck(DECK_SIZE) ; 
    Deck* d2 = make_deck(DECK_SIZE) ; 

    printf("Dumping initial deck:\n"); 
    dump_deck(initial_deck) ; 

    deal(initial_deck, d1, d2) ; 

    printf("Dumping d1:\n"); 
    dump_deck(d1); 

    printf("Dumping d2:\n"); 
    dump_deck(d2) ; 

    Deck* tmp = make_deck(DECK_SIZE) ; 
    play(d1, d2, tmp) ; 

    return 0 ; 
} 

/* 
* play: implements the game 

*/ 
void play (Deck* d1, Deck* d2, Deck *tmp) { 
    rounds_played++ ; 
    char card1, card2 ; 
    /* printf("Player 1 deck:\n"); dump_deck(d1) ; */ 
    /* printf("Player 2 deck:\n"); dump_deck(d2) ; */ 
    /* printf("tmp deck:\n"); dump_deck(tmp) ; */ 

    if (d1->slot_pointer == 0) { 
    printf("Player 2 wins the game!\n") ; 
    printf("Rounds played: %d\n", rounds_played); 
    printf("Wars declared: %d\n", wars_played) ; 

    return ; 
    } else { 
    card1 = dequeue(d1); 
    printf("[Player 1]: %s\n", print_card(card1)); 
    } 

    if (d2->slot_pointer == 0) { 
    printf("Player 1 wins the game!\n") ; 
    printf("Rounds played: %d\n", rounds_played); 
    printf("Wars declared: %d\n", wars_played) ; 
    return ; 
    } else { 
    card2 = dequeue(d2); 
    printf("[Player 2]: %s\n", print_card(card2)); 
    } 


    // recursive case: 
    if (card1 == card2) { 
    printf("This is War!\n") ; 
    wars_played++ ; 

    if (deck_empty(d1) == 0) { 
     enqueue(tmp, dequeue(d1)); // face down card 
    } 
    if (deck_empty(d2) == 0) { 
     enqueue(tmp, dequeue(d2)); // face down card 
    } 
    /* enqueue(tmp, dequeue(d1)); // face down card */ 
    /* enqueue(tmp, dequeue(d2)); // face down card */ 

    enqueue(tmp, card1); 
    enqueue(tmp, card2); 
    } else { 
    if (card1 > card2) { 
     // printf("Player1 wins the round!\n") ; 
     enqueue(tmp, card1) ; 
     enqueue(tmp, card2) ; 
     printf("Player 1 wins (%d) cards.\n", 
     tmp->slot_pointer) ; 
     // dump_deck(tmp); 
     while (tmp->slot_pointer > 0) { 
    enqueue(d1, dequeue(tmp)) ; 
     } 
    } 
    else { 
     // printf("Player2 wins the round!\n") ; 
     enqueue(tmp, card1) ; 
     enqueue(tmp, card2) ; 
     printf("Player 2 wins (%d) cards.\n", 
     tmp->slot_pointer) ; 
     // dump_deck(tmp); 
     while (tmp->slot_pointer > 0) { 
    enqueue(d2, dequeue(tmp)) ; 
     } 
    } 
    } 
    play(d1,d2,tmp); 

    return ; 
} 

/* Given a souce Deck and two destination Decks d1 and d2, it deals cards from 
* source deck to d1 and d2 so that both decks get half of the cards originally 
* in the source deck. 
*/ 
void deal(Deck *source, Deck *deck1, Deck *deck2) { 
    char card ; 
    for(int i=0 ; i< (source->deck_size) ; i++) { 
    card = dequeue(source) ; 
    if ((i%2) == 0){ 
     enqueue(deck1, card) ; 
    } else { 
     enqueue(deck2, card) ; 
    } 
    } 
    return ; 
} 

// INPUT: two decks, one for each player. 
// OUTPUT: true or false, depending on whether one of the two decks 
//   holds 52 cards 
bool game_won(Deck* d1, Deck* d2){ 
    if ((d1->slot_pointer == 51) || (d2->slot_pointer == 51)) 
    return true ; 
    else 
    return false ; 
} 


// INPUT: the desidered deck size 
// OUTPUT: an instance of the Deck data structure, properly intialized 
Deck* make_deck(unsigned int size){ 
    Deck *d = malloc(sizeof(Deck)); 
    d->slots = malloc(size*sizeof(char)) ; 
    memset(d->slots, 0, d->deck_size); 
    d->slot_pointer = 0 ; 
    d->deck_size = size ; 

    return d ; 
} 

// INPUT: an instance of the Deck data structure 
// POST: the contents of the deck will be displayed on standard output. 
//  available but empty slots will be represented with zeroes. 
void dump_deck(Deck* d) { 
    for(unsigned int i=1 ; i<=(d->deck_size) ; i++) { 
    printf("%2d ", d->slots[i-1]) ; 
    if(i>0 && i % 13 == 0) { 
     printf("\n") ; 
    } 
    } 
    printf("\n"); 
    return ; 
} 

// INPUT: An instance of the Deck data structure and a number (in a char) 
// representing a card. 
// POST: the card will be added to the deck. 
void enqueue(Deck* deck, char item) { 
    deck->slots[deck->slot_pointer++] = item ; 
    return ; 
} 


// INPUT: an instance of the Deck data structure 
// OUTPUT: a number representing a card from the deck. 
char dequeue(Deck* deck) { 
    deck->slot_pointer-- ; 
    char card = deck->slots[deck->slot_pointer] ; 
    deck->slots[deck->slot_pointer] = 0 ; 
    return card ; 
} 

// INPUT: an instance of the Deck data structure 
// OUTPUT: 1 if the deck is empty, 0 otherwise. 
int deck_empty(Deck *d) { 
    if (d->slot_pointer == 0) { 
    return 1 ; 
    } else { 
    return 0 ; 
    } 
} 

// OUTPUT: returns a pointer to a newly-created instance of the Deck data 
//   structure, holding DECK_SIZE cards, and randomly shuffled. 
Deck *make_initial_deck() { 
    Deck *d = make_deck(DECK_SIZE); 

    for(int i=0 ; i<4 ; i++) { 
    for (int j=2 ; j<15 ; j++) { 
     enqueue(d, j) ; 
    } 
    } 


    int n = DECK_SIZE; 
    for (int i = 0; i < n - 1; i++){ 
    /// get random element in the listplayer1Hand[26] = 2; 
    int j = i + rand()/(RAND_MAX/(n - i) + 1); 

    ///swap these two elements 
    char temp = d->slots[j]; 
    d->slots[j] = d->slots[i]; 
    d->slots[i] = temp; 
    } 

    return d; 
} 

// INPUT: a char holding the numeric representation of the card 
// OUTPUT: a pointer to a string holding the representation of the card. 
//   The representation can be "Ace", "Jack", "Queen" and "King", 
//   and the respective number for other cards. 
char* print_card(char card) { 
    switch (card) { 
    case 14 : 
    return "Ace" ; 
    case 11 : 
    return "Jack" ; 
    case 12: 
    return "Queen" ; 
    case 13: 
    return "King" ; 
    } 

    char* str = malloc(4) ; 
    sprintf(str, "%2d", card) ; 
    return str ; 
} 
+1

이것은 * long * 코드입니다. 무슨 일이 일어나고 있는지 알기 위해서는 그것을 디버그해야합니다. 내가 지금 당장 볼 수있는 한가지는'print_card'가 메모리를 누설하고 있다는 것입니다. 그리고 아무것도, 내가 말할 수있는 한. –

+0

필자가 주목해야 할 것은'print_card'에'malloc'을 사용했지만 대응하는'free'는 없습니다. 함수가 말한 것을 수행하면 (인쇄 할 때) 더 좋을지도 모릅니다.이 경우 카드 이름을 만들 때 배열이 필요조차 없습니다. 설명을 인쇄하려면 함수의 플레이어 번호도 전달해야합니다. –

답변

3

코드

Deck* make_deck(unsigned int size){ 
    Deck *d = malloc(sizeof(Deck)); 
    d->slots = malloc(size*sizeof(char)) ; 
    memset(d->slots, 0, d->deck_size); 
    d->slot_pointer = 0 ; 
    d->deck_size = size ; 

    return d ; 
} 

의이 비트에 명백한 버그가 있습니다, D-> deck_size 어떤 가치가 있는가? 정의되지 않은 동작을 일으키는 값이 없습니다. 으로 전화 한 것처럼 d->deck_size의 할당을 memset 이전으로 이동하거나 size과 같이 사용해야합니다.

+0

오 마이 갓. 너는 대단해 !! 방금 d-> deck_size의 할당을 옮겼습니다. 이제 완벽하게 작동합니다. 정말 고마워. 너는 생명의 은인이야 !! –

+0

@TinaTran "valgrind"와 같은 것을 통해 실행 파일을 실행할 수 있습니다. 이러한 종류의 단순하면서도 숨겨진 실수를 많이 발견 할 수 있으며 메모리 누수도 찾을 수 있습니다. –