summary refs log tree commit diff stats
path: root/gamestate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gamestate.cpp')
-rw-r--r--gamestate.cpp104
1 files changed, 52 insertions, 52 deletions
diff --git a/gamestate.cpp b/gamestate.cpp index 3ff08c4..18e41c2 100644 --- a/gamestate.cpp +++ b/gamestate.cpp
@@ -22,12 +22,12 @@ class GameBoard {
22 void render(SDL_Renderer* renderer, int level) const; 22 void render(SDL_Renderer* renderer, int level) const;
23 bool isObstructed(int x, int y) const; 23 bool isObstructed(int x, int y) const;
24 bool operator<(const GameBoard& other) const; 24 bool operator<(const GameBoard& other) const;
25 25
26 private: 26 private:
27 void initialize(int level); 27 void initialize(int level);
28 int solve(int playerx, int playery) const; 28 int solve(int playerx, int playery) const;
29 std::string dump() const; 29 std::string dump() const;
30 30
31 std::bitset<WIDTH*HEIGHT> blocks; 31 std::bitset<WIDTH*HEIGHT> blocks;
32 std::bitset<WIDTH*HEIGHT> updateable; 32 std::bitset<WIDTH*HEIGHT> updateable;
33 int oldx; 33 int oldx;
@@ -38,7 +38,7 @@ class LoadGameState : public State {
38 public: 38 public:
39 LoadGameState(int level); 39 LoadGameState(int level);
40 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 40 State* operator() (SDL_Window* window, SDL_Renderer* renderer);
41 41
42 private: 42 private:
43 int level; 43 int level;
44}; 44};
@@ -47,7 +47,7 @@ class PlayGameState : public State {
47 public: 47 public:
48 PlayGameState(int level, GameBoard* board, int playerx, int playery); 48 PlayGameState(int level, GameBoard* board, int playerx, int playery);
49 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 49 State* operator() (SDL_Window* window, SDL_Renderer* renderer);
50 50
51 private: 51 private:
52 bool move(int x, int y); 52 bool move(int x, int y);
53 int level; 53 int level;
@@ -111,7 +111,7 @@ State* LoadGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
111 char* wintitle = new char[50]; 111 char* wintitle = new char[50];
112 sprintf(wintitle, "Maze Of Life - Level %d", level); 112 sprintf(wintitle, "Maze Of Life - Level %d", level);
113 SDL_SetWindowTitle(window, wintitle); 113 SDL_SetWindowTitle(window, wintitle);
114 114
115 // Randomly place the player in a corner 115 // Randomly place the player in a corner
116 int playerx, playery; 116 int playerx, playery;
117 switch (rand()%4) 117 switch (rand()%4)
@@ -121,11 +121,11 @@ State* LoadGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
121 case 2: playerx = WIDTH-2; playery = HEIGHT-2; break; 121 case 2: playerx = WIDTH-2; playery = HEIGHT-2; break;
122 case 3: playerx = WIDTH-2; playery = 1; break; 122 case 3: playerx = WIDTH-2; playery = 1; break;
123 } 123 }
124 124
125 // Display the level number 125 // Display the level number
126 setRendererDeadColor(renderer, level); 126 setRendererDeadColor(renderer, level);
127 SDL_RenderClear(renderer); 127 SDL_RenderClear(renderer);
128 128
129 TTF_Font* font = loadFont(100); 129 TTF_Font* font = loadFont(100);
130 SDL_Color fontColor = {0, 0, 0, 0}; 130 SDL_Color fontColor = {0, 0, 0, 0};
131 char levelnum[8]; 131 char levelnum[8];
@@ -133,21 +133,21 @@ State* LoadGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
133 SDL_Surface* dispsurf = TTF_RenderText_Solid(font, levelnum, fontColor); 133 SDL_Surface* dispsurf = TTF_RenderText_Solid(font, levelnum, fontColor);
134 SDL_Texture* disptext = SDL_CreateTextureFromSurface(renderer, dispsurf); 134 SDL_Texture* disptext = SDL_CreateTextureFromSurface(renderer, dispsurf);
135 SDL_FreeSurface(dispsurf); 135 SDL_FreeSurface(dispsurf);
136 136
137 SDL_Rect pos; 137 SDL_Rect pos;
138 SDL_QueryTexture(disptext, NULL, NULL, &pos.w, &pos.h); 138 SDL_QueryTexture(disptext, NULL, NULL, &pos.w, &pos.h);
139 pos.x = 240-(pos.w/2); 139 pos.x = 240-(pos.w/2);
140 pos.y = 240-(pos.h/2); 140 pos.y = 240-(pos.h/2);
141 141
142 SDL_RenderCopy(renderer, disptext, NULL, &pos); 142 SDL_RenderCopy(renderer, disptext, NULL, &pos);
143 SDL_RenderPresent(renderer); 143 SDL_RenderPresent(renderer);
144 144
145 // Do 50 gens of Conway 145 // Do 50 gens of Conway
146 GameBoard* board = new GameBoard(level, playerx, playery); 146 GameBoard* board = new GameBoard(level, playerx, playery);
147 147
148 // Wait a bit 148 // Wait a bit
149 SDL_Delay(500); 149 SDL_Delay(500);
150 150
151 // Start the level 151 // Start the level
152 return new PlayGameState(level, board, playerx, playery); 152 return new PlayGameState(level, board, playerx, playery);
153} 153}
@@ -163,15 +163,15 @@ PlayGameState::PlayGameState(int m_level, GameBoard* m_board, int m_playerx, int
163State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer) 163State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
164{ 164{
165 SDL_Event e; 165 SDL_Event e;
166 166
167 for (;;) 167 for (;;)
168 { 168 {
169 // Tick board 169 // Tick board
170 board->tick(playerx, playery); 170 board->tick(playerx, playery);
171 171
172 // Paint board 172 // Paint board
173 board->render(renderer, level); 173 board->render(renderer, level);
174 174
175 // Paint event 175 // Paint event
176 SDL_Rect block; 176 SDL_Rect block;
177 block.w = 16; 177 block.w = 16;
@@ -180,15 +180,15 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
180 block.y = 15*16; 180 block.y = 15*16;
181 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); 181 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
182 SDL_RenderFillRect(renderer, &block); 182 SDL_RenderFillRect(renderer, &block);
183 183
184 // Paint player 184 // Paint player
185 block.x = playerx*16; 185 block.x = playerx*16;
186 block.y = playery*16; 186 block.y = playery*16;
187 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); 187 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
188 SDL_RenderFillRect(renderer, &block); 188 SDL_RenderFillRect(renderer, &block);
189 189
190 SDL_RenderPresent(renderer); 190 SDL_RenderPresent(renderer);
191 191
192 while (SDL_PollEvent(&e)) 192 while (SDL_PollEvent(&e))
193 { 193 {
194 if (e.type == SDL_QUIT) 194 if (e.type == SDL_QUIT)
@@ -205,7 +205,7 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
205 } else { 205 } else {
206 break; 206 break;
207 } 207 }
208 208
209 case SDLK_RIGHT: 209 case SDLK_RIGHT:
210 if (move(playerx+1, playery)) 210 if (move(playerx+1, playery))
211 { 211 {
@@ -213,7 +213,7 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
213 } else { 213 } else {
214 break; 214 break;
215 } 215 }
216 216
217 case SDLK_UP: 217 case SDLK_UP:
218 if (move(playerx, playery-1)) 218 if (move(playerx, playery-1))
219 { 219 {
@@ -221,7 +221,7 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
221 } else { 221 } else {
222 break; 222 break;
223 } 223 }
224 224
225 case SDLK_DOWN: 225 case SDLK_DOWN:
226 if (move(playerx, playery+1)) 226 if (move(playerx, playery+1))
227 { 227 {
@@ -229,10 +229,10 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
229 } else { 229 } else {
230 break; 230 break;
231 } 231 }
232 232
233 case SDLK_ESCAPE: 233 case SDLK_ESCAPE:
234 SDL_SetWindowTitle(window, ""); 234 SDL_SetWindowTitle(window, "");
235 235
236 std::ifstream exists(getDataFile()); 236 std::ifstream exists(getDataFile());
237 if (exists) 237 if (exists)
238 { 238 {
@@ -278,7 +278,7 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
278 } 278 }
279 } 279 }
280 } 280 }
281 281
282 SDL_Delay(5); 282 SDL_Delay(5);
283 } 283 }
284} 284}
@@ -286,7 +286,7 @@ State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer)
286bool PlayGameState::move(int x, int y) 286bool PlayGameState::move(int x, int y)
287{ 287{
288 wrap(&x, &y); 288 wrap(&x, &y);
289 289
290 // Are we at the event? 290 // Are we at the event?
291 if ((x==15)&&(y==15)) 291 if ((x==15)&&(y==15))
292 { 292 {
@@ -299,7 +299,7 @@ bool PlayGameState::move(int x, int y)
299 playerx = x; 299 playerx = x;
300 playery = y; 300 playery = y;
301 } 301 }
302 302
303 return false; 303 return false;
304} 304}
305 305
@@ -311,12 +311,12 @@ GameBoard::GameBoard(int level, int playerx, int playery)
311 updateable.set(); 311 updateable.set();
312 oldx = playerx; 312 oldx = playerx;
313 oldy = playery; 313 oldy = playery;
314 314
315 for (int i=0; i<50; i++) 315 for (int i=0; i<50; i++)
316 { 316 {
317 tick(playerx, playery); 317 tick(playerx, playery);
318 } 318 }
319 319
320 int states = solve(playerx, playery); 320 int states = solve(playerx, playery);
321 if (states != 0) 321 if (states != 0)
322 { 322 {
@@ -341,7 +341,7 @@ void GameBoard::tick(int playerx, int playery)
341 int tdy = oldy+dy; 341 int tdy = oldy+dy;
342 wrap(&tdx, &tdy); 342 wrap(&tdx, &tdy);
343 tempdateable.set(tdx+tdy*WIDTH); 343 tempdateable.set(tdx+tdy*WIDTH);
344 344
345 tdx = playerx+dx; 345 tdx = playerx+dx;
346 tdy = playery+dy; 346 tdy = playery+dy;
347 wrap(&tdx, &tdy); 347 wrap(&tdx, &tdy);
@@ -349,10 +349,10 @@ void GameBoard::tick(int playerx, int playery)
349 } 349 }
350 } 350 }
351 } 351 }
352 352
353 oldx = playerx; 353 oldx = playerx;
354 oldy = playery; 354 oldy = playery;
355 355
356 updateable.reset(); 356 updateable.reset();
357 357
358 for (int y=0;y<HEIGHT;y++) 358 for (int y=0;y<HEIGHT;y++)
@@ -381,7 +381,7 @@ void GameBoard::tick(int playerx, int playery)
381 } else { 381 } else {
382 blocks[x+y*WIDTH] = (neighbors == 3); 382 blocks[x+y*WIDTH] = (neighbors == 3);
383 } 383 }
384 384
385 if (temp[x+y*WIDTH] != blocks[x+y*WIDTH]) 385 if (temp[x+y*WIDTH] != blocks[x+y*WIDTH])
386 { 386 {
387 for (int dy = -1; dy <= 1; dy++) 387 for (int dy = -1; dy <= 1; dy++)
@@ -404,21 +404,21 @@ void GameBoard::render(SDL_Renderer* renderer, int level) const
404 SDL_Rect block; 404 SDL_Rect block;
405 block.w = 16; 405 block.w = 16;
406 block.h = 16; 406 block.h = 16;
407 407
408 for (int y=0; y<HEIGHT; y++) 408 for (int y=0; y<HEIGHT; y++)
409 { 409 {
410 for (int x=0; x<WIDTH; x++) 410 for (int x=0; x<WIDTH; x++)
411 { 411 {
412 block.x = x*16; 412 block.x = x*16;
413 block.y = y*16; 413 block.y = y*16;
414 414
415 if (blocks[x+y*WIDTH]) 415 if (blocks[x+y*WIDTH])
416 { 416 {
417 setRendererAliveColor(renderer, level); 417 setRendererAliveColor(renderer, level);
418 } else { 418 } else {
419 setRendererDeadColor(renderer, level); 419 setRendererDeadColor(renderer, level);
420 } 420 }
421 421
422 SDL_RenderFillRect(renderer, &block); 422 SDL_RenderFillRect(renderer, &block);
423 } 423 }
424 } 424 }
@@ -436,7 +436,7 @@ void GameBoard::initialize(int level)
436 for (int x=0; x<WIDTH; x++) 436 for (int x=0; x<WIDTH; x++)
437 { 437 {
438 blocks[x+y*WIDTH] = false; 438 blocks[x+y*WIDTH] = false;
439 439
440 switch (level/10+1) 440 switch (level/10+1)
441 { 441 {
442 case 1: 442 case 1:
@@ -464,7 +464,7 @@ void GameBoard::initialize(int level)
464 } 464 }
465 } 465 }
466 } 466 }
467 467
468 blocks[15+15*WIDTH] = false; 468 blocks[15+15*WIDTH] = false;
469} 469}
470 470
@@ -477,7 +477,7 @@ bool GameBoard::operator<(const GameBoard& other) const
477 return other.blocks[i]; 477 return other.blocks[i];
478 } 478 }
479 } 479 }
480 480
481 return false; 481 return false;
482} 482}
483 483
@@ -486,32 +486,32 @@ int GameBoard::solve(int playerx, int playery) const
486 std::deque<std::tuple<int, int, GameBoard, int>> search; 486 std::deque<std::tuple<int, int, GameBoard, int>> search;
487 std::set<std::tuple<int, int, GameBoard>> done; 487 std::set<std::tuple<int, int, GameBoard>> done;
488 search.push_front(std::make_tuple(playerx, playery, *this, 0)); 488 search.push_front(std::make_tuple(playerx, playery, *this, 0));
489 489
490 bool exists = false; 490 bool exists = false;
491 while (!search.empty()) 491 while (!search.empty())
492 { 492 {
493 auto cur = search.front(); 493 auto cur = search.front();
494 search.pop_front(); 494 search.pop_front();
495 495
496 int cpx = std::get<0>(cur); 496 int cpx = std::get<0>(cur);
497 int cpy = std::get<1>(cur); 497 int cpy = std::get<1>(cur);
498 GameBoard& cbr = std::get<2>(cur); 498 GameBoard& cbr = std::get<2>(cur);
499 int cns = std::get<3>(cur); 499 int cns = std::get<3>(cur);
500 500
501 auto cdn = std::make_tuple(cpx, cpy, cbr); 501 auto cdn = std::make_tuple(cpx, cpy, cbr);
502 done.insert(cdn); 502 done.insert(cdn);
503 503
504 if (((cpx == 15) && ((cpy == 14) || (cpy == 16))) || ((cpy == 15) && ((cpx == 14) || (cpx == 16)))) 504 if (((cpx == 15) && ((cpy == 14) || (cpy == 16))) || ((cpy == 15) && ((cpx == 14) || (cpx == 16))))
505 { 505 {
506 exists = true; 506 exists = true;
507 break; 507 break;
508 } 508 }
509 509
510 if (cns >= 100) 510 if (cns >= 100)
511 { 511 {
512 continue; 512 continue;
513 } 513 }
514 514
515 GameBoard immnext {cbr}; 515 GameBoard immnext {cbr};
516 immnext.tick(cpx, cpy); 516 immnext.tick(cpx, cpy);
517 if (immnext.blocks != cbr.blocks) 517 if (immnext.blocks != cbr.blocks)
@@ -519,30 +519,30 @@ int GameBoard::solve(int playerx, int playery) const
519 if (done.count(std::make_tuple(cpx, cpy, immnext)) == 0) 519 if (done.count(std::make_tuple(cpx, cpy, immnext)) == 0)
520 { 520 {
521 search.push_front(std::make_tuple(cpx, cpy, immnext, cns)); 521 search.push_front(std::make_tuple(cpx, cpy, immnext, cns));
522 522
523 continue; 523 continue;
524 } 524 }
525 } 525 }
526 526
527 std::vector<std::pair<int, int>> dirchanges {{cpx-1,cpy}, {cpx,cpy-1}, {cpx+1,cpy}, {cpx,cpy+1}}; 527 std::vector<std::pair<int, int>> dirchanges {{cpx-1,cpy}, {cpx,cpy-1}, {cpx+1,cpy}, {cpx,cpy+1}};
528 std::sort(std::begin(dirchanges), std::end(dirchanges), [] (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) { 528 std::sort(std::begin(dirchanges), std::end(dirchanges), [] (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) {
529 int lhd = sqrt(pow(15 - lhs.first, 2.0) + pow(15 - lhs.second, 2.0)); 529 int lhd = sqrt(pow(15 - lhs.first, 2.0) + pow(15 - lhs.second, 2.0));
530 int rhd = sqrt(pow(15 - rhs.first, 2.0) + pow(15 - rhs.second, 2.0)); 530 int rhd = sqrt(pow(15 - rhs.first, 2.0) + pow(15 - rhs.second, 2.0));
531 531
532 return lhd > rhd; 532 return lhd > rhd;
533 }); 533 });
534 534
535 for (auto& dirchange : dirchanges) 535 for (auto& dirchange : dirchanges)
536 { 536 {
537 GameBoard next {cbr}; 537 GameBoard next {cbr};
538 int npx = cpx + dirchange.first; 538 int npx = cpx + dirchange.first;
539 int npy = cpy + dirchange.second; 539 int npy = cpy + dirchange.second;
540 wrap(&npx, &npy); 540 wrap(&npx, &npy);
541 541
542 if (!next.isObstructed(npx, npy)) 542 if (!next.isObstructed(npx, npy))
543 { 543 {
544 next.tick(npx, npy); 544 next.tick(npx, npy);
545 545
546 if (done.count(std::make_tuple(npx, npy, next)) == 0) 546 if (done.count(std::make_tuple(npx, npy, next)) == 0)
547 { 547 {
548 search.push_front(std::make_tuple(npx, npy, next, cns+1)); 548 search.push_front(std::make_tuple(npx, npy, next, cns+1));
@@ -550,7 +550,7 @@ int GameBoard::solve(int playerx, int playery) const
550 } 550 }
551 } 551 }
552 } 552 }
553 553
554 if (exists) 554 if (exists)
555 { 555 {
556 return done.size(); 556 return done.size();
@@ -568,6 +568,6 @@ std::string GameBoard::dump() const
568 int chunk = (8 * blocks[i*4]) + (4 * blocks[i*4+1]) + (2 * blocks[i*4+2]) + blocks[i*4+3]; 568 int chunk = (8 * blocks[i*4]) + (4 * blocks[i*4+1]) + (2 * blocks[i*4+2]) + blocks[i*4+3];
569 output << chunk; 569 output << chunk;
570 } 570 }
571 571
572 return output.str(); 572 return output.str();
573} 573}