2 questions within. please help

so, when i am cycling through the loops, after the second round, the sorceress deck stops working and giving me negative numbers and not showing a card name why?
i am only allowed to use cards with type 1
card file looks like
type name attack defense
1 orc 2 2
2 dwarf 3 3
etc.
defence is irrelevant at this point. how do i read only type 1 cards into the deck?
Ihave done this to the best of my ability
full code below

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  const int ARRAYROW = 30;//sets number of lines for array
const int ARRAYCOL = 4;//sets columns for array
const int SIZE = 30;

class sorCard // creates class sorCard for deck
{
public:
	int sType;
	string sName;
	int sAttk;
	int sDef;
};
class wizCard
{
public:
	int wType;
	string wName;
	int wAttk;
	int wDef;
};

int main() {
	
	ifstream sorceresscards;
	sorceresscards.open("sorceress.txt");//opens sorceress cards file
	if (!sorceresscards) {
		cout << "Unable to open file";
		system("pause");
	}
	else {
		cout << "Sorceress file opened successfully" << endl;
	}
	sorCard sorDeck[SIZE];//creates deck for sorceress//
	for (int i = 0; i <= ARRAYCOL; i++) {
		
			sorceresscards >> sorDeck[i].sType >> sorDeck[i].sName >> sorDeck[i].sAttk >> sorDeck[i].sDef;//loads file into array
		

	}


	ifstream wizardcards;
	wizardcards.open("wizard.txt");//opens wizard  cards file//
	if (!wizardcards) {
		cout << "Unable to open file";
		system("pause");
	}
	else {
		cout << "Wizard file opened successfully" << endl;

	}
	wizCard wizDeck[SIZE];//creates deck for wizard
	for (int x = 0; x <= ARRAYCOL; x++) {
			wizardcards >> wizDeck[x].wType >> wizDeck[x].wName >> wizDeck[x].wAttk >> wizDeck[x].wDef;//loads file into array
		
	}

	cout << "Welcome To MAGIMANIA!" << endl << endl << "Created by M Gibson-Storey" << endl << endl;





	int sorceressHealth = 30;// sets health
	int wizardHealth = 30;
	int round = 1;// starts round at 1
	for (int x = 0; x <= ARRAYROW; x++) {

		for (int i = 0; i <= ARRAYROW; i++){
		system("pause");
		//Round begins
		cout << endl << "Round " << round++ << "  fight!" << endl << endl;


		//Sorceress draws card
		cout << "Sorceress draws " << sorDeck[i].sName << endl << endl;
		//Card attacks Wizard
		cout << sorDeck[i].sName << " deals " << sorDeck[i].sAttk << " damage to Wizard!" << endl << endl;


		//wizard draws card
		cout << "Wizard draws " << wizDeck[x].wName << endl << endl;

		//Card attacks sorceress
		cout << wizDeck[x].wName << " deals " << wizDeck[x].wAttk << " damage to Sorceress!" << endl << endl;

		wizardHealth -= sorDeck[i].sAttk;// changes player health
		sorceressHealth -= wizDeck[x].wAttk;
		cout << endl << "Sorceress has:" << sorceressHealth  << " Health" << endl << endl; // displays health
		cout << "Wizard has:" << wizardHealth  << " Health" << endl;
		system("pause");

		if (round == 31) {
			cout << endl << "its a tie!" << endl;
			system("pause");
		}
		if (wizardHealth == 0) {
			cout << "Sorceress Wins!" << endl;
			system("pause");
		}
		if (sorceressHealth == 0) {
			cout << "Wizard Wins!" << endl;
			system("pause");
		}
		}
	}



	system("pause");

	return 0;
}
ARRAYCOL is not needed because you aren't using a 2D array, just a 1D array of structs with 4 entries. Also, ARRAYROW seems to have the same meaning as SIZE. I would just use SIZE.

Also, the structs are essentially identical, so you may as well just have one called Card. And I guess you don't need the type if you are only reading in type 1 cards.

We would normally use a vector instead of an array, which would mean that you don't need SIZE at all. And the struct could benefit from a constructor.

If the files actually have a header as you showed it then you need to skip that. You show a header that says "type name attack defense", but maybe that's not part of the files.

The following compiles but I didn't actually run it.
It assumes you want to go through each deck and compare card-for-card (as opposed to the double loop in your original code where you compare each card in one deck to every card in the other).
If you would like to shuffle the deck I can show you how to do that, but this code doesn't.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Card {
    string name;
    int attk;
    int def;
    
    Card(string n, int a, int d)
        : name(n), attk(a), def(d) {}
};

