189 lines
6.0 KiB
C++
189 lines
6.0 KiB
C++
#include "console_renderer.h"
|
|
#include "sudoku/sudoku.h"
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
/**
|
|
* Sudoku Demo with Real-time Console Rendering
|
|
*
|
|
* This demo shows how to use the SudokuRenderer to display and animate
|
|
* a Sudoku puzzle being solved in real-time without adding new lines.
|
|
*/
|
|
|
|
void demonstrateSudokuRendering() {
|
|
std::cout << "=== SUDOKU CONSOLE RENDERING DEMO ===" << std::endl;
|
|
std::cout << "This demo will show a Sudoku puzzle and simulate solving it." << std::endl;
|
|
std::cout << "Press Enter to continue..." << std::endl;
|
|
std::cin.get();
|
|
|
|
// Clear screen for clean demo
|
|
ConsoleRenderer::clearScreen();
|
|
|
|
// Create a sample Sudoku puzzle
|
|
std::string puzzle = "530070000600195000098000060800060003400803001700020006060000280000419005000080079";
|
|
Sudoku sudoku(puzzle);
|
|
|
|
// Create renderer
|
|
SudokuRenderer renderer(sudoku);
|
|
|
|
// Allocate space first (this is crucial!)
|
|
std::cout << "Allocating console space..." << std::endl;
|
|
ConsoleRenderer::sleep(1000);
|
|
renderer.allocateSpace();
|
|
|
|
// Initial render
|
|
std::cout << "Rendering initial puzzle..." << std::endl;
|
|
ConsoleRenderer::sleep(500);
|
|
renderer.render();
|
|
|
|
// Wait a moment
|
|
ConsoleRenderer::sleep(2000);
|
|
|
|
// Simulate solving some cells with animation
|
|
std::vector<std::tuple<int, int, uint8_t>> moves = {
|
|
{0, 2, 1}, {0, 5, 8}, {0, 7, 4}, {0, 8, 2},
|
|
{1, 0, 2}, {1, 3, 4}, {1, 6, 7}, {1, 8, 3},
|
|
{2, 2, 7}, {2, 4, 3}, {2, 5, 2}, {2, 7, 6},
|
|
{3, 1, 9}, {3, 3, 5}, {3, 6, 2}, {3, 8, 7},
|
|
{4, 0, 5}, {4, 2, 6}, {4, 6, 9}, {4, 8, 8}
|
|
};
|
|
|
|
renderer.showSolvingProgress("Starting to solve...");
|
|
ConsoleRenderer::sleep(1000);
|
|
|
|
for (size_t i = 0; i < moves.size(); ++i) {
|
|
auto [row, col, value] = moves[i];
|
|
|
|
// Update status
|
|
std::string status = "Solving step " + std::to_string(i + 1) + " of " + std::to_string(moves.size());
|
|
renderer.showSolvingProgress(status);
|
|
|
|
// Set the value
|
|
sudoku.set(row, col, value);
|
|
|
|
// Animate the change
|
|
renderer.animateCell(row, col, value, 200);
|
|
|
|
// Small delay between moves
|
|
ConsoleRenderer::sleep(300);
|
|
}
|
|
|
|
// Final render
|
|
renderer.showSolvingProgress("Partial solution completed!");
|
|
ConsoleRenderer::sleep(2000);
|
|
|
|
// Show final state
|
|
if (sudoku.isSolved()) {
|
|
renderer.showSolvingProgress("PUZZLE SOLVED!");
|
|
} else {
|
|
renderer.showSolvingProgress("Partial solution (demo complete)");
|
|
}
|
|
|
|
ConsoleRenderer::sleep(2000);
|
|
}
|
|
|
|
void demonstrateRealTimeUpdates() {
|
|
std::cout << "\n=== REAL-TIME UPDATE DEMO ===" << std::endl;
|
|
std::cout << "This shows how to update the puzzle without adding lines." << std::endl;
|
|
std::cout << "Press Enter to continue..." << std::endl;
|
|
std::cin.get();
|
|
|
|
ConsoleRenderer::clearScreen();
|
|
|
|
// Create empty sudoku
|
|
Sudoku sudoku;
|
|
SudokuRenderer renderer(sudoku);
|
|
|
|
// Allocate and render
|
|
renderer.allocateSpace();
|
|
renderer.render();
|
|
|
|
ConsoleRenderer::sleep(1000);
|
|
|
|
// Add numbers one by one
|
|
std::vector<std::tuple<int, int, uint8_t>> sequence = {
|
|
{0, 0, 5}, {0, 1, 3}, {0, 4, 7},
|
|
{1, 0, 6}, {1, 3, 1}, {1, 4, 9}, {1, 5, 5},
|
|
{2, 1, 9}, {2, 2, 8}, {2, 7, 6},
|
|
{3, 0, 8}, {3, 4, 6}, {3, 8, 3},
|
|
{4, 0, 4}, {4, 3, 8}, {4, 5, 3}, {4, 8, 1}
|
|
};
|
|
|
|
for (const auto& [row, col, value] : sequence) {
|
|
renderer.showSolvingProgress("Adding number " + std::to_string(value) +
|
|
" at (" + std::to_string(row + 1) + "," + std::to_string(col + 1) + ")");
|
|
|
|
sudoku.set(row, col, value);
|
|
renderer.renderWithHighlight(row, col);
|
|
ConsoleRenderer::sleep(800);
|
|
|
|
renderer.render();
|
|
ConsoleRenderer::sleep(200);
|
|
}
|
|
|
|
renderer.showSolvingProgress("Real-time update demo complete!");
|
|
ConsoleRenderer::sleep(2000);
|
|
}
|
|
|
|
void showAPIUsage() {
|
|
std::cout << "\n=== API USAGE EXAMPLE ===" << std::endl;
|
|
std::cout << "Here's how to use the SudokuRenderer API:" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 1. Create a Sudoku puzzle" << std::endl;
|
|
std::cout << "Sudoku sudoku(\"530070000600195000...\");" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 2. Create renderer" << std::endl;
|
|
std::cout << "SudokuRenderer renderer(sudoku);" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 3. IMPORTANT: Allocate space first!" << std::endl;
|
|
std::cout << "renderer.allocateSpace();" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 4. Render initial state" << std::endl;
|
|
std::cout << "renderer.render();" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 5. Update puzzle and re-render" << std::endl;
|
|
std::cout << "sudoku.set(0, 0, 5);" << std::endl;
|
|
std::cout << "renderer.render(); // Updates in place!" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "// 6. Optional: Use animations" << std::endl;
|
|
std::cout << "renderer.animateCell(row, col, value);" << std::endl;
|
|
std::cout << "renderer.showSolvingProgress(\"Status\");" << std::endl;
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "Press Enter to continue..." << std::endl;
|
|
std::cin.get();
|
|
}
|
|
|
|
int main() {
|
|
try {
|
|
// Hide cursor for cleaner display
|
|
ConsoleRenderer::hideCursor();
|
|
|
|
// Run demonstrations
|
|
showAPIUsage();
|
|
demonstrateSudokuRendering();
|
|
demonstrateRealTimeUpdates();
|
|
|
|
// Show cursor again
|
|
ConsoleRenderer::showCursor();
|
|
|
|
std::cout << "\n=== DEMO COMPLETE ===" << std::endl;
|
|
std::cout << "The SudokuRenderer provides a clean API for real-time puzzle rendering!" << std::endl;
|
|
|
|
} catch (const std::exception& e) {
|
|
ConsoleRenderer::showCursor();
|
|
std::cerr << "Error: " << e.what() << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|