Thanks guys! And Harag, in case you still would like to see the code, I’ll just dump it here real quick:
Here is the Solitaire class… My game class just creates an instance of this and updates/draw it… This way, I can add other games later, no problem…
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
using System.Security.Cryptography;
namespace Kabale
{
class Solitaire : GameType
{
// these are the positions for interface, and the various components of the game, like specific card stacks…
//----------------------------------------------------------------------------------------------------------------
static Vector2 star_pos = new Vector2(10,10);
static Vector2 star_pos2 = new Vector2(1520, 10);
static Vector2 star_origin = new Vector2(32,32);
static Texture2D table;
static Texture2D star;
Stack deck;
Stack pile ;
Stack ace_1;
Stack ace_2;
Stack ace_3;
Stack ace_4;
List<Stack> kingStacks;
Stack held_stack; // this is the stack held or lifted by the player...
Stack return_stack; // this is where the held stack was liftet from, so they know were to return to if action is cancelled.
public static void LoadContent(ContentManager content)
{
table = content.Load<Texture2D>(".\\table");
star = content.Load<Texture2D>(".\\star");
}
// Variables used for "luck of the shuffle"....
//-------------------------------------------------------
static RandomNumberGenerator rng;
static byte[] rand; //Set the length of this array to
// the number of random numbers you want
static RandomNumberGenerator _rand = RandomNumberGenerator.Create();
static int dice_roll;
void Shuffle(Stack stack_to_shuffle)
{
{
rng = RandomNumberGenerator.Create();
rand = new byte[4];
rng.GetBytes(rand);
Stack tempStack = new Stack(Vector2.Zero);
while (deck.cards.Count >0)
{
dice_roll = CommonMethods.RandomNext(0, deck.cards.Count );
tempStack.Add(deck.cards[dice_roll]);
deck.cards.RemoveAt(dice_roll);
}
foreach (Card card in tempStack.cards)
{
deck.Add(card);
}
}
}
public Solitaire()
{
New_Game();
}
void New_Game()
{
held_stack = new Stack(Vector2.Zero);
held_stack.Open();
return_stack = new Stack(Vector2.Zero);
float border_x = 50;
float border_y = 50;
float spacing_x = Card.card_dimensions.X + border_x;
float spacing_y = Card.card_dimensions.Y + border_y;
deck = new Stack(new Vector2(border_x, border_y));
pile = new Stack(new Vector2(border_x + spacing_x, border_y));
ace_1 = new Stack(new Vector2(border_x + (3 * spacing_x), border_y));
ace_2 = new Stack(new Vector2(border_x + (4 * spacing_x), border_y));
ace_3 = new Stack(new Vector2(border_x + (5 * spacing_x), border_y));
ace_4 = new Stack(new Vector2(border_x + (6 * spacing_x), border_y));
kingStacks = new List<Stack>();
for (int i = 0; i < 7; i++)
{
kingStacks.Add(new Stack(new Vector2(i * spacing_x + border_x, border_y + spacing_y)));
kingStacks.Last().Open();
}
// add all the cards
for (int i = 1; i < 14; i++)
{
deck.Add(new Card("Diamonds", Card.red_color, i));
}
for (int i = 1; i < 14; i++)
{
deck.Add(new Card("Clovers", Card.black_color, i));
}
for (int i = 1; i < 14; i++)
{
deck.Add(new Card("Hearts", Card.red_color, i));
}
for (int i = 1; i < 14; i++)
{
deck.Add(new Card("Spades", Card.black_color, i));
}
//shuffle here
Shuffle(deck);
Shuffle(deck);
Shuffle(deck);
//add to king stacks
kingStacks[0].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[1].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[2].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[3].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[4].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[1].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[2].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[3].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[4].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[2].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[3].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[4].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[3].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[4].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[4].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[5].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
kingStacks[6].Add(deck.cards[0]);
deck.cards.RemoveAt(0);
foreach (Stack kings in kingStacks)
{
if (kings.cards.Count > 0)
kings.cards.Last().visible = true;
}
}
public override void ReleaseLeft(Vector2 click_pos)
{
if (mouse_held && held_stack.cards.Count() > 0)
{
mouse_held = false;
//try release on kings place !
bool lands_on_kingstack = false;
foreach (Stack kingstack in kingStacks)
{
if (kingstack.my_rect.Intersects(held_stack.my_rect))
{
if (kingstack.cards.Count == 0)
{
if (held_stack.cards[0].my_value == 13)
{
foreach (Card card in held_stack.cards)
kingstack.cards.Add(card);
kingstack.Update();
held_stack.cards.Clear();
lands_on_kingstack = true;
break;
}
}
else
{
if (kingstack.cards.Last().my_color != held_stack.cards[0].my_color && kingstack.cards.Last().my_value == held_stack.cards[0].my_value + 1)
{
foreach (Card card in held_stack.cards)
kingstack.Add(card);
//kingstack.Update();
held_stack.cards.Clear();
lands_on_kingstack = true;
break;
}
}
}
}
if (lands_on_kingstack)
{
// already done, just here for the else statements....
}
//release on ace piles
else if ((ace_1.my_rect.Intersects(held_stack.my_rect)) && ((ace_1.cards.Count == 0 && held_stack.cards[0].my_value == 1) || (ace_1.cards.Count > 0 && ace_1.cards.Last().my_value + 1 == held_stack.cards[0].my_value && ace_1.cards.Last().my_type == held_stack.cards[0].my_type)))
{
ace_1.cards.Add(held_stack.cards[0]);
ace_1.Update();
held_stack.cards.Clear();
}
else if ((ace_2.my_rect.Intersects(held_stack.my_rect)) && ((ace_2.cards.Count == 0 && held_stack.cards[0].my_value == 1) || (ace_2.cards.Count > 0 && ace_2.cards.Last().my_value + 1 == held_stack.cards[0].my_value && ace_2.cards.Last().my_type == held_stack.cards[0].my_type)))
{
ace_2.cards.Add(held_stack.cards[0]);
ace_2.Update();
held_stack.cards.Clear();
}
else if ((ace_3.my_rect.Intersects(held_stack.my_rect)) && ((ace_3.cards.Count == 0 && held_stack.cards[0].my_value == 1) || (ace_3.cards.Count > 0 && ace_3.cards.Last().my_value + 1 == held_stack.cards[0].my_value && ace_3.cards.Last().my_type == held_stack.cards[0].my_type)))
{
ace_3.cards.Add(held_stack.cards[0]);
ace_3.Update();
held_stack.cards.Clear();
}
else if ((ace_4.my_rect.Intersects(held_stack.my_rect)) && ((ace_4.cards.Count == 0 && held_stack.cards[0].my_value == 1) || (ace_4.cards.Count > 0 && ace_4.cards.Last().my_value + 1 == held_stack.cards[0].my_value && ace_4.cards.Last().my_type == held_stack.cards[0].my_type)))
{
ace_4.cards.Add(held_stack.cards[0]);
ace_4.Update();
held_stack.cards.Clear();
}
else
{
foreach (Card card in held_stack.cards)
{
return_stack.Add(card);
}
held_stack.cards.Clear();
}
foreach (Stack k_stack in kingStacks)
{
if (return_stack == k_stack)
{
if (k_stack.cards.Count > 0)
k_stack.cards.Last().visible = true;
}
}
}
}
// variables used for mouse movement and drag/drop interface.
bool mouse_held = false;
Vector2 mouseGrabDIFF;
//SET COLORS, like if you want spades and clovers to be green, and hearts and diamonds to be blue.
// The card icon sprites are white, and will be drawn as specified here:
//-----------------------------------------------------------------------------------------------------------------------
void ChangeCardColors(Color red, Color black)
{
foreach ( Stack k in kingStacks)
{
foreach (Card card in k.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
}
foreach (Card card in deck.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
foreach (Card card in pile.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
foreach (Card card in ace_1.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
foreach (Card card in ace_2.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
foreach (Card card in ace_3.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
foreach (Card card in ace_4.cards)
{
if (card.my_type == "Hearts" || card.my_type == "Diamonds")
card.my_color = red;
else
card.my_color = black;
}
}
public override void LeftClick(Vector2 click_POS)
{
mouse_held = true;
if (Vector2.Distance(click_POS, star_pos) < 20)
{
New_Game();
}
else if (Vector2.Distance(click_POS, star_pos2) < 20)
{
//set colors
Card.current_back += 1;
if (Card.current_back > Card.backs.Count-1)
{
Card.current_back = 0;
}
switch (Card.current_back)
{
case 0:
Card.red_color = Color.Red;
Card.black_color = Color.Black;
ChangeCardColors(Card.red_color,Card.black_color);
Card.pic_color = Color.Wheat;
Card.back_color = Color.White;
Card.face_color = Color.Wheat;
break;
case 1:
Card.pic_color = Color.White;
Card.back_color = Color.White;
Card.face_color = Color.White;
Card.red_color = Color.Red;
Card.black_color = Color.Black;
ChangeCardColors(Card.red_color, Card.black_color);
break;
case 2:
Card.red_color = Color.Red;
Card.black_color = Color.Black;
ChangeCardColors(Card.red_color, Card.black_color);
Card.pic_color = Color.White;
Card.back_color = Color.White;
Card.face_color = Color.White;
break;
case 3:
Card.red_color = new Color(240, 50, 0);
Card.black_color = new Color(10,10,10);
ChangeCardColors(Card.red_color, Card.black_color);
Card.pic_color = new Color(250, 100, 30);
Card.back_color = Color.White;
Card.face_color = Color.WhiteSmoke;
break;
case 4:
Card.red_color = new Color(240, 50, 0);
Card.black_color = new Color(0, 0, 0);
ChangeCardColors(Card.red_color, Card.black_color);
Card.pic_color = new Color(200, 70, 0);
Card.back_color = Color.White;
Card.face_color = Color.WhiteSmoke;
break;
case 5:
Card.red_color = new Color(205,20,0);
Card.black_color = Color.Black;
ChangeCardColors(Card.red_color, Card.black_color);
Card.pic_color = Color.Brown;
Card.back_color = Color.White;
Card.face_color = new Color(0.9f,0.9f,0.9f);
break;
case 6:
Card.pic_color = Color.White;
Card.back_color = Color.White;
Card.face_color = Color.White;
Card.red_color = Color.Red;
Card.black_color = Color.Black;
ChangeCardColors(Card.red_color, Card.black_color);
break;
}
}
foreach (Stack kingstack in kingStacks)
{
bool got_one = false;
if (kingstack.my_rect.Contains(click_POS))
{
held_stack.my_pos = kingstack.my_pos;
// BUGGY SHIT...... click in the stack, and if that card is visible, it, and every card AFTER it, are added to the held stack....
for (int i = 0; i < kingstack.cards.Count ; i++)
{
if (got_one == false)
{
if (kingstack.cards[i].visible)
{
if ((kingstack.cards[i].my_pos.Y < click_POS.Y && click_POS.Y - kingstack.cards[i].my_pos.Y < Stack.cardSpacing) || (i == kingstack.cards.Count -1 && kingstack.cards[i].my_rect.Contains(click_POS)) ) //my_rect.Contains(click_POS))
{
got_one = true;
return_stack = kingstack;
mouseGrabDIFF = click_POS - kingstack.cards[i].my_pos;
held_stack.Add(kingstack.cards[i]);
}
}
}
else // got_one == true
{
held_stack.Add(kingstack.cards[i]);
}
}
foreach (Card card in held_stack.cards)
{
kingstack.cards.Remove(card);
kingstack.Update();
}
}
}
if (held_stack.cards.Count > 0)
{
// just for the if structure
}
//click on deck, draw next card
else if (deck.my_rect.Contains(click_POS))
{
if (deck.cards.Count > 2)
{
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count - 1);
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count - 1);
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count - 1);
}
else if (deck.cards.Count == 2)
{
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count -1);
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count - 1);
}
else if (deck.cards.Count == 1)
{
pile.Add(deck.cards.Last());
pile.cards.Last().visible = true;
deck.cards.RemoveAt(deck.cards.Count - 1);
}
// if the deck is EMPTY, take the pile as the deck...
else if (deck.cards.Count == 0)
{
if (pile.cards.Count > 0)
{
foreach (Card c in pile.cards)
{
c.visible = false;
deck.Add(c);
}
deck.cards.Reverse();
pile.cards.Clear();
}
}
}
//click on the pile add the card to lifted_stack, subtract it from the old stack. Set return stack, home of lifted stack......
else if (pile.my_rect.Contains(click_POS))
{
if (pile.cards.Count > 0)
{
mouseGrabDIFF = click_POS - pile.my_pos;
held_stack.Add(pile.cards[pile.cards.Count() - 1]);
pile.cards.RemoveAt(pile.cards.Count() - 1);
return_stack = pile;
}
}
}
static Color starColor = new Color(1.0f,1.0f,1.0f);
static float g = 1f;
static float b = 1f;
public override void Update(MouseState currentMouse)
{
if (held_stack.cards.Count > 0)
{
held_stack.my_pos.X = currentMouse.X - mouseGrabDIFF.X;
held_stack.my_pos.Y = currentMouse.Y - mouseGrabDIFF.Y;
held_stack.Update();
}
if (Vector2.Distance(new Vector2(currentMouse.Position.X, currentMouse.Y), star_pos) < 20)
{
starAlpha = 0.65f;
}
else
{
if (starAlpha > 0.15f)
starAlpha -= 0.01f;
if (Vector2.Distance(new Vector2(currentMouse.Position.X, currentMouse.Y), star_pos2) < 20)
{
if (b > 0f)
{
b -= 0.02f;
g -= 0.02f;
starColor = new Color(b,g,1f);
}
}
else
{
if (b < 1f)
{
b += 0.02f;
g += 0.02f;
starColor = new Color(b, g, 1f);
}
}
}
}
static float starAlpha = 1.0f;
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(table, new Rectangle(0,0,1530,900), Color.White);
spriteBatch.Draw(star, star_pos,null,Color.White*starAlpha,0,star_origin,0.777f,SpriteEffects.None,0);
spriteBatch.Draw(star, star_pos2, null, starColor * (1.2f-g), 0, star_origin, 0.777f, SpriteEffects.None, 0);
spriteBatch.Draw(Card.face, new Rectangle(deck.my_rect.X , deck.my_rect.Y , deck.my_rect.Width, deck.my_rect.Height), Color.Black * 0.2f);
spriteBatch.Draw(Card.face, new Rectangle(pile.my_rect.X , pile.my_rect.Y , pile.my_rect.Width, pile.my_rect.Height), Color.Black * 0.2f);
spriteBatch.Draw(Card.face, new Rectangle(ace_1.my_rect.X , ace_1.my_rect.Y , ace_1.my_rect.Width, ace_1.my_rect.Height), Color.Black * 0.2f);
spriteBatch.Draw(Card.face, new Rectangle(ace_2.my_rect.X, ace_2.my_rect.Y, ace_2.my_rect.Width, ace_2.my_rect.Height), Color.Black * 0.2f);
spriteBatch.Draw(Card.face, new Rectangle(ace_3.my_rect.X, ace_3.my_rect.Y, ace_3.my_rect.Width, ace_3.my_rect.Height), Color.Black * 0.2f);
spriteBatch.Draw(Card.face, new Rectangle(ace_4.my_rect.X, ace_4.my_rect.Y, ace_4.my_rect.Width, ace_4.my_rect.Height), Color.Black * 0.2f);
//SHADOW OF EACH DECK
if (deck.cards.Count > 0)
spriteBatch.Draw(Card.face, new Rectangle(deck.my_rect.X - deck.cards.Count, deck.my_rect.Y + 4, deck.my_rect.Width+ deck.cards.Count, deck.my_rect.Height), Color.Black * 0.2f);
if (pile.cards.Count > 0)
spriteBatch.Draw(Card.face, new Rectangle(pile.my_rect.X - pile.cards.Count, pile.my_rect.Y + 4, pile.my_rect.Width + pile.cards.Count, pile.my_rect.Height), Color.Black * 0.2f);
foreach (Stack kingStack in kingStacks)
{
if (kingStack.cards.Count == 0)
spriteBatch.Draw(Card.face, kingStack.my_rect, Color.Black * 0.2f);
else
{
spriteBatch.Draw(Card.face, new Rectangle(kingStack.my_rect.X - 4, kingStack.my_rect.Y + 4, kingStack.my_rect.Width, kingStack.my_rect.Height), Color.Black * 0.2f);
kingStack.Draw(spriteBatch);
}
}
if (ace_1.cards.Count > 0)
{
spriteBatch.Draw(Card.face, new Rectangle(ace_1.my_rect.X - ace_1.cards.Count, ace_1.my_rect.Y + 4, ace_1.my_rect.Width+ace_1.cards.Count, ace_1.my_rect.Height), Color.Black * 0.2f);
ace_1.cards[ace_1.cards.Count() - 1].Draw(spriteBatch);
}
if (ace_2.cards.Count > 0)
{
spriteBatch.Draw(Card.face, new Rectangle(ace_2.my_rect.X - ace_2.cards.Count, ace_2.my_rect.Y + 4, ace_2.my_rect.Width + ace_2.cards.Count, ace_2.my_rect.Height), Color.Black * 0.2f);
ace_2.cards[ace_2.cards.Count() - 1].Draw(spriteBatch);
}
if (ace_3.cards.Count > 0)
{
spriteBatch.Draw(Card.face, new Rectangle(ace_3.my_rect.X - ace_3.cards.Count, ace_3.my_rect.Y + 4, ace_3.my_rect.Width + ace_3.cards.Count, ace_3.my_rect.Height), Color.Black * 0.2f);
ace_3.cards[ace_3.cards.Count() - 1].Draw(spriteBatch);
}
if (ace_4.cards.Count > 0)
{
spriteBatch.Draw(Card.face, new Rectangle(ace_4.my_rect.X - ace_4.cards.Count, ace_4.my_rect.Y + 4, ace_4.my_rect.Width + ace_4.cards.Count, ace_4.my_rect.Height), Color.Black * 0.2f);
ace_4.cards[ace_4.cards.Count() - 1].Draw(spriteBatch);
}
if (deck.cards.Count > 0)
deck.cards[deck.cards.Count()-1].Draw(spriteBatch);
if (pile.cards.Count > 0)
pile.cards[pile.cards.Count()-1].Draw(spriteBatch);
if (held_stack.cards.Count > 0)
{
spriteBatch.Draw(Card.face, new Rectangle(held_stack.my_rect.X - 10, held_stack.my_rect.Y + 10, held_stack.my_rect.Width, held_stack.my_rect.Height), Color.Black * 0.2f);
foreach (Card card in held_stack.cards)
card.Draw(spriteBatch);
}
}
}
}