mRandomDeck.h
Engine/source/math/mRandomDeck.h
Classes:
class
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