1 #include <assert.h> 2 #include <stdlib.h> 3 #include <SDL.h> 4 #include "cube.h" 5 #include "font.h" 6 #include "soundDev.h" 7 #include "view.h" 8 #include "bombView.h" 9 #include "bomb.h" BombSquad(Cube * _cube,unsigned int _dims,unsigned int _skillLevel,bool _wrap,BombSquadView * _view)10 NKlein_54321::BombSquad::BombSquad( 11 Cube* _cube, 12 unsigned int _dims, 13 unsigned int _skillLevel, 14 bool _wrap, 15 BombSquadView* _view 16 ) : cube( _cube ), 17 dims( _dims ), 18 skillLevel( _skillLevel ), 19 wrap( _wrap ), 20 view( _view ) 21 { 22 assert( cube != 0 ); 23 assert( dims > 1 ); 24 assert( dims <= NKlein_54321::Cube::DIMENSIONS ); 25 assert( NKlein_54321::Cube::DIMENSIONS <= 4 ); 26 assert( skillLevel < 3 ); 27 this->reset(); 28 } 29 void reset(void)30 NKlein_54321::BombSquad::reset( void ) 31 { 32 *this->cube = 0; 33 34 unsigned int table[ Cube::DIMENSIONS+1 ][ 3 ] = { 35 { 0, 0, 0 }, 36 { 1, 2, 3 }, 37 { 2, 4, 8 }, 38 { 4, 8, 16 }, 39 { 16, 32, 64 }, 40 }; 41 unsigned int bombs = table[ this->dims ][ this->skillLevel ]; 42 unsigned int len 43 = NKlein_54321::Cube::arrayLengths[ this->dims ]; 44 45 unsigned int* lut = new unsigned int[ bombs ]; 46 unsigned int lutLen = 0; 47 48 for ( unsigned int ii=0; ii < bombs; ++ii ) { 49 unsigned int index = random() % len--; 50 for ( unsigned int jj=0; jj < lutLen; ++jj ) { 51 if ( index >= lut[ jj ] ) { 52 ++index; 53 } 54 } 55 56 (*this->cube)[ index ] |= BOMB; 57 unsigned int nn[ 2 * NKlein_54321::Cube::DIMENSIONS ]; 58 unsigned int nc; 59 60 nc = NKlein_54321::Cube::getNeighbors( 61 nn, index, this->dims, this->wrap 62 ); 63 for ( unsigned int jj=0; jj < nc; ++jj ) { 64 ++(*this->cube)[ nn[ jj ] ]; 65 } 66 67 unsigned int spot = lutLen; 68 while ( spot > 0 && lut[ spot-1 ] > index ) { 69 lut[ spot ] = lut[ spot-1 ]; 70 --spot; 71 } 72 lut[ spot ] = index; 73 ++lutLen; 74 } 75 76 delete[] lut; 77 this->bombCount = bombs; 78 this->flagCount = 0; 79 this->coveredCount 80 = NKlein_54321::Cube::arrayLengths[ this->dims ]; 81 this->gameOver = false; 82 83 if ( this->view != 0 ) { 84 this->view->reset(); 85 this->view->redraw(); 86 } 87 } 88 void uncover(unsigned int index,bool click)89 NKlein_54321::BombSquad::uncover( 90 unsigned int index, bool click 91 ) 92 { 93 unsigned int cell = (*this->cube)[ index ]; 94 if ( ( cell & ( UNCOVERED | FLAG ) ) == 0 ) { 95 --this->coveredCount; 96 if ( click && this->view != 0 ) { 97 this->view->moveNoise(); 98 } 99 (*this->cube)[ index ] |= UNCOVERED; 100 if ( this->view != 0 ) { 101 this->view->redraw( index ); 102 } 103 104 if ( ( cell & BOMB ) != 0 ) { 105 if ( ! this->gameOver ) { 106 this->gameOver = true; 107 if ( this->view != 0 ) { 108 this->view->showLosing(); 109 } 110 } 111 } else if ( ( cell & 0x0FFF ) == 0 ) { 112 unsigned int nn[ 2 * NKlein_54321::Cube::DIMENSIONS ]; 113 unsigned int nc = this->cube->getNeighbors( 114 nn, index, this->dims, this->wrap 115 ); 116 117 for ( unsigned int ii=0; ii < nc; ++ii ) { 118 this->uncover( nn[ ii ], false ); 119 } 120 } 121 122 if ( click ) { 123 this->checkWinningCondition(); 124 } 125 } 126 } 127 void toggleFlag(unsigned int index)128 NKlein_54321::BombSquad::toggleFlag( 129 unsigned int index 130 ) 131 { 132 if ( ( (*this->cube)[ index ] & UNCOVERED ) == 0 ) { 133 (*this->cube)[ index ] ^= FLAG; 134 135 if ( ( (*this->cube)[ index ] & FLAG ) == 0 ) { 136 --this->flagCount; 137 } else { 138 ++this->flagCount; 139 } 140 141 if ( this->view != 0 ) { 142 this->view->moveNoise(); 143 this->view->redraw( index ); 144 } 145 146 this->checkWinningCondition(); 147 } 148 } 149 void checkWinningCondition(void)150 NKlein_54321::BombSquad::checkWinningCondition( void ) { 151 if ( ! this->gameOver 152 && this->flagCount == this->bombCount 153 && this->coveredCount == this->bombCount ) { 154 this->gameOver = true; 155 if ( this->view != 0 ) { 156 this->view->showWinning( 157 this->flagCount, this->bombCount 158 ); 159 } 160 } 161 }; 162