赞 | 14 |
VIP | 0 |
好人卡 | 1 |
积分 | 18 |
经验 | 2716 |
最后登录 | 2022-6-5 |
在线时间 | 133 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1803
- 在线时间
- 133 小时
- 注册时间
- 2013-10-6
- 帖子
- 193
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
刚才看到了这个如何使用RPGMaker制作数独小游戏
然后闲得蛋疼花了一小时用C++写了个控制台版本的】明早还赶飞机呀 赶紧先滚床了
支持鼠标键盘操作,输入数字填入,Backspace删除
逻辑封装在Sudoku class里了 应该很好写成JS/Ruby吧 来试试?】@无终
随机生成的话rand一下就可以了】class里有判别准则
#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"); }
#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");
}
|
|