L型棋盘覆盖问题以及解决C++ 控制台清屏时闪屏现象
棋盘覆盖--老生常谈的问题,不在追叙。
重点是找到了解决控制台闪屏的方法。
1 HANDLE hOutput; //设备句柄 2 COORD coord = { 0,0 }; 3 hOutput = GetStdHandle(STD_OUTPUT_HANDLE); 4 5 //把system("cls"),替换为以下语句 6 CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; 7 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); 8 SetConsoleCursorPosition(hOutput, coord);
对于方法的解释:
1、HANDLE GetStdHandle( _In_ DWORD nStdHandle);
说明,获取标准设备句柄
nStdHandle 标准设备,可取值:
STD_INPUT_HANDLE (DWORD)-10,输入设备
STD_OUTPUT_HANDLE (DWORD)-11,输出设备
STD_ERROR_HANDLE (DWORD)-12,错误设备
调用返回:
成功,返回设备句柄(HANDLE);
失败,返回 INVALID_HANDLE_VALUE;
如果没有标准设备,返回 NULL。
2、BOOL SetConsoleCursorPosition( _In_ HANDLE hConsoleOutput, _In_ COORD dwCursorPosition);
说明,设置控制台光标位置
hConsoleOutput 控制台输出设备句柄
dwCursorPosition 光标位置
3、BOOL WINAPISetConsoleCursorInfo( _In_ HANDLE hConsoleOutput, _In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo);
说明,设置控制台光标信息
hConsoleOutput,控制台输出设备句柄
lpConsoleCursorInfo,光标信息(大小、可见性)
已知其然,不知其所以然。
棋盘覆盖算法:
1 #define rep(i,a,b) for(int i=a;i<(b);i++) 2 #define trav(a,x) for(auto& a:x) 3 #define all(x) begin(x),end(x) 4 #define sz(x) (int)(x).size() 5 6 using namespace std; 7 8 typedef long long ll; 9 typedef long double ld; 10 typedef pair<int, int> pii; 11 typedef pair<ll, ll> pll; 12 typedef vector<int> vi; 13 typedef vector<vi> vii; 14 15 //打印棋盘,用于更新 16 void printBorder(vii &border, int len); 17 //分治--> 更新 18 void cover(vii &border, pii LT, pii zang, int lengt); 19 20 static int lran = 1; 21 int KLen = 2; 22 23 HANDLE hOutput; 24 COORD coord = { 0,0 }; 25 26 int main() 27 { 28 hOutput = GetStdHandle(STD_OUTPUT_HANDLE); 29 //■◆●○ 30 int k = 4; 31 int blen = 2 << k; 32 vii border(blen, vi(blen, 0)); 33 34 //棋盘初始化 35 unsigned int seed = time(0); 36 srand(seed); 37 int x = (rand() % (blen - 0)); 38 int y = (rand() % (blen - 0)); 39 border[x][y] = 1; 40 41 //左上角坐标 42 pii LT(0, 0); 43 //脏点坐标 44 pii zang(x, y); 45 KLen = blen; 46 cover(border, LT, zang, blen); 47 48 return 0; 49 } 50 51 void printBorder(vii &border, int len) { 52 Sleep(500); 53 CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; 54 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); 55 SetConsoleCursorPosition(hOutput, coord);//清屏 56 rep(i, 0, len) { 57 rep(j, 0, len) { 58 int li = (rand() % (6 - 0)); 59 if (border[i][j] == 0) 60 cout << setw(2) << "○"; 61 else if (border[i][j] == -1) 62 cout << setw(2) << "X"; 63 else 65 cout << setw(2) << "●"; 67 } 68 cout << endl; 69 } 70 } 71 72 void cover(vii &border, pii LT, pii zang, int len) { 73 74 if (len <= 2) { 75 rep(x, LT.first, LT.first + len) { 76 rep(y, LT.second, LT.second + len) { 77 if (border[x][y] == 0) 78 border[x][y] = lran; 79 } 80 lran++; 81 } 82 83 printBorder(border, KLen ); 84 } 85 else { 86 int zx = (zang.first - LT.first) * 2 / len; 87 int zy = (zang.second - LT.second) * 2 / len; 88 89 rep(x, LT.first+len / 2 - 1, LT.first + len / 2 + 1) { 90 rep(y, LT.second + len / 2 - 1, LT.second + len / 2 + 1) { 91 border[x][y] = 1; 92 } 93 } 94 border[LT.first +(len / 2-1)+zx][LT.second + zy + (len / 2-1)] = 0; 95 printBorder(border, KLen); 96 97 rep(x, LT.first + len / 2 - 1, LT.first + len / 2 + 1) { 98 rep(y, LT.second + len / 2 - 1, LT.second + len / 2 + 1) { 99 int zx = (x - LT.first) * 2 / len; 100 int zy = (y - LT.second) * 2 / len; 101 if (border[x][y] == 1) 102 cover(border, pii(LT.first + zx * len / 2, LT.second + zy * len / 2), pii(x, y), len / 2); 103 else 104 cover(border, pii(LT.first + zx * len / 2, LT.second + zy * len / 2), zang, len / 2); 105 } 106 } 107 } 108 }