int main() {
    ifstream fin("sorceress.txt");
    if (!fin) {
        cerr << "Unable to open sorceress.txt\n";
        return 0;
    }

    int typ, att, def;
    string nam;
    vector<Card> sorDeck;
    
    // getline(fin, nam);   // skip header (?)

    while (fin >> typ >> nam >> att >> def)
        if (typ == 1)
            sorDeck.push_back(Card(nam, att, def));

    fin.close();

    fin.open("wizard.txt");
    if (!fin) {
        cerr << "Unable to open wizard.txt\n";
        return 0;
    }

    vector<Card> wizDeck;

    // getline(fin, nam);   // skip header (?)

    while (fin >> typ >> nam >> att >> def)
        if (typ == 1)
            wizDeck.push_back(Card(nam, att, def));

    fin.close();

    // See how many cards you read in.
    cout << "sorDeck: " << sorDeck.size() << "\n";
    cout << "wizDeck: " << wizDeck.size() << "\n\n";


    cout << "Welcome To MAGIMANIA!\n\nCreated by M Gibson-Storey\n\n";

    int sorceressHealth = 30, wizardHealth = 30;
    size_t i = 0;

    while (i < 30 && i < sorDeck.size() && i < wizDeck.size()
           && sorceressHealth > 0 && wizardHealth > 0) {
        cout << "\nRound " << i + 1 << "  fight!\n\n";
        system("pause");

        cout << "Sorceress draws " << sorDeck[i].name << "\n\n";
        cout << sorDeck[i].name << " deals "
             << sorDeck[i].attk << " damage to Wizard!\n\n";

        cout << "Wizard draws " << wizDeck[i].name << "\n\n";
        cout << wizDeck[i].name << " deals "
             << wizDeck[i].attk << " damage to Sorceress!\n\n";

        wizardHealth -= sorDeck[i].attk;
        sorceressHealth -= wizDeck[i].attk;

        cout << "\nSorceress has:" << sorceressHealth << " Health\n\n";
        cout << "Wizard has:" << wizardHealth  << " Health\n";
        system("pause");
    }

    if (wizardHealth <= 0)
        cout << "Sorceress Wins!\n";
    else if (sorceressHealth <= 0)
        cout << "Wizard Wins!\n";
    else
        cout << "\nIts a tie!\n";
    system("pause");
}

we arent using vectors and to be fair i have no idea.
i have removed ARRAYROW and ARRAYCOL still works the same less code cheers.

any idea why the sorceress deck doesnt read the card name after the second round?
If you don't want to use vectors then just remove them and go back to arrays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

const int SIZE = 30;

struct Card {
    string name;
    int attk;
    int def;
};

void pause() {
    system("pause");
    //cout << "Enter to continue... ";
    //string line;
    //getline(cin, line);
}

int main() {
    ifstream fin("sorceress.txt");
    if (!fin) {
        cerr << "Unable to open sorceress.txt\n";
        return 0;
    }

    int typ, att, def;
    string nam;
    Card sorDeck[SIZE];

    // getline(fin, nam);   // skip header (?)

    for (int i = 0; i < SIZE && fin >> typ >> nam >> att >> def; )
        if (typ == 1) {
            sorDeck[i].name = nam;
            sorDeck[i].attk = att;
            sorDeck[i].def = def;
            i++;
        }

    fin.close();

    fin.open("wizard.txt");
    if (!fin) {
        cerr << "Unable to open wizard.txt\n";
        return 0;
    }

    Card wizDeck[SIZE];

    // getline(fin, nam);   // skip header (?)

    for (int i = 0; i < SIZE && fin >> typ >> nam >> att >> def; )
        if (typ == 1) {
            wizDeck[i].name = nam;
            wizDeck[i].attk = att;
            wizDeck[i].def = def;
            i++;
        }

    fin.close();

    cout << "Welcome To MAGIMANIA!\n\nCreated by M Gibson-Storey\n\n";

    int sorceressHealth = 30, wizardHealth = 30;
    int i = 0;

    while (i < SIZE && sorceressHealth > 0 && wizardHealth > 0) {
        cout << "\nRound " << i + 1 << "  fight!\n\n";
        pause();

        cout << "Sorceress draws " << sorDeck[i].name << "\n\n";
        cout << sorDeck[i].name << " deals "
             << sorDeck[i].attk << " damage to Wizard!\n\n";

        cout << "Wizard draws " << wizDeck[i].name << "\n\n";
        cout << wizDeck[i].name << " deals "
             << wizDeck[i].attk << " damage to Sorceress!\n\n";

        wizardHealth -= sorDeck[i].attk;
        sorceressHealth -= wizDeck[i].attk;

        cout << "\nSorceress has:" << sorceressHealth << " Health\n\n";
        cout << "Wizard has:" << wizardHealth  << " Health\n";
        pause();
    }

    if (wizardHealth < sorceressHealth)
        cout << "Sorceress Wins!\n";
    else if (sorceressHealth < wizardHealth)
        cout << "Wizard Wins!\n";
    else
        cout << "\nIts a tie!\n";
}

Last edited on
Topic archived. No new replies allowed.