// board.cc // // Copyright 2000 Daniel Burrows // // Definitions for the Minesweeper board (from board.h) #include "board.h" #include using namespace std; int rngrand(int max) // Returns a random number between 0 and max-1 { return (int) ((float) rand()*max/RAND_MAX); } void mine_board::init_board(int _width, int _height, int _mines) { width=_width; height=_height; covered_squares=_width*_height; mines=0; flags=0; state=playing; if(_mines>width*height) _mines=width*height; // Allocate a (blank) board board=new board_entry[width*height]; for(int i=0; i<_mines; i++) { int x,y; do { x=rngrand(_width); y=rngrand(_height); } while(get_entry(x, y).contains_mine); seed_square(x, y); } starttime=time(0); eassert(mines==_mines); } void mine_board::seed_square(int x, int y) // This could be an ugly routine with 9 cases. I've decided to do something // slightly less efficient but quicker to write..you could argue it's more // readable and/or elegant, but really I'm just lazy ;-) // Anyway, I don't think this will be a speed bottleneck, so a sloppy version // is probably fine { eassert(!get_entry(x, y).contains_mine); for(int i=x-1; i<=x+1; i++) if(i>=0 && i=0 && j>width>>height>>_total_mines>>_remaining_mines>>_duration; time(&starttime); starttime-=_duration; _flags=_total_mines-_remaining_mines; flags=mines=0; covered_squares=width*height; state=playing; if(s.fail()) return false; delete[] board; // Just in case. board=new board_entry[width*height]; for(int y=0; y>c; if(s.fail()) { delete[] board; board=NULL; return false; } switch(c) { case '+': break; case '*': seed_square(x, y); break; case 'f': get_entry(x, y).flagged=true; flags++; break; case 'F': get_entry(x, y).flagged=true; flags++; seed_square(x, y); // This makes sure that the counters are properly updated. break; default: if(c>='0' && c<='9') { get_entry(x, y).uncovered=true; covered_squares--; } else { delete[] board; board=NULL; return false; } } } if(flags!=_flags || mines!=_total_mines) { delete[] board; board=NULL; return false; } return true; } void mine_board::print(ostream &o) { for(int y=0; y=0 && i=0 && j=0 && i=0 && j0 && get_entry(x, y).flagged && !get_entry(x, y).uncovered) { get_entry(x, y).flagged=false; flags--; return true; } else return false; }