7 Commits

Author SHA1 Message Date
Kayne Ruse
1a09f2a8f0 Added some newer art to rsc, but not using it yet 2013-03-10 09:09:59 +11:00
Kayne Ruse
81a36b3baa Added Codebase as a submodule 2013-02-02 23:44:57 +11:00
Kayne Ruse
ca8820ba78 Updated some function calls for compatability
Seems to be stable right now.
2013-01-22 03:51:08 +11:00
Kayne Ruse
83e564c80d Updating development files 2013-01-21 03:27:40 +11:00
Kayne Ruse
1a7a7a1f88 Updated Table's compatability 2013-01-21 03:25:08 +11:00
Kayne Ruse
440b13c413 Revamped the card system to use the newer graphics system 2013-01-21 03:14:37 +11:00
Kayne Ruse
c407add405 Switched to a newer grapgics system
Not using Codebase as a submodule, since this project is so small anyway.
2013-01-21 03:06:01 +11:00
25 changed files with 392 additions and 561 deletions

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "Hearts/Codebase"]
path = Hearts/Codebase
url = https://github.com/Ratstail91/Codebase.git

1
Hearts/Codebase Submodule

Submodule Hearts/Codebase added at 214d3f51c4

View File

@@ -273,36 +273,6 @@
RelativePath=".\base_engine.h" RelativePath=".\base_engine.h"
> >
</File> </File>
<File
RelativePath=".\image.cpp"
>
</File>
<File
RelativePath=".\image.h"
>
</File>
<File
RelativePath=".\image_manager.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\image_manager.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File <File
RelativePath=".\music.cpp" RelativePath=".\music.cpp"
> >
@@ -324,6 +294,162 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="Codebase"
>
<File
RelativePath=".\Codebase\animator.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\animator.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\bbox.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\bbox.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\config_utility.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\config_utility.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\delta.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\delta.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\frame_rate.cpp"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\frame_rate.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\image.cpp"
>
</File>
<File
RelativePath=".\Codebase\image.h"
>
</File>
<File
RelativePath=".\Codebase\vector2.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\Codebase\vector3.h"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
</Filter>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>

View File

@@ -1,7 +1,7 @@
/* File Name: card.cpp /* File Name: card.cpp
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 22/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,50 +23,52 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * A basic playing card. This also has the graphics built in.
*/ */
#include "card.h" #include "card.h"
Card::Card(int _suit, int _rank, SDL_Surface* _faceSurface, SDL_Surface* _backSurface): #include <stdexcept>
Image(_faceSurface),
suit(_suit), //-------------------------
rank(_rank), //Public access members
faceSurface(_faceSurface), //-------------------------
backSurface(_backSurface)
Card::Card(int s, int r, SDL_Surface* faceSurface, SDL_Surface* backSurface):
suit(s),
rank(r)
{ {
SetFace(UP); //images
SetWidth(73); face.SetSurface(faceSurface);
SetHeight(98); back.SetSurface(backSurface);
//set the face's clip (static values based on the card files)
face.SetClipX((rank - 1) * 73);
face.SetClipY((suit - 1) * 98);
face.SetClipW(73);
face.SetClipH(98);
face.SetClipW(73);
face.SetClipH(98);
SetFaceState(UP);
x = 0;
y = 0;
next = NULL; next = NULL;
} }
int Card::Suit() { //-------------------------
//Card game members
//-------------------------
int Card::GetSuit() {
return suit; return suit;
} }
int Card::Rank() { int Card::GetRank() {
return rank; return rank;
} }
int Card::SetFace(int _face) {
face = _face;
if (face == UP) {
SetSurface(faceSurface);
SetClipX((rank - 1) * 73);
SetClipY((suit - 1) * 98);
}
else {
SetSurface(backSurface);
SetClipX(0);
SetClipY(0);
}
return face;
}
int Card::GetFace() {
return face;
}
Card* Card::SetNext(Card* _next) { Card* Card::SetNext(Card* _next) {
return next = _next; return next = _next;
} }
@@ -76,11 +78,10 @@ Card* Card::GetNext() {
} }
bool Card::operator>(Card& card) { bool Card::operator>(Card& card) {
if (Suit() > card.Suit()) if (suit > card.suit)
return true; return true;
if (Suit() == card.Suit() && if (suit == card.suit && rank > card.rank)
Rank() > card.Rank())
return true; return true;
return false; return false;
@@ -89,3 +90,53 @@ bool Card::operator>(Card& card) {
bool Card::operator<(Card& card) { bool Card::operator<(Card& card) {
return card > *this; return card > *this;
} }
//-------------------------
//Graphics members
//-------------------------
int Card::SetFaceState(int face) {
if (face != UP && face != DOWN)
throw(std::invalid_argument("Unknown face value"));
return faceState = face;
}
int Card::GetFaceState() {
return faceState;
}
void Card::SetPos(Sint16 newX, Sint16 newY) {
x = newX;
y = newY;
}
Sint16 Card::SetX(Sint16 newX) {
return x = newX;
}
Sint16 Card::SetY(Sint16 newY) {
return y = newY;
}
Sint16 Card::GetX() {
return x;
}
Sint16 Card::GetY() {
return y;
}
Sint16 Card::GetWidth() {
return face.GetClipW();
}
Sint16 Card::GetHeight() {
return face.GetClipH();
}
void Card::DrawTo(SDL_Surface* const dest) {
if (faceState == UP)
face.DrawTo(dest, x, y);
else if (faceState == DOWN)
back.DrawTo(dest, x, y);
}

View File

@@ -1,7 +1,7 @@
/* File Name: card.h /* File Name: card.h
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 22/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,25 +23,25 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * A basic playing card. This also has the graphics built in.
*/ */
#ifndef KR_CARD_H_ #ifndef KR_CARD_H_
#define KR_CARD_H_ #define KR_CARD_H_
#include "SDL.h" #include "SDL.h"
#include "image.h"
#define ISCARD(CARD,RANK,SUIT) (CARD->Suit() == Card::SUIT && CARD->Rank() == Card::RANK) #include "Codebase/image.h"
class Card : public KAGE::Image { #define ISCARD(CARD,RANK,SUIT) (CARD->GetSuit() == Card::SUIT && CARD->GetRank() == Card::RANK)
class Card {
public: public:
/* Public access members */ /* Public access members */
Card(int suit, int rank, SDL_Surface* faceSurface, SDL_Surface* backSurface); Card(int suit, int rank, SDL_Surface* faceSurface, SDL_Surface* backSurface);
int Suit(); /* Card game memebers */
int Rank(); int GetSuit();
int GetRank();
int SetFace(int face);
int GetFace();
Card* SetNext(Card* next); Card* SetNext(Card* next);
Card* GetNext(); Card* GetNext();
@@ -49,6 +49,22 @@ public:
bool operator>(Card&); bool operator>(Card&);
bool operator<(Card&); bool operator<(Card&);
/* Graphics members */
int SetFaceState(int face);
int GetFaceState();
void SetPos(Sint16 x, Sint16 y);
Sint16 SetX(Sint16);
Sint16 SetY(Sint16);
Sint16 GetX();
Sint16 GetY();
Sint16 GetWidth();
Sint16 GetHeight();
void DrawTo(SDL_Surface* const);
/* Macros */
enum { enum {
UP = 1, DOWN UP = 1, DOWN
}; };
@@ -63,15 +79,17 @@ public:
TEN=9, JACK=10, QUEEN=11, KING=12, ACE=13 TEN=9, JACK=10, QUEEN=11, KING=12, ACE=13
}; };
protected: protected:
/* Protected access members */ /* Card game members */
const int suit; const int suit;
const int rank; const int rank;
int face; //TODO: "facestate"
SDL_Surface* faceSurface; //TODO: Image
SDL_Surface* backSurface;
Card* next; Card* next;
/* Graphics members */
int faceState;
Image face;
Image back;
Sint16 x, y;
}; };
#endif #endif

View File

@@ -1,7 +1,7 @@
/* File Name: card_list.cpp /* File Name: card_list.cpp
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,12 +23,11 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * A linked list of playing cards.
*/ */
#include <iostream>
#include <time.h>
#include "card_list.h" #include "card_list.h"
using namespace std;
#include <cstdlib>
//------------------------- //-------------------------
//Public access members //Public access members
@@ -144,8 +143,9 @@ Card* CardList::PassSlab(int first, int count) {
//------------------------- //-------------------------
void CardList::Shuffle() { void CardList::Shuffle() {
//TODO: rewrite this to avoid continuous calls to Size()
//New version //New version
srand((unsigned int)time(NULL)); //TODO: Remove this, initiate randomization in the Scene (and shuffle 3 times ;) )
iterator shuffleHead = NULL; iterator shuffleHead = NULL;
iterator prev = NULL; iterator prev = NULL;
@@ -207,7 +207,7 @@ void CardList::SortRank() {
while(it != NULL && Size()) { while(it != NULL && Size()) {
//first card //first card
if (it->Rank() > Read()->Rank()) { if (it->GetRank() > Read()->GetRank()) {
//insert the new card at the start of the list //insert the new card at the start of the list
it = Pass(); it = Pass();
it->SetNext(sortHead); it->SetNext(sortHead);
@@ -215,7 +215,7 @@ void CardList::SortRank() {
continue; continue;
} }
while (it->GetNext() != NULL && Read()->Rank() > it->GetNext()->Rank()) { while (it->GetNext() != NULL && Read()->GetRank() > it->GetNext()->GetRank()) {
//place the iterator just before the position to insert the card //place the iterator just before the position to insert the card
it = it->GetNext(); it = it->GetNext();
} }
@@ -243,7 +243,7 @@ Card* CardList::Head() {
return headCard; return headCard;
} }
void CardList::DrawAll(SDL_Surface* dest) { void CardList::DrawTo(SDL_Surface* dest) {
for (iterator it = headCard;it != NULL;it = it->GetNext()) for (iterator it = headCard;it != NULL;it = it->GetNext())
it->Draw(dest); it->DrawTo(dest);
} }

View File

@@ -1,7 +1,7 @@
/* File Name: card_list.h /* File Name: card_list.h
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,7 +23,7 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * A linked list of playing cards.
*/ */
#ifndef KR_CARDLIST_H_ #ifndef KR_CARDLIST_H_
#define KR_CARDLIST_H_ #define KR_CARDLIST_H_
@@ -47,7 +47,7 @@ public:
int Size(); int Size();
Card* Head(); Card* Head();
void DrawAll(SDL_Surface*); void DrawTo(SDL_Surface*);
typedef Card* iterator; typedef Card* iterator;
private: private:

View File

@@ -1,7 +1,7 @@
/* File Name: deck.cpp /* File Name: deck.cpp
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,55 +23,43 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * Create and destroy the cards in the game, and report if any are missing.
*/ */
#include <iostream>
#include "deck.h" #include "deck.h"
using namespace std;
#include <stdexcept>
Deck::Deck() { Deck::Deck() {
faceSurface = NULL; count = 0;
backSurface = NULL;
} }
Deck::~Deck() { Deck::~Deck() {
DeleteAll(); Quit();
if (faceSurface != NULL)
SDL_FreeSurface(faceSurface);
if (backSurface != NULL)
SDL_FreeSurface(backSurface);
} }
void Deck::Init(const char* faceName, const char* backName) { void Deck::Init(const char* faceName, const char* backName) {
//Create and setup the surfaces, with error checking face.LoadSurface(faceName);
faceSurface = SDL_LoadBMP(faceName); back.LoadSurface(backName);
if (faceSurface == NULL) { //exit if there are already cards in the game
cerr << "Error in Deck::Init(faceName,backName)" << endl; if (count != 0)
cerr << "SDL_LoadBMP() returned NULL" << endl;
cerr << "faceName: " << faceName << endl;
return; return;
}
backSurface = SDL_LoadBMP(backName);
if (backSurface == NULL) {
cerr << "Error in Deck::Init(faceName,backName)" << endl;
cerr << "SDL_LoadBMP() returned NULL" << endl;
cerr << "backName: " << backName << endl;
return;
}
SDL_SetColorKey(faceSurface,SDL_SRCCOLORKEY,SDL_MapRGB(faceSurface->format,255,0,255));
SDL_SetColorKey(backSurface,SDL_SRCCOLORKEY,SDL_MapRGB(backSurface->format,255,0,255));
//Create the cards //Create the cards
for (int s = 1; s <= 4; s++) for (int s = 1; s <= 4; s++) {
for (int r = 1; r <= 13; r++) for (int r = 1; r <= 13; r++) {
Receive(new Card(s,r,faceSurface,backSurface)); Receive(new Card(s,r,face.GetSurface(),back.GetSurface()));
count++;
}
}
} }
void Deck::DeleteAll() { void Deck::Quit() {
while(Head() != NULL) while(Head() != NULL) {
delete Pass(); delete Pass();
count--;
}
if (count != 0)
throw(std::runtime_error("Memory leak: Some cards are unnacounted for"));
} }

View File

@@ -1,7 +1,7 @@
/* File Name: deck.h /* File Name: deck.h
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 05/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,11 +23,15 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * Create and destroy the cards in the game, and report if any are missing.
*/ */
#ifndef KR_DECK_H_ #ifndef KR_DECK_H_
#define KR_DECK_H_ #define KR_DECK_H_
#include "SDL.h" #include "SDL.h"
#include "Codebase/image.h"
#include "card_list.h" #include "card_list.h"
class Deck : public CardList { class Deck : public CardList {
@@ -37,11 +41,13 @@ public:
~Deck(); ~Deck();
void Init(const char* faceName, const char* backName); void Init(const char* faceName, const char* backName);
void DeleteAll(); void Quit();
private: private:
/* Private access members */ /* Private access members */
SDL_Surface* faceSurface; Image face;
SDL_Surface* backSurface; Image back;
int count;
}; };
#endif #endif

View File

@@ -26,6 +26,7 @@
* Designed for Project Hearts, 4th try. * Designed for Project Hearts, 4th try.
*/ */
#include <iostream> #include <iostream>
#include <time.h>
#include "hearts_engine.h" #include "hearts_engine.h"
using namespace std; using namespace std;
@@ -36,7 +37,8 @@ using namespace std;
//------------------------- //-------------------------
HeartsEngine::HeartsEngine() { HeartsEngine::HeartsEngine() {
mImage.Add("heart","rsc\\heart.bmp",32,32,64,64); heartSprite.LoadSurface("rsc\\heart.bmp");
heartSprite.SetClipW(64);
mAudio.Init(0,MIX_DEFAULT_FREQUENCY,MIX_DEFAULT_FORMAT,1,1024); mAudio.Init(0,MIX_DEFAULT_FREQUENCY,MIX_DEFAULT_FORMAT,1,1024);
mAudio.Add("knock","rsc\\knock.wav"); mAudio.Add("knock","rsc\\knock.wav");
@@ -60,6 +62,10 @@ HeartsEngine::HeartsEngine() {
player[1]->SetPositions(0, ScreenHeight()/2 - 169, 0,20); player[1]->SetPositions(0, ScreenHeight()/2 - 169, 0,20);
player[2]->SetPositions(ScreenWidth()/2-156, 0, 20,0); player[2]->SetPositions(ScreenWidth()/2-156, 0, 20,0);
player[3]->SetPositions(ScreenWidth()-73, ScreenHeight()/2 - 169, 0,20); player[3]->SetPositions(ScreenWidth()-73, ScreenHeight()/2 - 169, 0,20);
//randomization
srand(time(NULL));
rand(); rand(); rand();
} }
HeartsEngine::~HeartsEngine() { HeartsEngine::~HeartsEngine() {
@@ -67,6 +73,8 @@ HeartsEngine::~HeartsEngine() {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
delete player[i]; delete player[i];
heartSprite.UnloadSurface();
} }
//------------------------- //-------------------------
@@ -97,7 +105,7 @@ void HeartsEngine::Process() {
void HeartsEngine::Draw() { void HeartsEngine::Draw() {
SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,128,0)); SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,0,128,0));
mImage.DrawAll(screen); heartSprite.DrawTo(screen, 32, 32);
switch(gamePhase) { switch(gamePhase) {
case SETUP: case SETUP:
@@ -140,7 +148,7 @@ void HeartsEngine::SetupPhase() {
firstPlayer = -1; firstPlayer = -1;
trickCount = 0; trickCount = 0;
heartsBroken = false; heartsBroken = false;
mImage["heart"]->SetClipX(0); heartSprite.SetClipX(0);
if (rotation == NONE) { if (rotation == NONE) {
CalcFirst(); CalcFirst();
@@ -271,7 +279,7 @@ void HeartsEngine::PlayBeforePhase() {
cerr << "Player index: " << i << endl; cerr << "Player index: " << i << endl;
} }
if (heartSound != heartsBroken) { if (heartSound != heartsBroken) {
mImage["heart"]->SetClipX(64); heartSprite.SetClipX(64);
mAudio.Play("glass"); mAudio.Play("glass");
} }
} }
@@ -288,7 +296,7 @@ void HeartsEngine::PlayPlayerPhase() {
playPhase = AFTER; playPhase = AFTER;
} }
if (heartSound != heartsBroken) { if (heartSound != heartsBroken) {
mImage["heart"]->SetClipX(64); heartSprite.SetClipX(64);
mAudio.Play("glass"); mAudio.Play("glass");
} }
} }
@@ -309,7 +317,7 @@ void HeartsEngine::PlayAfterPhase() {
cerr << "Player index: " << i << endl; cerr << "Player index: " << i << endl;
} }
if (heartSound != heartsBroken) { if (heartSound != heartsBroken) {
mImage["heart"]->SetClipX(64); heartSprite.SetClipX(64);
mAudio.Play("glass"); mAudio.Play("glass");
} }
} }
@@ -372,7 +380,7 @@ void HeartsEngine::CalcScores() {
if (card == NULL) if (card == NULL)
break; break;
if (card->Suit() == Card::HEARTS) if (card->GetSuit() == Card::HEARTS)
tally++; tally++;
if (ISCARD(card,QUEEN,SPADES)) if (ISCARD(card,QUEEN,SPADES))

View File

@@ -28,7 +28,7 @@
#ifndef KR_HEARTSENGINE_H_ #ifndef KR_HEARTSENGINE_H_
#define KR_HEARTSENGINE_H_ #define KR_HEARTSENGINE_H_
#include "base_engine.h" #include "base_engine.h"
#include "image_manager.h" #include "Codebase/image.h"
#include "audio_manager.h" #include "audio_manager.h"
#include "deck.h" #include "deck.h"
#include "player_ai.h" #include "player_ai.h"
@@ -47,7 +47,7 @@ private:
void Draw (); void Draw ();
/* KAGE Managers */ /* KAGE Managers */
KAGE::ImageManager mImage; Image heartSprite;
KAGE::AudioManager mAudio; KAGE::AudioManager mAudio;
/* Game phase members */ //TODO: "phases" /* Game phase members */ //TODO: "phases"

View File

@@ -1,174 +0,0 @@
/* File Name: image.cpp
* Author: Kayne Ruse
* Date (dd/mm/yyyy): 20/06/2011
* Copyright: (c) Kayne Ruse 2011, 2012
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Description:
* The Image class, a wrapper for SDL_Surface and other drawing functionality.
* Part of the KAGE Game Engine.
*/
#include <iostream>
#include "image.h"
using namespace std;
using namespace KAGE;
//-------------------------
//Public access members
//-------------------------
Image::Image(const char* fileName, int x, int y, int w, int h):
localSurface(true)
{
//Create a local surface from a file
surface = SDL_LoadBMP(fileName);
if (surface == NULL) {
cout << "Error in Image::Image()" << endl;
cout << "SDL_LoadBMP() returned NULL" << endl;
cout << "fileName: " << fileName << endl;
return;
}
SetColorKey(255,0,255);
Init(x,y,0,0,w,h);
}
Image::Image(SDL_Surface* surf, int x, int y, int w, int h):
localSurface(false)
{
//Use a surface passed by the calling function
surface = surf;
Init(x,y,0,0,w,h);
}
void Image::Init(int x, int y, int sx, int sy, int sw, int sh) {
//Set up the variables
dclip.x = x;
dclip.y = y;
sclip.x = sx;
sclip.y = sy;
sclip.w = (sw == 0) ? surface->w : sw;
sclip.h = (sh == 0) ? surface->h : sh;
}
Image::~Image() {
if (localSurface)
SDL_FreeSurface(surface);
}
//-------------------------
//Graphical members
//-------------------------
void Image::Draw(SDL_Surface* dest, int camX, int camY) {
SDL_Rect tmp = dclip;
tmp.x += camX;
tmp.y += camY;
SDL_BlitSurface(surface,&sclip,dest,&tmp);
}
int Image::SetColorKey(int red, int green, int blue) {
if (localSurface)
return SDL_SetColorKey(surface,SDL_SRCCOLORKEY,SDL_MapRGB(surface->format,red,green,blue));
else
return -2;
}
int Image::ClearColorKey() {
if (localSurface)
return SDL_SetColorKey(surface,0,0);
else
return -2;
}
//-------------------------
//Accessors and mutators
//-------------------------
void Image::SetPos(int x, int y) {
dclip.x = x;
dclip.y = y;
}
int Image::SetX(int x) {
return dclip.x = x;
}
int Image::SetY(int y) {
return dclip.y = y;
}
int Image::SetClipX(int x) {
return sclip.x = x;
}
int Image::SetClipY(int y) {
return sclip.y = y;
}
int Image::SetWidth(int w) {
return sclip.w = w;
}
int Image::SetHeight(int h) {
return sclip.h = h;
}
int Image::GetX() {
return dclip.x;
}
int Image::GetY() {
return dclip.y;
}
int Image::GetClipX() {
return sclip.x;
}
int Image::GetClipY() {
return sclip.y;
}
int Image::GetWidth() {
return sclip.w;
}
int Image::GetHeight() {
return sclip.h;
}
//-------------------------
//Protected access members
//-------------------------
SDL_Surface* Image::SetSurface(SDL_Surface* surf) {
return surface = surf;
}
SDL_Surface* Image::GetSurface() {
return surface;
}
bool Image::LocalSurface() {
return localSurface;
}

View File

@@ -1,79 +0,0 @@
/* File Name: image.h
* Author: Kayne Ruse
* Date (dd/mm/yyyy): 20/06/2011
* Copyright: (c) Kayne Ruse 2011, 2012
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Description:
* The Image class, a wrapper for SDL_Surface and other drawing functionality.
* Part of the KAGE Game Engine.
*/
#ifndef KR_KAGE_IMAGE_H_
#define KR_KAGE_IMAGE_H_
#include "SDL.h"
namespace KAGE {
class Image {
public:
/* Public access members */
Image(const char* fileName, int x = 0, int y = 0, int w = 0, int h = 0);
Image(SDL_Surface* surface, int x = 0, int y = 0, int w = 0, int h = 0);
~Image();
/* Graphical members */
virtual void Draw(SDL_Surface* dest, int camX = 0, int camY = 0);
int SetColorKey(int red, int green, int blue);
int ClearColorKey();
/* Accessors and mutators */
virtual void SetPos(int x, int y);
virtual int SetX(int);
virtual int SetY(int);
virtual int SetClipX(int);
virtual int SetClipY(int);
virtual int SetWidth(int);
virtual int SetHeight(int);
virtual int GetX();
virtual int GetY();
virtual int GetClipX();
virtual int GetClipY();
virtual int GetWidth();
virtual int GetHeight();
protected:
/* Protected access members */
void Init(int x, int y, int sx, int sy, int sw, int sh);
SDL_Surface* SetSurface (SDL_Surface* surf);
SDL_Surface* GetSurface ();
bool LocalSurface ();
private:
/* Private access members */
SDL_Surface* surface;
SDL_Rect sclip;
SDL_Rect dclip;
const bool localSurface;
};
}
#endif

View File

@@ -1,74 +0,0 @@
/* File Name: image_manager.cpp
* Author: Kayne Ruse
* Date (dd/mm/yyyy): 20/06/2011
* Copyright: (c) Kayne Ruse 2011, 2012
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Description:
* The Image Manager creates, organises and cleans up the Images in the game.
* Part of the KAGE Game Engine.
*/
#include <iostream>
#include "image_manager.h"
using namespace std;
using namespace KAGE;
//-------------------------
//Public access members
//-------------------------
Image* ImageManager::Add(const char* name,const char* fName, int x, int y, int w, int h) {
if (Exists(name)) {
cout << "Error in ImageManager::Add(name,fName)" << endl;
cout << "An Image of that name already exists" << endl;
cout << "name: " << name << endl;
return NULL;
}
return NamedManager::Add(name,new Image(fName,x,y,w,h));
}
Image* ImageManager::Add(const char* name,SDL_Surface* surface, int x, int y, int w, int h) {
if (Exists(name)) {
cout << "Error in ImageManager::Add(name,surface)" << endl;
cout << "An Image of that name already exists" << endl;
cout << "name: " << name << endl;
return NULL;
}
return NamedManager::Add(name,new Image(surface,x,y,w,h));
}
Image* ImageManager::Add(const char *name,Image* image) {
if (Exists(name)) {
cout << "Error in ImageManager::Add(name,image)" << endl;
cout << "An Image of that name already exists" << endl;
cout << "name: " << name << endl;
return NULL;
}
return NamedManager::Add(name,image);
}
void ImageManager::DrawAll(SDL_Surface* dest, int camX, int camY) {
for (MapType::iterator it = mapList.begin(); it != mapList.end(); it++)
it->second->Draw(dest,camX,camY);
}

View File

@@ -1,47 +0,0 @@
/* File Name: image_manager.h
* Author: Kayne Ruse
* Date (dd/mm/yyyy): 20/06/2011
* Copyright: (c) Kayne Ruse 2011, 2012
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Description:
* The Image Manager creates, organises and cleans up the Images in the game.
* Part of the KAGE Game Engine.
*/
#ifndef KR_KAGE_IMAGEMANAGER_H_
#define KR_KAGE_IMAGEMANAGER_H_
#include "named_manager.h"
#include "image.h"
namespace KAGE {
class ImageManager : public NamedManager<Image> {
public:
/* Public access members */
Image* Add(const char* name, const char* fileName, int x = 0, int y = 0, int w = 0, int h = 0);
Image* Add(const char* name, SDL_Surface* surface, int x = 0, int y = 0, int w = 0, int h = 0);
Image* Add(const char* name, Image* image);
void DrawAll(SDL_Surface* dest, int camX = 0, int camY = 0);
};
}
#endif

View File

@@ -104,7 +104,7 @@ void Player::ShiftCard(int index, int dirX, int dirY) {
void Player::SetFaces(int face) { void Player::SetFaces(int face) {
for (CardList::iterator it = hand.Head(); it != NULL; it = it->GetNext()) for (CardList::iterator it = hand.Head(); it != NULL; it = it->GetNext())
it->SetFace(face); it->SetFaceState(face);
} }
void Player::SetPositions(int _posX, int _posY, int _dirX, int _dirY) { void Player::SetPositions(int _posX, int _posY, int _dirX, int _dirY) {
@@ -131,7 +131,7 @@ void Player::SetTrickPositions() {
tricks.Sort(); tricks.Sort();
for (int i = 0; i < tricks.Size(); i++) { for (int i = 0; i < tricks.Size(); i++) {
if (tricks.Read(i)->Suit() != Card::HEARTS && !ISCARD(tricks.Read(i),QUEEN,SPADES)) if (tricks.Read(i)->GetSuit() != Card::HEARTS && !ISCARD(tricks.Read(i),QUEEN,SPADES))
continue; continue;
tricks.Read(i)->SetPos(x,y); tricks.Read(i)->SetPos(x,y);
@@ -141,7 +141,7 @@ void Player::SetTrickPositions() {
} }
void Player::DrawHand(SDL_Surface* dest) { void Player::DrawHand(SDL_Surface* dest) {
Hand()->DrawAll(dest); Hand()->DrawTo(dest);
} }
void Player::DrawTricks(SDL_Surface* dest) { void Player::DrawTricks(SDL_Surface* dest) {
@@ -149,9 +149,9 @@ void Player::DrawTricks(SDL_Surface* dest) {
tricks.Sort(); tricks.Sort();
for (int i = 0; i < tricks.Size(); i++) { for (int i = 0; i < tricks.Size(); i++) {
if (tricks.Read(i)->Suit() != Card::HEARTS && !ISCARD(tricks.Read(i),QUEEN,SPADES)) if (tricks.Read(i)->GetSuit() != Card::HEARTS && !ISCARD(tricks.Read(i),QUEEN,SPADES))
continue; continue;
tricks.Read(i)->Draw(dest); tricks.Read(i)->DrawTo(dest);
} }
} }

View File

@@ -38,7 +38,7 @@ void PlayerAI::SelectSwapCards(int dirX, int dirY) {
int card = -1; int card = -1;
for (int i = Hand()->Size() - 1; i >= 0; i--) { for (int i = Hand()->Size() - 1; i >= 0; i--) {
if (Hand()->Read(i)->Rank() > Hand()->Read(card)->Rank() && !CheckSwapCards(i) ) { if (Hand()->Read(i)->GetRank() > Hand()->Read(card)->GetRank() && !CheckSwapCards(i) ) {
card = i; card = i;
} }
} }
@@ -75,7 +75,7 @@ Card* PlayerAI::PassPlayFirstTrick(int leadingSuit) {
//follow suit //follow suit
for(int i = 0; i < Hand()->Size()-1; i++) for(int i = 0; i < Hand()->Size()-1; i++)
if (Hand()->Read(i)->Suit() == leadingSuit) if (Hand()->Read(i)->GetSuit() == leadingSuit)
return Hand()->Pass(i); return Hand()->Pass(i);
/* bug: it's possible that if every penalty card is initially dealt the the AI, it'll break /* bug: it's possible that if every penalty card is initially dealt the the AI, it'll break
@@ -88,7 +88,7 @@ Card* PlayerAI::PassPlayFirstTrick(int leadingSuit) {
for (int i = Hand()->Size() -1; i >= 0; i--) {//backwards, to choose the highest rank for (int i = Hand()->Size() -1; i >= 0; i--) {//backwards, to choose the highest rank
c = Hand()->Read(i); c = Hand()->Read(i);
if (c->Suit() != Card::HEARTS && !ISCARD(c,QUEEN,SPADES) ) { if (c->GetSuit() != Card::HEARTS && !ISCARD(c,QUEEN,SPADES) ) {
c = Hand()->Pass(i); c = Hand()->Pass(i);
break; break;
} }
@@ -109,7 +109,7 @@ Card* PlayerAI::PassPlayFollowSuit(int leadingSuit, bool heartsBroken) {
} }
else { else {
for (int i = 0; i < Hand()->Size() -1; i++) { for (int i = 0; i < Hand()->Size() -1; i++) {
if (Hand()->Read(i)->Suit() != Card::HEARTS) { if (Hand()->Read(i)->GetSuit() != Card::HEARTS) {
c = Hand()->Pass(i); c = Hand()->Pass(i);
break; break;
} }
@@ -122,7 +122,7 @@ Card* PlayerAI::PassPlayFollowSuit(int leadingSuit, bool heartsBroken) {
//play the lowest card of the suit //play the lowest card of the suit
for (int i = 0; i < Hand()->Size()-1; i++) for (int i = 0; i < Hand()->Size()-1; i++)
if (Hand()->Read(i)->Suit() == leadingSuit) if (Hand()->Read(i)->GetSuit() == leadingSuit)
return Hand()->Pass(i); return Hand()->Pass(i);
return NULL; return NULL;
@@ -135,7 +135,7 @@ Card* PlayerAI::PassPlayBreakSuit(bool& heartsBroken) {
return Hand()->Pass(i); return Hand()->Pass(i);
//if I have a heart //if I have a heart
if (Hand()->Read( Hand()->Size()-1 )->Suit() == Card::HEARTS) { if (Hand()->Read( Hand()->Size()-1 )->GetSuit() == Card::HEARTS) {
heartsBroken = true; heartsBroken = true;
return Hand()->Pass( Hand()->Size()-1 ); return Hand()->Pass( Hand()->Size()-1 );
} }

View File

@@ -99,16 +99,16 @@ Card* PlayerUser::PassPlayFirstTrick(int card, int leadingSuit) {
} }
//follow suit //follow suit
if (Hand()->Read(card)->Suit() == leadingSuit) //if I've selected the correct suit if (Hand()->Read(card)->GetSuit() == leadingSuit) //if I've selected the correct suit
return Hand()->Pass(card); return Hand()->Pass(card);
//if I haven't selected the correct suit //if I haven't selected the correct suit
for (int i = 0; i < Hand()->Size() -1; i++) for (int i = 0; i < Hand()->Size() -1; i++)
if (Hand()->Read(i)->Suit() == leadingSuit) //The correct suit is in my hand if (Hand()->Read(i)->GetSuit() == leadingSuit) //The correct suit is in my hand
return NULL; return NULL;
//can't follow suit, no penalty cards //can't follow suit, no penalty cards
if (Hand()->Read(card)->Suit() != Card::HEARTS && !ISCARD(Hand()->Read(card),QUEEN,SPADES)) if (Hand()->Read(card)->GetSuit() != Card::HEARTS && !ISCARD(Hand()->Read(card),QUEEN,SPADES))
return Hand()->Pass(card); return Hand()->Pass(card);
return NULL; return NULL;
@@ -121,7 +121,7 @@ Card* PlayerUser::PassPlayFollowSuit(int card, int leadingSuit, bool heartsBroke
if (heartsBroken) if (heartsBroken)
return Hand()->Pass(card); return Hand()->Pass(card);
else { else {
if (Hand()->Read(card)->Suit() != Card::HEARTS) if (Hand()->Read(card)->GetSuit() != Card::HEARTS)
return Hand()->Pass(card); return Hand()->Pass(card);
else else
return NULL; return NULL;
@@ -129,7 +129,7 @@ Card* PlayerUser::PassPlayFollowSuit(int card, int leadingSuit, bool heartsBroke
} }
//if the player is following suit //if the player is following suit
if (Hand()->Read(card)->Suit() == leadingSuit) if (Hand()->Read(card)->GetSuit() == leadingSuit)
return Hand()->Pass(card); return Hand()->Pass(card);
//when the card does not follow suit //when the card does not follow suit
@@ -139,10 +139,10 @@ Card* PlayerUser::PassPlayFollowSuit(int card, int leadingSuit, bool heartsBroke
Card* PlayerUser::PassPlayBreakSuit(int card, int leadingSuit, bool& heartsBroken) { Card* PlayerUser::PassPlayBreakSuit(int card, int leadingSuit, bool& heartsBroken) {
//if the player CAN still follow suit //if the player CAN still follow suit
for (int i = 0; i < Hand()->Size() -1; i++) for (int i = 0; i < Hand()->Size() -1; i++)
if (Hand()->Read(i)->Suit() == leadingSuit) if (Hand()->Read(i)->GetSuit() == leadingSuit)
return NULL; return NULL;
if (Hand()->Read(card)->Suit() == Card::HEARTS) if (Hand()->Read(card)->GetSuit() == Card::HEARTS)
heartsBroken = true; heartsBroken = true;
return Hand()->Pass(card); return Hand()->Pass(card);
} }

View File

@@ -1,7 +1,7 @@
/* File Name: table.cpp /* File Name: table.cpp
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 09/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,10 +23,12 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * Hold the cards in play, and determine the winner of a trick.
*/ */
#include "table.h" #include "table.h"
#include <stdexcept>
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
@@ -47,32 +49,31 @@ Card* Table::Pass() {
return cList.PassSlab(0,4); return cList.PassSlab(0,4);
} }
void Table::Receive(Card* card,int position) { void Table::Receive(Card* card, int position) {
//position is the player's pos //position is the player's pos
if (position < 0 || position > 4) if (position < 0 || position > 3)
return; throw(std::invalid_argument("Unknown player index"));
cards[position] = card; cards[position] = card;
cards[position]->SetPos( cards[position]->SetPos(
cardPositions[position].x, cardPositions[position].x,
cardPositions[position].y cardPositions[position].y
); );
cards[position]->SetFace(Card::UP); cards[position]->SetFaceState(Card::UP);
} }
int Table::CalcWinner(int first) { int Table::CalcWinner(int first) {
if (first < 0 || first > 3) if (first < 0 || first > 3)
return -1; throw(std::invalid_argument("Unknown player index"));
int suit = cards[first]->Suit(); int suit = cards[first]->GetSuit();
int winner = -1; int winner = -1;
int highest = -1; int highest = -1;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if (cards[i]->Suit() == suit && if (cards[i]->GetSuit() == suit && cards[i]->GetRank() > highest)
cards[i]->Rank() > highest)
{ {
highest = cards[i]->Rank(); highest = cards[i]->GetRank();
winner = i; winner = i;
} }
} }
@@ -82,8 +83,8 @@ int Table::CalcWinner(int first) {
int Table::GetLeadingSuit(int first) { int Table::GetLeadingSuit(int first) {
if (cards[first] == NULL) if (cards[first] == NULL)
return -1; return -1; //this means "No cards yet..." -?
return cards[first]->Suit(); return cards[first]->GetSuit();
} }
//------------------------- //-------------------------
@@ -107,5 +108,5 @@ void Table::Draw(SDL_Surface* dest, int first) {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (cards[(i + first) % 4] != NULL) if (cards[(i + first) % 4] != NULL)
cards[(i + first) % 4]->Draw(dest); cards[(i + first) % 4]->DrawTo(dest);
} }

View File

@@ -1,7 +1,7 @@
/* File Name: table.h /* File Name: table.h
* Author: Kayne Ruse * Author: Kayne Ruse
* Date (dd/mm/yyyy): 09/06/2011 * Date (dd/mm/yyyy): 21/01/2013
* Copyright: (c) Kayne Ruse 2011, 2012 * Copyright: (c) Kayne Ruse 2011, 2012, 2013
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@@ -23,7 +23,7 @@
* distribution. * distribution.
* *
* Description: * Description:
* Designed for Project Hearts, 4th try. * Hold the cards in play, and determine the winner of a trick.
*/ */
#ifndef KR_TABLE_H_ #ifndef KR_TABLE_H_
#define KR_TABLE_H_ #define KR_TABLE_H_

View File

@@ -1,15 +1,16 @@
* Try to keep the project as stable as possible. * Try to keep the project as stable as possible.
* Use a separate development branch where necessary * Use a separate development branch where necessary
* Don't forget to search for "TODO" tags in the code
* Remove NamedManager as soon as possible * Remove NamedManager as soon as possible
* Remove unnecessary KAGE modules * Remove unnecessary KAGE modules
* Rearrange the project hierarchy > Rearrange the project hierarchy
* Breakdown and analyse the structure * Breakdown and analyse the structure
* Upgrade to the current Codebase where possible * Upgrade to the current Codebase where possible
* Remedy Card's graphical system > Remedy Card's graphical system
* Use the current Image class in Card & Deck > Use the current Image class in Card & Deck
* Add in graphical buttons and onscreen text for user friendlyness * Add in graphical buttons and onscreen text for user friendlyness
* Research SDL_mixer, to fully understand the audio system * Research SDL_mixer, to fully understand the audio system
@@ -20,3 +21,5 @@
This system seems to be split between the three player classes This system seems to be split between the three player classes
I could use a unified highlighting system for both swapping and playing a card I could use a unified highlighting system for both swapping and playing a card
~~~~~

BIN
rsc/newdev/heart128x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
rsc/newdev/heart32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
rsc/newdev/heart64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
rsc/newdev/heart_b64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB