1. 程式人生 > 其它 >L型棋盤覆蓋問題以及解決C++ 控制檯清屏時閃屏現象

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 }