|
In order of no progress to done:
Red,
Orange,
Yellow,
Blue,
Light blue,
Green,
Light green.
Last updated 2/12/09 at 12:01 am PST
Cripes! 2.0 -- See the Class Layout
Arenamatic Code w/ cConsole
 Tactics (and Advice) |
Posted - 7/18/2007 8:20:45 PM | Well, after some of the people over at #gamedev looked at my code and pointed out at TON of "design errors" (such as the use of BAD_SUIT, BAD_VALUE cards as sentinels for the end of the deck), they told me to mostly scrap the entirety of CardDeck, and change some of the details of Card.h - Card itself was fine - by tkaing out the BAD_ values in the enums, and JOKER in Suits.
So now I'm rewriting CardDeck as an inheritance tree, with base class Pile and derived classes Deck and Hand - yes, this wasn't my idea, which is why it sounds so good. Honestly, I haven't had much experience at all with inheritance, but if I can pull this off, I'll be able to do my next project much more smoothly. It's a big redesign of cConsole.
I've got a design problem in my plan for cConsole though. I'm going to have a ConsoleBase class that contains the core Console info (like the buffer), but I need a way for both of its derived classes to be able to access the the exact same info in it.
For example, if ConsoleBase has derived classes ConsoleInput and ConsoleOutput (not the names I'll use, just an example), and an ConsoleInput is created, it should initialize the ConsoleBase class if it isn't already. Then, if ConsoleOutput is instatiated, it should just use the ConsoleBase info that's already there, rather then creating another instance.
Could that be solved with static members in ConsoleBase? The members would have to be private to keep the derived classes from inheriting them, though. That would keep the derived classes from using them at all. =| Would it work if I made the derived classes friends of the base class? Is that even allowed?
Please comment and help =|
| |
 A new level of geekdom |
Posted - 7/15/2007 4:13:25 AM | Look at the bottom of my journal before you read any further. Then proceed to comment on my geekiness.
Done? No? Look again.
Hex and Celestial countdowns from THE LAST MIMZY. <_>
In less interesting news, I'm redoing CardDeck almost completely.
| |
 CardDeck |
Posted - 7/14/2007 2:58:12 PM | Over the past few days I've been slimming down CardDeck, and trying to fix some inconsistencies I've noticed (like the previously mentioned BAD_SUIT, BAD_VALUE cards when I know there's still more cards). If I clear up some of the clutter, though, maybe I can see what's going wrong.
Well, I don't know why I did it in the first place, but I had a size variable to track the vector size. I think it was because I didn't want to include the "BADCARD" at the end of the vector. I removed the size variable and changed all references to it to "deck.size()-1". Definitely a lot easier than adding and subtracting from the size every time cards are added or drawn.
So right now I'm fairly happy with how CardDeck is looking. The only thing I wish I could improve more is operator=, which I'm told should call the copy constructor so as to keep from repeating code. I'm sort of stumped on that - I was told how on #gamedev, but I forgot. <_< - but it looks OK enough.
Here's the current implementation of Card and CardDeck. I don't think Card can get much better, it's too simple of a class. :P
Card.h
namespace Twisol
{
namespace Suits
{
enum Suit
{
BAD_SUIT, DIAMOND,
HEART, CLUB,
SPADE, JOKER
};
}
namespace Values
{
enum Value
{
BAD_VALUE, ACE, TWO, THREE, FOUR,
FIVE, SIX, SEVEN, EIGHT, NINE,
TEN, JACK, QUEEN, KING, JOKER
};
}
class Card
{
private:
Suits::Suit suit;
Values::Value value;
public:
Card();
Card(Suits::Suit _suit, Values::Value _value);
Suits::Suit Suit() const;
Values::Value Value() const;
bool operator==(const Card& _card) const
{
if (this->suit == _card.suit && this->value == _card.value)
return true;
else
return false;
}
bool operator!=(const Card& _card) const
{
if (this->suit != _card.suit || this->value == _card.value)
return true;
else
return false;
}
};
}
Card.cpp
#include "Card.h"
namespace Twisol
{
Card::Card(Suits::Suit _suit, Values::Value _value)
{
if (_suit == Suits::BAD_SUIT || _suit > Suits::JOKER)
suit = Suits::BAD_SUIT;
else
suit = _suit;
if (_value == Values::BAD_VALUE || _value > Values::JOKER)
value = Values::BAD_VALUE;
else
value = _value;
}
Card::Card()
{
suit = Suits::BAD_SUIT;
value = Values::BAD_VALUE;
}
Suits::Suit Card::Suit() const
{
return suit;
}
Values::Value Card::Value() const
{
return value;
}
}
CardDeck.h
#pragma once
#include "Card.h"
#include <vector>
namespace Twisol
{
class CardDeck
{
private:
std::vector<Card> deck;
std::vector<Card>::iterator currentCard;
int size;
bool (*comp_func)(Card const& a, Card const& b);
static bool CardDeck::CardCompare(Card const& a, Card const& b);
void Init();
void InitDeck(const std::vector<Card>& Deck);
public:
CardDeck(bool jokers=false, bool empty=false);
CardDeck(std::vector<Card> _deck);
CardDeck(const CardDeck& _deck);
~CardDeck();
void SetComp(bool (*comp_func)(Card const& a, Card const& b));
int DeckSize() const;
int TotalSize() const;
void Shuffle();
void Sort();
Card Draw(bool remove=false);
void Empty();
void Add(Card _card);
void Add(std::vector<Card> _cards);
void Add(CardDeck _deck);
CardDeck const& operator= (CardDeck const& _deck);
};
}
CardDeck.cpp
#include "CardDeck.h"
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
namespace Twisol
{
Card BADCARD(Suits::BAD_SUIT, Values::BAD_VALUE);
CardDeck::CardDeck(bool jokers, bool empty)
{
if (!empty)
{
if (jokers)
deck.push_back(Card(Suits::JOKER, Values::JOKER));
for (int x = 1; x <= 4; x++)
for (int y = 1; y <= 13; y++)
deck.push_back(Card(Suits::Suit(x), Values::Value(y)));
if (jokers)
deck.push_back(Card(Suits::JOKER, Values::JOKER));
}
Init();
}
CardDeck::CardDeck(std::vector<Card> Deck)
{
InitDeck(Deck);
}
CardDeck::CardDeck(const CardDeck& Deck)
{
InitDeck(Deck.deck);
int diff = static_cast<int>(Deck.currentCard - Deck.deck.begin());
for (; diff > 0; diff--)
currentCard++;
}
void CardDeck::InitDeck(const std::vector<Card>& Deck)
{
for (int i = 0; i < static_cast<signed>(Deck.size()); i++)
{
deck.push_back(deck.at(i));
if (deck.at(i) == BADCARD)
break;
}
Init();
}
void CardDeck::Init()
{
deck.push_back(BADCARD);
currentCard = deck.begin();
comp_func = &CardDeck::CardCompare;
srand(static_cast<unsigned int>(time(NULL)));
}
CardDeck::~CardDeck()
{}
void CardDeck::SetComp(bool (*comp_func)(Card const& a, Card const& b))
{
if (comp_func != 0)
{
this->comp_func = comp_func;
}
}
int CardDeck::DeckSize() const
{
return TotalSize() - static_cast<int>(currentCard - deck.begin());
}
int CardDeck::TotalSize() const
{
return static_cast<int>(deck.size() - 1);
}
void CardDeck::Shuffle()
{
deck.pop_back();
std::random_shuffle(deck.begin(), deck.end());
currentCard = deck.begin();
deck.push_back(BADCARD);
}
bool CardDeck::CardCompare(Card const& a, Card const& b)
{
if (a.Value() > b.Value() ||
(a.Value() == b.Value() && a.Suit() > b.Suit()))
return true;
return false;
}
void CardDeck::Sort()
{
deck.pop_back();
std::sort(deck.begin(), deck.end(), comp_func);
currentCard = deck.begin();
deck.push_back(BADCARD);
}
Card CardDeck::Draw(bool remove)
{
Card card = *currentCard;
if (card != BADCARD && !remove)
currentCard++;
else if (remove)
currentCard = deck.erase(currentCard);
return card;
}
void CardDeck::Add(Card _card)
{
deck.pop_back();
deck.push_back(_card);
deck.push_back(BADCARD);
if (deck.capacity() <= 1)
{
deck.reserve(deck.size() + 20);
int diff = static_cast<int>(currentCard - deck.begin());
for (currentCard = deck.begin(); diff > 0; diff--)
currentCard++;
}
}
void CardDeck::Add(std::vector<Card> _cards)
{
deck.pop_back();
for (int i = 0; i < static_cast<signed>(_cards.size()); i++)
if (_cards.at(i) != BADCARD)
deck.push_back(_cards.at(i));
deck.push_back(BADCARD);
}
void CardDeck::Add(CardDeck _deck)
{
std::vector<Card> _cards = _deck.deck;
Add(_cards);
}
void CardDeck::Empty()
{
deck.clear();
deck.push_back(BADCARD);
currentCard = deck.begin();
}
CardDeck const& CardDeck::operator= (CardDeck const& _cardDeck)
{
deck.clear();
for (int i = 0; i < static_cast<signed>(Deck.size()); i++)
{
deck.push_back(deck.at(i));
if (deck.at(i) == BADCARD)
break;
}
currentCard = deck.begin();
int diff = static_cast<int>(_cardDeck.currentCard - _cardDeck.deck.begin());
for (; diff > 0; diff--)
currentCard++;
if (deck.at(static_cast<int>(deck.size())-1) != BADCARD)
deck.push_back(BADCARD);
return _cardDeck;
}
}
| |
 cConsole |
Posted - 7/13/2007 1:03:26 AM | This is a blast from the past... Apparently, Programmer16 studied my cConsole code to research how to "interface with the console", and wrote his own Console class (without the input capabilities, from what I can tell) for use in his recent Quickies games. That's pretty neat, and quite an ego boost for the amateur 'grammer to have his code used in someone else's program.
I'm definitely considering going back and improving it, since it's apparently a useful resource for Windows console programming. I'll get on it after I'm done with my Card classes. Hey, cConsole (renamed to Console when I do it) will definitely be handy at the very least for the C++ Workshop projects.
Uh.. that's actually why I originally wrote it. Talk about getting sidetracked.
Speaking of the Card classes, I haven't worked on them much lately, but CardDeck needs some reworking, since it's got some very strange bugs, like iterator invalidations which I had thought I'd fixed, and on Draw() getting an invalid card when I know there's cards in there.
Finally... it'd be nice to get a comment or two here? My last few entries garnered zilch.
| |
|
| S | M | T | W | T | F | S | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | | | | 16 | 17 | | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | |
OPTIONS
Track this Journal
ARCHIVES
August, 2009
July, 2009
March, 2009
February, 2009
December, 2008
November, 2008
October, 2008
August, 2008
July, 2008
June, 2008
May, 2008
April, 2008
November, 2007
July, 2007
June, 2007
May, 2007
April, 2007
March, 2007
February, 2007
December, 2006
October, 2006
September, 2006
July, 2006
May, 2006
April, 2006
|