Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <ctime>
- #include <random>
- #include "timer.cpp"
- // std::chrono::steady_clock?
- std::mt19937_64 mt_rand(time(0));
- class Board
- {
- int * board;
- int width, height;
- int binMask;
- void reset(int);
- public:
- Board(int, int);
- void display();
- void newRandomBoard(int);
- void newRandomBoard2(int);
- int getSquare(int, int);
- int totalCallsToRand;
- };
- Board::Board(int width, int height){
- // std::unique_pointer<int> ?
- std::cout << "In Board constructor" << std::endl;
- board = new int[height*width];
- for(int i=0; i<height*width; i++){
- board[i] = i%10;
- }
- binMask = 1;
- while(binMask < height*width) {
- binMask <<= 1;
- binMask++;
- }
- this->width = width;
- this->height = height;
- totalCallsToRand = 0;
- }
- void Board::display() {
- int i, j;
- std::cout << "+";
- for (i=0; i<width*2-1; i++){
- std::cout << "-";
- }
- std::cout << "+" << std::endl;
- for (i=0; i<height; i++){
- std::cout << "|";
- for (j=0; j<width; j++) {
- std::cout << getSquare(i, j);
- if (j < width-1){std::cout << " ";}
- }
- std::cout << "|" << std::endl;
- }
- std::cout << "+";
- for (i=0; i<width*2-1; i++){
- std::cout << "-";
- }
- std::cout << "+" << std::endl;
- }
- int Board::getSquare(int row, int column){
- if (0 <= row && 0 <= column){
- if (row < height && column < width) {
- return board[row*width + column];
- }
- }
- std::cout << "Warning. Out of bounds." << std::endl;
- return -1;
- }
- void Board::reset(int val){
- for (int i=0;i<width*height;i++){
- board[i] = val;
- }
- }
- void Board::newRandomBoard(int mines){
- int area = width*height;
- if(mines > area/2){
- std::cout << "Too many mines" << std::endl;
- return;
- }
- reset(0);
- for (int i=0;i<mines;i++) {
- int done = 0;
- while (done == 0){
- int xy = mt_rand() & binMask;
- totalCallsToRand++;
- if (xy < area && board[xy] == 0){
- done++;
- board[xy] = 1;
- }
- }
- }
- }
- void Board::newRandomBoard2(int mines) {
- int area = width*height;
- mines = (mines<0) ? 0 : ((mines>area) ? area : mines);
- int initialState = 0;
- int changedState = 1;
- if (mines > area/2) {
- initialState = 1;
- changedState = 0;
- mines = area - mines;
- }
- reset(initialState);
- int mask = 1;
- while(mask < area-mines){
- mask<<=1; mask++;
- }
- // Now we do the shuffle
- for (int i=area-mines; i<area; i++) {
- int gotRand = 0;
- int index;
- while(gotRand==0){
- index = mt_rand() & mask; // Take a power of 2 for good randomness
- totalCallsToRand++;
- if(index <= i){
- gotRand++;
- }
- }
- board[i] = board[index];
- board[index] = changedState;
- if (mask == i){
- mask<<=1; mask++;
- }
- }
- }
- void test(Board board) {
- for(int i=0;i<1000;i++){
- board.newRandomBoard2(99);
- }
- std::cout << "Total rand calls: " << board.totalCallsToRand << std::endl;
- }
- int main()
- {
- Board board(30, 16);
- Timer timer;
- timer.start();
- test(board);
- double elapsed = timer.stop();
- std::cout << elapsed << std::endl;
- std::cout << "Total rand calls: " << board.totalCallsToRand << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement