mRandomDeck.h

Engine/source/math/mRandomDeck.h

More...

Classes:

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _MRANDOMDECK_H_
 25#define _MRANDOMDECK_H_
 26
 27#ifndef _MRANDOM_H_
 28#include "math/mRandom.h"
 29#endif
 30
 31template <class T>
 32class MRandomDeck
 33{
 34protected:
 35
 36   MRandomLCG *mRandGen;
 37
 38   Vector<T> mDeck;
 39
 40   Vector<T> mPile;
 41
 42public:
 43
 44   MRandomDeck( MRandomLCG *randGen = &gRandGen );
 45
 46   void addToPile( const T &item );
 47
 48   void addToPile( const Vector<T> &items );
 49
 50   void shuffle();
 51
 52   S32 draw( T *item, bool reshuffle = true );
 53
 54   void removeAll( Vector<T> *outItems );
 55
 56};
 57
 58template<class T>
 59inline MRandomDeck<T>::MRandomDeck( MRandomLCG *randGen )
 60   : mRandGen( randGen )
 61{
 62}
 63
 64template<class T> 
 65inline void MRandomDeck<T>::shuffle()
 66{
 67   // Move everything to the pile.
 68   mPile.merge( mDeck );
 69
 70   if ( mPile.empty() )
 71      return;
 72   T& last = mPile.last();
 73   mDeck.clear();
 74
 75   // Randomly draw from the pile
 76   // and place them in the deck.
 77   while ( !mPile.empty() )
 78   {
 79      U32 i = mRandGen->randI( 0, mPile.size() - 1 );
 80      mDeck.push_back( mPile[i] );
 81      mPile.erase_fast( i );
 82   }
 83
 84   // Make sure that the first drawn item
 85   // is not the same as the last drawn item.
 86   if ( mDeck.last() == last )
 87   {
 88      mDeck.pop_back();
 89      mDeck.push_front( last );
 90   }
 91}
 92
 93template<class T> 
 94inline S32 MRandomDeck<T>::draw( T *item, bool reshuffle )
 95{ 
 96   if ( mDeck.size() == 0 )
 97   {
 98      if ( mPile.size() == 0 )
 99         return -1;
100      
101      if ( reshuffle )
102         shuffle();
103      else
104         return -1;
105   }
106
107   *item = mDeck.last();
108   mPile.push_back( *item );
109   mDeck.pop_back();   
110
111   return mDeck.size();
112}
113
114template<class T>
115inline void MRandomDeck<T>::addToPile( const T &item )
116{
117   mPile.push_back( item );
118}
119
120template<class T>
121inline void MRandomDeck<T>::addToPile( const Vector<T> &items )
122{
123   mPile.merge( items );
124}
125
126template<class T>
127inline void MRandomDeck<T>::removeAll( Vector<T> *outItems )
128{
129   if ( outItems )
130   {
131      outItems->merge( mPile );
132      outItems->merge( mDeck );
133   }
134
135   mPile.clear();
136   mDeck.clear();
137}
138
139#endif //_MRANDOMDECK_H_
140