Commit 8a5ca866 authored by twanvl's avatar twanvl

working on an improved random pack system, #ifdefed out for now

parent 911fcd2a
This diff is collapsed.
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
#include <script/scriptable.hpp> #include <script/scriptable.hpp>
#include <boost/random/mersenne_twister.hpp> #include <boost/random/mersenne_twister.hpp>
#define USE_NEW_PACK_SYSTEM 0
#if !USE_NEW_PACK_SYSTEM
// =================================================================================================== OLD
DECLARE_POINTER_TYPE(PackItemRef); DECLARE_POINTER_TYPE(PackItemRef);
DECLARE_POINTER_TYPE(Card); DECLARE_POINTER_TYPE(Card);
class Set; class Set;
...@@ -97,5 +102,152 @@ class PackItemCache { ...@@ -97,5 +102,152 @@ class PackItemCache {
map<String,Cards> item_cards; map<String,Cards> item_cards;
}; };
#else
// =================================================================================================== NEW
DECLARE_POINTER_TYPE(PackItem);
DECLARE_POINTER_TYPE(Card);
class Set;
// ----------------------------------------------------------------------------- : PackType
enum OneMany
{ SELECT_ONE_OR_EMPTY
, SELECT_ONE
, SELECT_FIRST
, SELECT_ALL
};
/// A card pack description for playtesting
class PackType : public IntrusivePtrBase<PackType> {
public:
PackType();
String name; ///< Name of this pack
Scriptable<bool> enabled; ///< Is this pack enabled?
bool selectable; ///< Is this pack listed in the UI?
bool summary; ///< Should the total be listed for this type?
OneMany select; ///< Select one or many?
OptionalScript cards; ///< Script to select this type of cards (there are no items)
OptionalScript filter; ///< Filter to select this type of cards
vector<PackItemP> items; ///< Subpacks in this pack
/// Update scripts, returns true if there is a change
bool update(Context& ctx);
private:
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : PackItem
enum PackSelectType
{ PACK_REF_INHERIT
, PACK_REF_REPLACE
, PACK_REF_NO_REPLACE
, PACK_REF_CYCLIC
};
/// An item in a PackType
class PackItem : public IntrusivePtrBase<PackItem> {
public:
PackItem();
String pack; ///< Name of the pack to select cards from
Scriptable<int> amount; ///< Number of cards of this type
Scriptable<double> weight; ///< Relative probability of picking this item
PackSelectType type;
/// Update scripts, returns true if there is a change
bool update(Context& ctx);
private:
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : Generating / counting
// --------------------------------------------------- : PackItemCache
class PackItemCache {
public:
PackItemCache(Set& set) : set(set) {}
/// Look up a pack type by name
const PackType& pack(const String& name);
protected:
Set& set;
/// The cards for a given PackItem
ScriptValueP cardsFor(const ScriptValueP& cards_script);
private:
/// Lookup PackTypes by name
//%%
/// Cards for each PackType
map<ScriptValueP,ScriptValueP> item_cards;
};
// --------------------------------------------------- : Counting expected cards
/// Class for determining the *expected* number of cards from each type
class PackItemCounter : PackItemCache {
public:
PackItemCounter(Set& set, map<const PackType*,double>& counts)
: PackItemCache(set), counts(counts)
{}
/// Add a number of copies of the PackType to the counts, recurse into child items
void addCountRecursive(const PackType& pack, double copies);
void addCountRecursive(const PackItem& item, double copies);
/// The probability that the given pack is non-empty
double probabilityNonEmpty(const PackType& pack);
double probabilityNonEmpty(const PackItem& item);
/// The counts will be stored here
map<const PackType*,double>& counts;
private:
/// The probability that a pack type is empty (cache)
//%map<const PackItem*,double> probability_empty;
};
// --------------------------------------------------- : PackItemCounter
/// Class for generating card packs
class PackItemGenerator : PackItemCache {
public:
PackItemGenerator(Set& set, vector<CardP>& cards, boost::mt19937& gen)
: PackItemCache(set), out(cards), gen(gen)
{}
/// Generate a pack, adding it to cards
void generate(const PackType& pack);
/// Number of cards of a type
typedef map<pair<ScriptValueP,PackSelectType>,int> OfTypeCount;
/// Determine what *types* of cards to pick (store in out)
/** Does NOT add cards yet.
* Returns true if non-empty.
*/
bool generateCount(const PackType& pack, int copies, PackSelectType type, OfTypeCount& out);
bool generateCount(const PackItem& item, int copies, PackSelectType type, OfTypeCount& out);
bool generateSingleCount(const PackType& pack, PackSelectType type, OfTypeCount& out);
/// Pick cards from a list
void pickCards(const ScriptValueP& cards, PackSelectType type, int amount);
/// The cards will be stored here
vector<CardP>& out;
/// Random generator
boost::mt19937& gen;
};
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
#endif
...@@ -21,7 +21,9 @@ ...@@ -21,7 +21,9 @@
DECLARE_TYPEOF_COLLECTION(PackTypeP); DECLARE_TYPEOF_COLLECTION(PackTypeP);
DECLARE_TYPEOF_COLLECTION(PackItemP); DECLARE_TYPEOF_COLLECTION(PackItemP);
DECLARE_TYPEOF_COLLECTION(PackItemRefP); #if !USE_NEW_PACK_SYSTEM
DECLARE_TYPEOF_COLLECTION(PackItemRefP);
#endif
DECLARE_TYPEOF_COLLECTION(CardP); DECLARE_TYPEOF_COLLECTION(CardP);
DECLARE_TYPEOF_COLLECTION(RandomPackPanel::PackItem_for_typeof); DECLARE_TYPEOF_COLLECTION(RandomPackPanel::PackItem_for_typeof);
...@@ -34,8 +36,10 @@ class RandomCardList : public CardListBase { ...@@ -34,8 +36,10 @@ class RandomCardList : public CardListBase {
/// Reset the list /// Reset the list
void reset(); void reset();
#if !USE_NEW_PACK_SYSTEM
/// Add a pack of cards /// Add a pack of cards
void add(PackItemCache& packs, boost::mt19937& gen, const PackType& pack); void add(PackItemCache& packs, boost::mt19937& gen, const PackType& pack);
#endif
using CardListBase::rebuild; using CardListBase::rebuild;
...@@ -45,7 +49,11 @@ class RandomCardList : public CardListBase { ...@@ -45,7 +49,11 @@ class RandomCardList : public CardListBase {
virtual void getItems(vector<VoidP>& out) const; virtual void getItems(vector<VoidP>& out) const;
virtual void onChangeSet(); virtual void onChangeSet();
private: #if USE_NEW_PACK_SYSTEM
public:
#else
private:
#endif
vector<CardP> cards; vector<CardP> cards;
}; };
...@@ -56,9 +64,12 @@ RandomCardList::RandomCardList(Window* parent, int id, long style) ...@@ -56,9 +64,12 @@ RandomCardList::RandomCardList(Window* parent, int id, long style)
void RandomCardList::reset() { void RandomCardList::reset() {
cards.clear(); cards.clear();
} }
void RandomCardList::add(PackItemCache& packs, boost::mt19937& gen, const PackType& pack) {
pack.generate(packs,gen,cards); #if !USE_NEW_PACK_SYSTEM
} void RandomCardList::add(PackItemCache& packs, boost::mt19937& gen, const PackType& pack) {
pack.generate(packs,gen,cards);
}
#endif
void RandomCardList::onChangeSet() { void RandomCardList::onChangeSet() {
reset(); reset();
...@@ -80,15 +91,22 @@ class PackTotalsPanel : public wxPanel { ...@@ -80,15 +91,22 @@ class PackTotalsPanel : public wxPanel {
PackTotalsPanel(Window* parent, int id) : wxPanel(parent,id) {} PackTotalsPanel(Window* parent, int id) : wxPanel(parent,id) {}
void setGame(const GameP& game); void setGame(const GameP& game);
void clear(); void clear();
#if !USE_NEW_PACK_SYSTEM
void addPack(PackType& pack, int copies); void addPack(PackType& pack, int copies);
void addItemRef(PackItemRef& item, int copies); void addItemRef(PackItemRef& item, int copies);
#endif
private: private:
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
GameP game; GameP game;
void onPaint(wxPaintEvent&); void onPaint(wxPaintEvent&);
void draw(DC& dc); void draw(DC& dc);
void drawItem(DC& dc, int& y, const String& name, int value); void drawItem(DC& dc, int& y, const String& name, double value);
#if USE_NEW_PACK_SYSTEM
public:
map<const PackType*,double> amounts;
#else
map<String,int> amounts; map<String,int> amounts;
#endif
}; };
void PackTotalsPanel::onPaint(wxPaintEvent&) { void PackTotalsPanel::onPaint(wxPaintEvent&) {
...@@ -106,11 +124,21 @@ void PackTotalsPanel::draw(DC& dc) { ...@@ -106,11 +124,21 @@ void PackTotalsPanel::draw(DC& dc) {
dc.SetFont(*wxNORMAL_FONT); dc.SetFont(*wxNORMAL_FONT);
int y = 0; int y = 0;
int total = 0; int total = 0;
#if USE_NEW_PACK_SYSTEM
FOR_EACH(pack, game->pack_types) {
if (pack->summary) {
int value = amounts[pack.get()];
drawItem(dc, y, tr(*game, pack->name, capitalize), value);
total += value;
}
}
#else
FOR_EACH(item, game->pack_items) { FOR_EACH(item, game->pack_items) {
int value = amounts[item->name]; int value = amounts[item->name];
drawItem(dc, y, tr(*game, item->name, capitalize), value); drawItem(dc, y, tr(*game, item->name, capitalize), value);
total += value; total += value;
} }
#endif
// draw total // draw total
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW));
dc.DrawLine(0, y-3, size.x, y-3); dc.DrawLine(0, y-3, size.x, y-3);
...@@ -120,10 +148,10 @@ void PackTotalsPanel::draw(DC& dc) { ...@@ -120,10 +148,10 @@ void PackTotalsPanel::draw(DC& dc) {
drawItem(dc, y, _LABEL_("total cards"), total); drawItem(dc, y, _LABEL_("total cards"), total);
} }
void PackTotalsPanel::drawItem(DC& dc, int& y, const String& name, int value) { void PackTotalsPanel::drawItem(DC& dc, int& y, const String& name, double value) {
wxSize size = dc.GetSize(); wxSize size = dc.GetSize();
int w,h; int w,h;
String amount; amount << value; String amount = String::Format(_("%.f"),value);
dc.GetTextExtent(amount,&w,&h); dc.GetTextExtent(amount,&w,&h);
dc.DrawText(name, 0, y); dc.DrawText(name, 0, y);
dc.DrawText(amount, size.x-w, y);//align right dc.DrawText(amount, size.x-w, y);//align right
...@@ -137,14 +165,16 @@ void PackTotalsPanel::setGame(const GameP& game) { ...@@ -137,14 +165,16 @@ void PackTotalsPanel::setGame(const GameP& game) {
void PackTotalsPanel::clear() { void PackTotalsPanel::clear() {
amounts.clear(); amounts.clear();
} }
void PackTotalsPanel::addPack(PackType& pack, int copies) { #if !USE_NEW_PACK_SYSTEM
FOR_EACH(item,pack.items) { void PackTotalsPanel::addPack(PackType& pack, int copies) {
addItemRef(*item, copies * item->amount); FOR_EACH(item,pack.items) {
addItemRef(*item, copies * item->amount);
}
} }
} void PackTotalsPanel::addItemRef(PackItemRef& item, int copies) {
void PackTotalsPanel::addItemRef(PackItemRef& item, int copies) { amounts[item.name] += copies;
amounts[item.name] += copies; }
} #endif
BEGIN_EVENT_TABLE(PackTotalsPanel, wxPanel) BEGIN_EVENT_TABLE(PackTotalsPanel, wxPanel)
EVT_PAINT(PackTotalsPanel::onPaint) EVT_PAINT(PackTotalsPanel::onPaint)
...@@ -298,12 +328,19 @@ void RandomPackPanel::onCommand(int id) { ...@@ -298,12 +328,19 @@ void RandomPackPanel::onCommand(int id) {
// ----------------------------------------------------------------------------- : Generating // ----------------------------------------------------------------------------- : Generating
void RandomPackPanel::updateTotals() { void RandomPackPanel::updateTotals() {
#if USE_NEW_PACK_SYSTEM
PackItemCounter counter(*set, totals->amounts);
#endif
totals->clear(); totals->clear();
total_packs = 0; total_packs = 0;
FOR_EACH(i,packs) { FOR_EACH(i,packs) {
int copies = i.value->GetValue(); int copies = i.value->GetValue();
total_packs += copies; total_packs += copies;
#if USE_NEW_PACK_SYSTEM
counter.addCountRecursive(*i.pack, copies);
#else
totals->addPack(*i.pack, copies); totals->addPack(*i.pack, copies);
#endif
} }
// update UI // update UI
totals->Refresh(false); totals->Refresh(false);
...@@ -337,13 +374,21 @@ void RandomPackPanel::setSeed(int seed) { ...@@ -337,13 +374,21 @@ void RandomPackPanel::setSeed(int seed) {
void RandomPackPanel::generate() { void RandomPackPanel::generate() {
boost::mt19937 gen((unsigned)getSeed()); boost::mt19937 gen((unsigned)getSeed());
#if USE_NEW_PACK_SYSTEM
PackItemGenerator generator(*set, card_list->cards, gen);
#else
PackItemCache pack_cache(*set); PackItemCache pack_cache(*set);
#endif
// add packs to card list // add packs to card list
card_list->reset(); card_list->reset();
FOR_EACH(item,packs) { FOR_EACH(item,packs) {
int copies = item.value->GetValue(); int copies = item.value->GetValue();
for (int i = 0 ; i < copies ; ++i) { for (int i = 0 ; i < copies ; ++i) {
#if USE_NEW_PACK_SYSTEM
generator.generate(*item.pack);
#else
card_list->add(pack_cache, gen, *item.pack); card_list->add(pack_cache, gen, *item.pack);
#endif
} }
} }
card_list->rebuild(); card_list->rebuild();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment