First, I should point out that I'm not actually using C++ or C-- I'm using C#. There's no forum for C#, though, and C# is so similar to C++ that I think "the experts" will likely be able to help me anyway. I'm using Visual Studio .NET 2005.
I've implemented operator overloading and deep copying, but I also need to implement a SortDeck function that will take a deck of cards and sort it from Clubs to Spades, Ace to King using the operator overloading that I've implemented and then I need my client code to display this sorted deck the same way I've displayed the regular deck and the cloned deck.
I feel like this should be pretty simple (I only need one more function!), especially in comparison to what I've done so far, but I just can't seem to wrap my head around it. Any help would be greatly appreciated!CODE
using System;
using System.Collections.Generic;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
namespace CardsClass
{
public class Cards : CollectionBase, ICloneable
{
public object Clone()
{
Cards newCards = new Cards();
foreach (Card sourceCard in List)
{
newCards.Add(sourceCard.Clone() as Card);
}
return newCards;
}
public void Add(Card newCard)
{
List.Add(newCard);
}
public void Remove(Card oldCard)
{
List.Remove(oldCard);
}
public Card this[int cardIndex]
{
get
{
return (Card)List[cardIndex];
}
set
{
List[cardIndex] = value;
}
}
// Utility method for copying card instances into another Cards
// instance - used in Deck.Shuffle(). This implementation assumes that
// source and target collections are the same size.
public void CopyTo(Cards targetCards)
{
for (int index = 0; index < this.Count; index++)
{
targetCards[index] = this[index];
}
}
// Check to see if the Cards collection contains a particular card.
// This calls the Contains method of the ArrayList for the collection,
// which you access through the InnerList property.
public bool Contains(Card card)
{
return InnerList.Contains(card);
}
}
public class Card : ICloneable
{
// Flag for trump usage. If true, trumps are valued higher
// than cards of other suits.
public static bool useTrumps = false;
// Trump suit to use if useTrumps is true.
public static int trump = (int)Suits.Club;
// Flag that determines whether Aces are higher than Kings or lower
// than deuces.
public static bool isAceHigh = true;
public object Clone()
{
return MemberwiseClone();
}
public static bool operator ==(Card card1, Card card2)
{
return (card1.suit == card2.suit) && (card1.rank == card2.rank);
}
public static bool operator !=(Card card1, Card card2)
{
return !(card1 == card2);
}
public override bool Equals(object card)
{
return this == (Card)card;
}
public override int GetHashCode()
{
return 13 * (int)rank + (int)suit;
}
public static bool operator >(Card card1, Card card2)
{
if (card1.suit == card2.suit)
{
if (isAceHigh)
{
if (card1.rank == 0)
{
if (card2.rank == 0)
return false;
else
return true;
}
else
{
if (card2.rank == 0)
return false;
else
return (card1.rank > card2.rank);
}
}
else
{
return (card1.rank > card2.rank);
}
}
else
{
if (useTrumps && (card2.suit == Card.trump))
return false;
else
return true;
}
}
public static bool operator <(Card card1, Card card2)
{
return !(card1 >= card2);
}
public static bool operator >=(Card card1, Card card2)
{
if (card1.suit == card2.suit)
{
if (isAceHigh)
{
if (card1.rank == (int)Ranks.Ace)
{
return true;
}
else
{
if (card2.rank == (int)Ranks.Ace)
return false;
else
return (card1.rank >= card2.rank);
}
}
else
{
return (card1.rank >= card2.rank);
}
}
else
{
if (useTrumps && (card2.suit == Card.trump))
return false;
else
return true;
}
}
public static bool operator <=(Card card1, Card card2)
{
return !(card1 > card2);
}
//properites of a card
private int rank, suit;
private int back;
[DllImport("cards.dll")]
private static extern bool cdtDraw(IntPtr hdc, Int32 x, Int32 y, Int32 cd,
Int32 md, UInt32 rgbBgnd);
[DllImport("cards.dll")]
//private unsafe
private static extern bool cdtInit(out int pdxCard, out int pdyCard);
//Same as cdtDraw except that cards may be sized by dx and dy
[DllImport("cards.dll")]
private static extern bool cdtDrawExt(IntPtr hdc, Int32 x, Int32 y, Int32 dx,
Int32 dy, Int32 cd, Int32 md, UInt32 rgbBgnd);
//Draws animation on cards that support animation
[DllImport("cards.dll")]
private static extern bool cdtAnimate(IntPtr hdc, Int32 cd, Int32 x, Int32 y, Int32 ispr);
//Call this function with application terminates
[DllImport("cards.dll")]
private static extern void cdtTerm();
// cdtDraw and cdtDrawExt mode flags
public const int mdFaceUp = 0; //Draw card face up, card to draw specified by cd
public const int mdFaceDown = 1; //Draw card face down, back specified by cd cdFaceDownFirst..cdFaceDownLast)
public const int mdHilite = 2; //Same as FaceUp except drawn with NOTSRCCOPY mode
public const int mdGhost = 3; //Draw a ghost card -- for ace piles
public const int mdRemove = 4; //draw background specified by rgbBgnd
public const int mdInvisibleGhost = 5; //?
public const int mdDeckX = 6; //Draw X card (end of deck marker)
public const int mdDeckO = 7; //Draw O card (end of deck marker)
//Enumeration representing above Mode Constants
public enum modes
{
Up = mdFaceUp, Down = mdFaceDown, Hilite = mdHilite, Ghost = mdGhost,
Remove = mdRemove, Invisible = mdInvisibleGhost, DeckX = mdDeckX,
DeckO = mdDeckO
};
//Suit and card indices. Orders of BOTH are important
public const int suClub = 0;
public const int suDiamond = 1;
public const int suHeart = 2;
public const int suSpade = 3;
public const int suMax = 4;
public const int suFirst = suClub;
//Enumeration representing above Suit Constants
public enum Suits { Club = suClub, Diamond = suDiamond, Heart = suHeart, Spade = suSpade, First = suFirst };
public const int raAce = 0;
public const int raTwo = 1;
public const int raThree = 2;
public const int raFour = 3;
public const int raFive = 4;
public const int raSix = 5;
public const int raSeven = 6;
public const int raEight = 7;
public const int raNine = 8;
public const int raTen = 9;
public const int raJack = 10;
public const int raQueen = 11;
public const int raKing = 12;
public const int raMax = 13;
public const int raNil = 15;
public const int raFirst = raAce;
public enum Ranks
{
Ace = raAce, Two = raTwo, Three = raThree, Four = raFour, Five = raFive,
Six = raSix, Seven = raSeven, Eight = raEight, Nine = raNine, Ten = raTen,
Jack = raJack, Queen = raQueen, King = raKing, Max = raMax, Nil = raNil, First = raFirst
};
/*-----------------------------------------------------------------------------
| Face down cds
-----------------------------------------------------------------------------*/
public const int cdFaceDown1 = 54;
public const int cdFaceDown2 = 55;
public const int cdFaceDown3 = 56;
public const int cdFaceDown4 = 57;
public const int cdFaceDown5 = 58;
public const int cdFaceDown6 = 59;
public const int cdFaceDown7 = 60;
public const int cdFaceDown8 = 61;
public const int cdFaceDown9 = 62;
public const int cdFaceDown10 = 63;
public const int cdFaceDown11 = 64;
public const int cdFaceDown12 = 65;
public const int cdFaceDownFirst = cdFaceDown1;
public const int cdFaceDownLast = cdFaceDown12;
public enum Backs { back1 = 54, back2, back3, back4, back5, back6, back7, back8, back9, back10, back11, back12 };
//Default Constructor
public Card()
{
rank = raAce;
suit = suClub;
back = cdFaceDown1;
}
//Non-default Constructor: Initializes card to specific rank and suit
public Card(int ra, int su)
{
rank = ra;
suit = su;
back = cdFaceDown1;
}
public bool Draw(IntPtr hdc, int x, int y, modes md)
{
if (md == modes.Up)
return cdtDraw(hdc, x, y, Cd(rank, suit), (int)md, 0);
return cdtDraw(hdc, x, y, Back, (int)md, 0);
}
public bool Initialize()
{
int dxcard, dycard;
//unsafe
//{
return cdtInit(out dxcard, out dycard);
//}
}
public int Back
{
get
{
return back;
}
set
{
back = value;
}
}
public void Terminate()
{
cdtTerm();
}
public int Suit
{
set
{
suit = value;
}
get
{
return suit;
}
}
public int Rank
{
set
{
rank = value;
}
get
{
return rank;
}
}
//return card from rank and suit
public int Cd(int ra, int su)
{
return (((ra) << 2) | (su));
}
}
public class Deck : ICloneable
{
private Cards cards = new Cards();
public object Clone()
{
Deck newDeck = new Deck(cards.Clone() as Cards);
return newDeck;
}
private Deck(Cards newCards)
{
cards = newCards;
}
public Deck()
{
for (int i = 0; i < 4; i++) //suit
for (int j = 0; j < 13; j++) //rank
cards.Add(new Card(j,i)); //rank/suit
}
public void Show(IntPtr hdc, int x, int y, Card.modes md)
{
for (int i = 0; i < 52; i++)
{
cards[i].Draw(hdc, x * i, y, md);
}
}
public void Shuffle()
{
Cards newDeck = new Cards();
bool[] assigned = new bool[52];
Random sourceGen = new Random();
for (int i = 0; i < 52; i++)
{
int sourceCard = 0;
bool foundCard = false;
while (foundCard == false)
{
sourceCard = sourceGen.Next(52);
if (assigned[sourceCard] == false)
foundCard = true;
}
assigned[sourceCard] = true;
newDeck.Add(cards[sourceCard]);
}
newDeck.CopyTo(cards);
}
}
}
There is a reference from this client code to the .dll file created when you compile the previous code. My client code so far: CODE
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CardsClass;
namespace ClientCode
{
public partial class Form1 : Form
{
Deck deck;
Deck shuffleDeck;
Deck clonedDeck;
public Form1()
{
InitializeComponent();
deck = new Deck();
shuffleDeck = new Deck();
shuffleDeck.Shuffle();
clonedDeck = (Deck)deck.Clone();
Deck sortedDeck = new Deck();
// sortedDeck.SortDeck();
}
protected override void OnPaint(PaintEventArgs e)
{
IntPtr hdc = e.Graphics.GetHdc();
Card card1 = new Card();
card1.Initialize();
deck.Show(hdc, 20, 10, Card.modes.Up);
shuffleDeck.Show(hdc, 20, 200, Card.modes.Up);
clonedDeck.Show(hdc, 20, 310, Card.modes.Up);
//sortedDeck.Show(hdc, 20, 310, Card.modes.Up);
}
}
}