#include <iostream> #include <sstream> #include <Windows.h> #include <fstream> #include <string> using namespace std; struct Grid { int number = 0; bool is_fixed = false; }; class Sudoku { public: Sudoku() { init(); } void init() { for (int row = 0; row < 9; ++row) { for (int col = 0; col < 9; ++col) { data[row][col] = Grid(); } } } void set_fixed(int r, int c, int n) { Grid& g = data[r][c]; g.number = n; g.is_fixed = true; } bool set(int r, int c, int n) { if (data[r][c].is_fixed) { return false; } bool valid = true; auto validator = [&](Grid g) { if (g.number == n) { valid = false; } }; if (n != 0) { get_each_in_row(r, c, validator); get_each_in_col(r, c, validator); get_each_in_block(r, c, validator); } if (valid) { data[r][c].number = n; } return valid; } bool finished() { for (int r = 0; r < 9; ++r) { for (int c = 0; c < 9; ++c) { if (data[r][c].number == 0) { return false; } } } return true; } Grid get(int r, int c) { return data[r][c]; } private: Grid data[9][9]; template<typename Fn> void get_each_in_row(int r, int c, Fn f) { for (int i = 0; i < 9; ++i) { if (i != c) { f(data[r][i]); } } } template<typename Fn> void get_each_in_col(int r, int c, Fn f) { for (int i = 0; i < 9; ++i) { if (i != r) { f(data[i][c]); } } } template<typename Fn> void get_each_in_block(int r, int c, Fn f) { int block_rn = r / 3; int block_cn = c / 3; for (int br = 0; br < 3; ++br) { for (int bc = 0; bc < 3; ++bc) { int data_r = block_rn * 3 + br; int data_c = block_cn * 3 + bc; if (data_r != r && data_c != c) { f(data[data_r][data_c]); } } } } }; void move_to(int x, int y) { HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(hStdOut, coord); } template<typename T> void print(const T& arg) { wstringstream ss; ss << arg; HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD charsWritten; wstring str = ss.str(); WriteConsoleW(hStdOut, str.c_str(), str.size(), &charsWritten, NULL); } template<typename T1, typename T2, typename... Ts> void print(const T1& arg1, const T2& arg2, Ts... rest) { wstringstream ss; ss << arg1 << arg2; print(ss.str(), rest...); } void set_color(WORD color) { HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hStdOut, color); } void set_color() { set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } int main(int argc, char* argv[]) { Sudoku game; ifstream in("data.txt", ios::in); if (in) { int row = 0; string line; while (getline(in, line)) { int col = 0; for (char ch : line) { if (ch >= '1'&&ch <= '9') { game.set_fixed(row, col, ch - '0'); } ++col; if (col >= 9) { break; } } ++row; if (row >= 9) { break; } } in.close(); } HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); DWORD mode; GetConsoleMode(hStdIn, &mode); mode &= ~ENABLE_QUICK_EDIT_MODE; SetConsoleMode(hStdIn, mode); DWORD recordsRead; INPUT_RECORD record; int sel_x = 0, sel_y = 0; bool invalidated = true; while (true) { if (invalidated) { for (int r = 0; r < 9; ++r) { for (int c = 0; c < 9; ++c) { move_to(c, r); Grid g = game.get(r, c); if (r == sel_y && c == sel_x) { set_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); } else { if (g.is_fixed) { set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY); } else { set_color(); } } if (g.number == 0) { print('.'); } else { print(g.number); } } } if (game.finished()) { break; } invalidated = false; } ReadConsoleInputW(hStdIn, &record, 1, &recordsRead); if (record.EventType == MOUSE_EVENT) { auto evt = record.Event.MouseEvent; if (evt.dwEventFlags == 0) { auto pos = evt.dwMousePosition; if (evt.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { if (pos.X >= 0 && pos.X < 9 && pos.Y >= 0 && pos.Y < 9) { sel_x = pos.X; sel_y = pos.Y; invalidated = true; } } } } else if (record.EventType == KEY_EVENT) { auto evt = record.Event.KeyEvent; if (evt.bKeyDown) { if (evt.wVirtualKeyCode >= '1'&&evt.wVirtualKeyCode <= '9') { int num = evt.wVirtualKeyCode - '0'; if (game.set(sel_y, sel_x, num)) { invalidated = true; } } else if (evt.wVirtualKeyCode == VK_BACK) { if (game.set(sel_y, sel_x, 0)) { invalidated = true; } } else { switch (evt.wVirtualKeyCode) { case VK_UP: if (sel_y > 0) { --sel_y; invalidated = true; } break; case VK_DOWN: if (sel_y < 8) { ++sel_y; invalidated = true; } break; case VK_LEFT: if (sel_x > 0) { --sel_x; invalidated = true; } break; case VK_RIGHT: if (sel_x < 8) { ++sel_x; invalidated = true; } break; } } } } } move_to(0, 9); set_color(); print("Congratulations!\n"); system("pause"); }
130.78 KB, 下载次数: 99
芯☆淡茹水 发表于 2018-1-25 11:29
然而我连数独怎么玩都不知道。
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |