Permalänk

c++ objekt hjälp

Hej jag håller på mig och lär mig objektorientering och har därför bestämt mig för att koda ett kortspel objektorieterat. Detta är mitt första OOP så koden är inte den bästa. Syftet med programmet är enbart att lära sig och jag har inte ens bestämt vad för kortspel som jag ska koda, så kritisera gärna alla dumheter jag gör.

Nu har jag fått ett problem som jag inte förstår varför det uppstår.

Jag kan enkelt förklara hur jag tänkte med mitt program

Jag har en klass card, som enbart är korts nummer och valör.
Sedan en klass kortbunt som är en buntkort, denna klass ska sedan olika spelare ärva och ha egna kortbuntar.

I main skapar jag en kortbunt som jag därefter blandar, sedan ska man från denna kortbunt ge bort det översta kortet till andra kortbuntar.

Problemet är att i den första kortbunten måste hålla ordning på hur många kort som jag har gett bort så jag vet
vilket jag ska ge bort därefter, detta sköter jag med en variabel int usedCard, men den nollställs varje gång och jag förstår ej varför.
Det konstiga är att den andra "instansvariabeln" card cards[52] i samma klass fungerar som den ska från samma metod.

Visst det är kanske smartare att ha en dynamisk vektor med kort, men nu är jag ute efter att lära mig och vill veta vad felet är.

Här är hela koden och som sagt det är min första OOP kod så kritisera gärna alla dumheter som ni tycker jag gör.

Jag tycker själv koden blir extremt grötig och svårläst med min OOP. Isåfall vad gör jag för fel? Hade jag kodat samma strukturerat, så hade det blivit tusan så mycket lättläst, men man lär sig nog att hantera OOP.

#include "stdafx.h" #include <iostream> #include <cstdlib> #include <string> #include <ctime> using namespace std; enum {CLUBS, DIAMONDS, HEARTS, SPADES}; enum {Knave = 11, QUEEN, KING, ACE}; /* Klassen card, innehåller bara kortens värde och färg */ class card { protected: int value, suit; public: card(){}; card(int v, int s) { setCard(v,s); } void setCard(int v,int s) { value = v; suit = s; } int getValue() { return value; } int getSuit() { return suit; } string getSuitString() { string stringSuit[] = {"CLUBS", "DIAMONDS", "HEARTS", "SPADES"}; return stringSuit[suit]; } }; /* Klassen kortlek, ska föreställa en bunt med kort. Denna bunt kan vara olika stor, men högst 52kort. cardVeckorns storlek sedan såklart vara dynamisk. */ class kortBunt: public card { int usedCard; //card cards[52]; //orginalet public: card cards[52]; //är bara public under felsökning //Konstruktur som initerar kortbunten med kort i sorterad form kortBunt() { usedCard = 0; for(int a = CLUBS; a<= SPADES;a++) { for (int b =2; b<= ACE;b++) { cards[b-2+a*13] = card(b,a); } } } //Det är tänkt att denna metod ska kunna ge spelare och dator kort card giveCard() { cout << "\n usedCard:" <<usedCard << "\n"; usedCard++; //Denna nollställs varenda gång, varför? return cards[usedCard-1]; } int nextCard() { //Temporär metod som returnerar nästa kort platsering i högen. //Sådan metod ska såklart ej senare finnas return usedCard; } void shuffle(int times) { //blandar korten card *temp = new card(); int random; srand(int(time(0))); for (int n=1;n<=times;n++) { for (int i=0;i<52;i++) { random = int((rand()/float(RAND_MAX))*52); *temp = cards[i]; cards[i] = cards[random]; cards[random] = *temp; } } delete temp; } }; //Spelaren, som skapar en egen kortbunt class playerHand: public kortBunt { public: string playerName; int numberOfCard; //antal kort som spelaren har card playerCards[52]; //bara public under test playerHand() { playerName="Kalle"; //temporär numberOfCard=0; cout<<"\ninit\n"; } void takeCard(kortBunt kortBuntTest) { playerCards[numberOfCard] = kortBuntTest.giveCard(); numberOfCard++; cout << "\n numberOfCard:" <<numberOfCard << "\n"; //cout << endl<< playerCards[numberOfCard].getValue() <<" " << playerCards[numberOfCard].getSuitString() << endl; } }; class computerHand { public: string computerName; }; class boardHand { }; int _tmain(int argc, _TCHAR* argv[]) { kortBunt kortBuntTest = kortBunt(); kortBuntTest.shuffle(5); cout <<"Korten blandade:"<<endl; for(int i=0;i<52;i++) { cout << endl<< kortBuntTest.cards[i].getValue() <<" " << kortBuntTest.cards[i].getSuitString() << endl; } playerHand player; player.takeCard(kortBuntTest); player.takeCard(kortBuntTest); player.takeCard(kortBuntTest); //test.giveCard(); //test.giveCard(); //test.giveCard(); cout <<"Kort kvar i högen:"<<endl; for(int i= kortBuntTest.nextCard();i<52;i++) { cout << endl<< kortBuntTest.cards[i].getValue() <<" " << kortBuntTest.cards[i].getSuitString() << endl; } cout <<"Spelarens kort:"<<endl; cout << endl<< player.playerCards[0].getValue() <<" " << player.playerCards[0].getSuitString() << endl; cout << endl<< player.playerCards[1].getValue() <<" " << player.playerCards[1].getSuitString() << endl; cout << endl<< player.playerCards[2].getValue() <<" " << player.playerCards[2].getSuitString() << endl; return 0; }

