1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
#ifndef NIM_MOVE_SELECTOR_HPP
#define NIM_MOVE_SELECTOR_HPP

/* collect acceptable moves and chose one of them by random;
   this is done using the reservoir-sampling algorithm by
   Donald Knuth for the special case with one entry.
*/

#include "NimMove.hpp"
#include "UniformIntDistribution.hpp"

class NimMoveSelector {
   public:
      NimMoveSelector() : moves{0}, selected{}, uniform{} {
      }
      void add(NimMove move) {
     ++moves;
     if (moves == 1 || uniform.draw(moves) == 0) {
        selected = move;
     }
      }
      NimMove get() const {
     return selected;
      }
      unsigned int get_count() const {
     return moves;
      }
   private:
      unsigned int moves;
      NimMove selected;
      UniformIntDistribution uniform;
};

#endif