void tutorial_game::add_message(game *g, tut_lesson lesson) { // Cycle through intro lessons if (lesson == LESSON_INTRO) { while (lesson != NUM_LESSONS && tutorials_seen[lesson]) { switch (lesson) { case LESSON_INTRO: lesson = LESSON_MOVE; break; case LESSON_MOVE: lesson = LESSON_LOOK; break; case LESSON_LOOK: lesson = NUM_LESSONS; break; } } if (lesson == NUM_LESSONS) return; } if (tutorials_seen[lesson]) return; tutorials_seen[lesson] = true; popup_top(tut_text[lesson].c_str()); g->refresh_all(); }
int minesweeper_game::start_game() { const int iCenterX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0; const int iCenterY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0; WINDOW *w_minesweeper_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iCenterY, iCenterX); WINDOW_PTR w_minesweeper_borderptr( w_minesweeper_border ); WINDOW *w_minesweeper = newwin(FULL_SCREEN_HEIGHT - 2, FULL_SCREEN_WIDTH - 2, iCenterY + 1, iCenterX + 1); WINDOW_PTR w_minesweeperptr( w_minesweeper ); draw_border(w_minesweeper_border); std::vector<std::string> shortcuts; shortcuts.push_back(_("<n>ew level")); shortcuts.push_back(_("<f>lag")); shortcuts.push_back(_("<q>uit")); int iWidth = 0; for( auto &shortcut : shortcuts ) { if ( iWidth > 0 ) { iWidth += 1; } iWidth += utf8_width(shortcut); } int iPos = FULL_SCREEN_WIDTH - iWidth - 1; for( auto &shortcut : shortcuts ) { shortcut_print(w_minesweeper_border, 0, iPos, c_white, c_ltgreen, shortcut); iPos += utf8_width(shortcut) + 1; } mvwputch(w_minesweeper_border, 0, 2, hilite(c_white), _("Minesweeper")); wrefresh(w_minesweeper_border); input_context ctxt("MINESWEEPER"); ctxt.register_cardinal(); ctxt.register_action("NEW"); ctxt.register_action("FLAG"); ctxt.register_action("CONFIRM"); ctxt.register_action("QUIT"); ctxt.register_action("HELP_KEYBINDINGS"); static const std::array<int, 9> aColors = {{ c_white, c_ltgray, c_cyan, c_blue, c_ltblue, c_green, c_magenta, c_red, c_yellow }}; int iScore = 5; int iPlayerY = 0; int iPlayerX = 0; std::function<void (int, int)> rec_reveal = [&](const int y, const int x) { if ( mLevelReveal[y][x] == unknown || mLevelReveal[y][x] == flag ) { mLevelReveal[y][x] = seen; if ( mLevel[y][x] == 0 ) { const auto circle = closest_tripoints_first( 1, {x, y, 0} ); for( const auto &p : circle ) { if ( p.x >= 0 && p.x < iLevelX && p.y >= 0 && p.y < iLevelY ) { if ( mLevelReveal[p.y][p.x] != seen ) { rec_reveal(p.y, p.x); } } } mvwputch(w_minesweeper, iOffsetY + y, iOffsetX + x, c_black, " "); } else { mvwputch(w_minesweeper, iOffsetY + y, iOffsetX + x, (x == iPlayerX && y == iPlayerY) ? hilite(aColors[mLevel[y][x]]) : aColors[mLevel[y][x]], to_string(mLevel[y][x])); } } }; int iDirY, iDirX; std::string action = "NEW"; do { if (action == "NEW") { new_level(w_minesweeper); iPlayerY = 0; iPlayerX = 0; } wrefresh(w_minesweeper); if (check_win()) { popup_top(_("Congratulations, you won!")); iScore = 30; action = "QUIT"; } else { action = ctxt.handle_input(); } if (ctxt.get_direction(iDirX, iDirY, action)) { if ( iPlayerX + iDirX >= 0 && iPlayerX + iDirX < iLevelX && iPlayerY + iDirY >= 0 && iPlayerY + iDirY < iLevelY ) { std::string sGlyph; nc_color cColor; for ( int i=0; i < 2; i++ ) { cColor = c_white; if ( mLevelReveal[iPlayerY][iPlayerX] == flag ) { sGlyph = "!"; cColor = c_yellow; } else if ( mLevelReveal[iPlayerY][iPlayerX] == seen ) { if ( mLevel[iPlayerY][iPlayerX] == 0 ) { sGlyph = " "; cColor = c_black; } else { sGlyph = to_string(mLevel[iPlayerY][iPlayerX]); cColor = aColors[mLevel[iPlayerY][iPlayerX]]; } } else { sGlyph = '#'; } mvwputch(w_minesweeper, iOffsetY + iPlayerY, iOffsetX + iPlayerX, (i == 0) ? cColor : hilite(cColor), sGlyph.c_str()); if ( i == 0 ) { iPlayerX += iDirX; iPlayerY += iDirY; } } } } else if (action == "FLAG") { if ( mLevelReveal[iPlayerY][iPlayerX] == unknown ) { mLevelReveal[iPlayerY][iPlayerX] = flag; mvwputch(w_minesweeper, iOffsetY + iPlayerY, iOffsetX + iPlayerX, hilite(c_yellow), "!"); } else if ( mLevelReveal[iPlayerY][iPlayerX] == flag ) { mLevelReveal[iPlayerY][iPlayerX] = unknown; mvwputch(w_minesweeper, iOffsetY + iPlayerY, iOffsetX + iPlayerX, hilite(c_white), "#"); } } else if (action == "CONFIRM") { if ( mLevelReveal[iPlayerY][iPlayerX] != seen ) { if ( mLevel[iPlayerY][iPlayerX] == (int)bomb ) { for ( int y = 0; y < iLevelY; y++ ) { for ( int x = 0; x < iLevelX; x++ ) { if (mLevel[y][x] == (int)bomb) { mvwputch(w_minesweeper, iOffsetY + y, iOffsetX + x, hilite(c_red), (mLevelReveal[y][x] == flag) ? "!" : "*" ); } } } wrefresh(w_minesweeper); popup_top(_("Boom, you're dead! Better luck next time.")); action = "QUIT"; } else if ( mLevelReveal[iPlayerY][iPlayerX] == unknown ) { rec_reveal(iPlayerY, iPlayerX); } } } } while (action != "QUIT"); return iScore; }