/johan

Permalänk
Medlem

problemet är att när du anropar takeCard så skapas implicit en ny kortBunt via en automatiskt utlagd copy-konstruktor och på den kopian anropas giveCard. vad du vill göra är att göra om parametern till referens:

void takeCard(kortBunt& kortBuntTest) { ... }

Permalänk
Citat:

Ursprungligen inskrivet av helmet
problemet är att när du anropar takeCard så skapas implicit en ny kortBunt via en automatiskt utlagd copy-konstruktor och på den kopian anropas giveCard. vad du vill göra är att göra om parametern till referens:

void takeCard(kortBunt& kortBuntTest) { ... }

Tackar, jag ska kolla på detta.

Och när jag tänker efter så måste vektorn som håller ordning på korten vara dynamisk, då en spelare inte nödvändigtvis behöver ge bort det översta kortet.

Men jag är som sagt bara ute efter att lära mig OOP genom att experimentera och ha mig, även om programmen blir lite underligt kodade. hehe

EDIT:
Jag testade och det fungerade perfekt, tackar så hemsk mycket! Det är just sånt här som jag tycker är svårt att läsa sig till utan man behöver upptäcka det själv.

Permalänk
Medlem

att blanda teori och praktik är det bästa sättet att lära sig

du kan testa min teori genom att lägga till en explicit copy-konstruktor innan du ändrar parametern till en referens, typ:

public:
kortBunt (const kortBunt& k) {
cout << "in cc" << endl;
*this = k;
}

Permalänk
Citat:

Ursprungligen inskrivet av helmet
att blanda teori och praktik är det bästa sättet att lära sig

du kan testa min teori genom att lägga till en explicit copy-konstruktor innan du ändrar parametern till en referens, typ:

public:
kortBunt (const kortBunt& k) {
cout << "in cc" << endl;
*this = k;
}

Ja då ser jag felet tydligt och som sagt tackar så mycket för hjälpen. Att koda själv utan någon tidspress eller resultatkrav och bara leka är helt underbart.

Sedan ska jag göra en sorteringsalgoritm för mitt kortspel, vilket kommer bli lite klurigt och lärorikt. Det blir väl en Bubble sort variant, men det ger mycket "fingerfärdighet" att få det effektivt, vilket jag just är ute efter att lära mig.