C++实现鼠标控制的黑框象棋

时间:2022-11-02 17:04:46

本文实例为大家分享了C++实现鼠标控制的黑框象棋的具体代码,供大家参考,具体内容如下

该象棋小游戏的特色

有颜色标注出 红方和绿方
可以用鼠标控制

颜色原理

直接调用用Windows自带的颜色API
用到了 颜色头文件.h

代码.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//consolecolor.hpp这是着色的实现头文件
#pragma once
#include<Windows.h>//调用win32API函数
#include<iostream>//调用flush成员函数,首先刷新缓冲区
namespace color//命名空间为color,防止名字冲突
{
    //颜色常量定义,分为掩码,前景色,背景色
    static const WORD bgMask(BACKGROUND_BLUE |
        BACKGROUND_GREEN |
        BACKGROUND_RED |
        BACKGROUND_INTENSITY);
    static const WORD fgMask(FOREGROUND_BLUE |
        FOREGROUND_GREEN |
        FOREGROUND_RED |
        FOREGROUND_INTENSITY);
 
    static const WORD fgBlack(0);
    static const WORD fgLoRed(FOREGROUND_RED);
    static const WORD fgLoGreen(FOREGROUND_GREEN);
    static const WORD fgLoBlue(FOREGROUND_BLUE);
    static const WORD fgLoCyan(fgLoGreen | fgLoBlue);
    static const WORD fgLoMagenta(fgLoRed | fgLoBlue);
    static const WORD fgLoYellow(fgLoRed | fgLoGreen);
    static const WORD fgLoWhite(fgLoRed | fgLoGreen | fgLoBlue);
    static const WORD fgGray(fgBlack | FOREGROUND_INTENSITY);
    static const WORD fgHiWhite(fgLoWhite | FOREGROUND_INTENSITY);
    static const WORD fgHiBlue(fgLoBlue | FOREGROUND_INTENSITY);
    static const WORD fgHiGreen(fgLoGreen | FOREGROUND_INTENSITY);
    static const WORD fgHiRed(fgLoRed | FOREGROUND_INTENSITY);
    static const WORD fgHiCyan(fgLoCyan | FOREGROUND_INTENSITY);
    static const WORD fgHiMagenta(fgLoMagenta | FOREGROUND_INTENSITY);
    static const WORD fgHiYellow(fgLoYellow | FOREGROUND_INTENSITY);
    static const WORD bgBlack(0);
    static const WORD bgLoRed(BACKGROUND_RED);
    static const WORD bgLoGreen(BACKGROUND_GREEN);
    static const WORD bgLoBlue(BACKGROUND_BLUE);
    static const WORD bgLoCyan(bgLoGreen | bgLoBlue);
    static const WORD bgLoMagenta(bgLoRed | bgLoBlue);
    static const WORD bgLoYellow(bgLoRed | bgLoGreen);
    static const WORD bgLoWhite(bgLoRed | bgLoGreen | bgLoBlue);
    static const WORD bgGray(bgBlack | BACKGROUND_INTENSITY);
    static const WORD bgHiWhite(bgLoWhite | BACKGROUND_INTENSITY);
    static const WORD bgHiBlue(bgLoBlue | BACKGROUND_INTENSITY);
    static const WORD bgHiGreen(bgLoGreen | BACKGROUND_INTENSITY);
    static const WORD bgHiRed(bgLoRed | BACKGROUND_INTENSITY);
    static const WORD bgHiCyan(bgLoCyan | BACKGROUND_INTENSITY);
    static const WORD bgHiMagenta(bgLoMagenta | BACKGROUND_INTENSITY);
    static const WORD bgHiYellow(bgLoYellow | BACKGROUND_INTENSITY);
    //设置颜色的实现函数,主要是调用win32的API和一些位运算。
    void setConsoleColor(WORD mask, WORD c)
    {
        static HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
        if(hStdout==NULL)return;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        GetConsoleScreenBufferInfo(hStdout, &csbi);
        csbi.wAttributes &= ~mask;
        csbi.wAttributes |= c;
        SetConsoleTextAttribute(hStdout, csbi.wAttributes);
    }
    //用到模板是为了通用,不仅cout,cerr可以染色,wcout,wcerr等也可以着色,自己定义的流只要满足模板都可以。
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_white(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgLoWhite);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_blue(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiBlue);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_green(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiGreen);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_red(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiRed);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_cyan(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiCyan);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_magenta(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiMagenta);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_yellow(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgHiYellow);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& fg_black(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(fgMask, fgBlack);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_white(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgLoWhite);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_blue(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiBlue);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_green(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiGreen);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_red(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiRed);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_cyan(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiCyan);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_magenta(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiMagenta);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_yellow(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgHiYellow);
        return os;
    }
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& bg_black(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgBlack);
        return os;
    }
    //清空屏幕,还原本色
    template<typename charT, typename traits>
    inline std::basic_ostream<charT, traits>& clr(std::basic_ostream<charT, traits>& os)
    {
        os.flush();
        setConsoleColor(bgMask, bgBlack);
        setConsoleColor(fgMask, fgLoWhite);
        system("cls");
        return os;
    }
}

鼠标控制原理

直接调用windows自带的鼠标控制函数
注意,如果直接使用清屏函数 system(“clr”)会导致鼠标输入阻塞所以要自己重新编译一个清屏函数

鼠标代码.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void MyCls(HANDLE hConsole)
{
COORD coordScreen={0,0};//设置清屏后光标返回的屏幕左上角坐标
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;//保存缓冲区信息
DWORD dwConSize;//当前缓冲区可容纳的字符数
bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息
PERR(bSuccess,"GetConsoleScreenBufferInfo");
dwConSize=csbi.dwSize.X * csbi.dwSize.Y;//缓冲区容纳字符数目
//用空格填充缓冲区
bSuccess=FillConsoleOutputCharacter(hConsole,(TCHAR)' ',dwConSize,coordScreen,&cCharsWritten);
PERR(bSuccess,"FillConsoleOutputCharacter");
bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息
PERR(bSuccess,"ConsoleScreenBufferInfo");
//填充缓冲区属性
bSuccess=FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,coordScreen,&cCharsWritten);
PERR(bSuccess,"FillConsoleOutputAttribute");
//光标返回屏幕左上角坐标
bSuccess=SetConsoleCursorPosition(hConsole,coordScreen);
PERR(bSuccess,"SetConsoleCursorPosition");
return;
}

自定义清屏函数.

?
1
2
3
4
5
6
void clrscr(void)
{
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
MyCls(hStdOut);
return;
}

象棋的具体实现细节

定义了一个棋盘chessboard,和一个棋子控制的类chess,对不同的棋子有自己的类,定义有特定的ID和每个棋子特定的走法规则。还有对棋盘控制的move()函数。

总体代码.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
#include <iostream>
#include <memory.h>
#include <math.h>
#include<windows.h>
#include<winuser.h>
#include"颜色头文件.h"
#include<conio.h>
#include <stdlib.h>
#include <stdio.h>
#define PERR(bSuccess, api){if(!(bSuccess)) printf("%s:Error %d from %s on line %d\n", __FILE__, GetLastError(), api, __LINE__);}
 
void MyCls(HANDLE) ;
void clrscr(void)
{
HANDLE hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
MyCls(hStdOut);
return;
}
void MyCls(HANDLE hConsole)
{
COORD coordScreen={0,0};//设置清屏后光标返回的屏幕左上角坐标
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi;//保存缓冲区信息
DWORD dwConSize;//当前缓冲区可容纳的字符数
bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息
PERR(bSuccess,"GetConsoleScreenBufferInfo");
dwConSize=csbi.dwSize.X * csbi.dwSize.Y;//缓冲区容纳字符数目
//用空格填充缓冲区
bSuccess=FillConsoleOutputCharacter(hConsole,(TCHAR)' ',dwConSize,coordScreen,&cCharsWritten);
PERR(bSuccess,"FillConsoleOutputCharacter");
bSuccess=GetConsoleScreenBufferInfo(hConsole,&csbi);//获得缓冲区信息
PERR(bSuccess,"ConsoleScreenBufferInfo");
//填充缓冲区属性
bSuccess=FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,coordScreen,&cCharsWritten);
PERR(bSuccess,"FillConsoleOutputAttribute");
//光标返回屏幕左上角坐标
bSuccess=SetConsoleCursorPosition(hConsole,coordScreen);
PERR(bSuccess,"SetConsoleCursorPosition");
return;
}
using namespace color;
using namespace std;//存储结构:chess类是基类,派生类是各种棋子,在chessboard类中用chess的指针调用各个棋子
class chessboard;
//鼠标控制参数
 
//
bool turn=0;
class chess{
private:
    int id;//等级
public:
    chess(int i):id(i){}
    int get(){return id;}
    virtual bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy)=0;
    virtual ~chess(){};//虚析构
};
 
class chessboard{
private:
    chess *c[10][9];//用指针调用各个棋子,实现多态
    char chessword[15][4]={"帅","相","炮","士","車","馬","兵","","卒","馬","車","士","炮","象","将"};//名字
public:
    chessboard(){memset(c, NULL, sizeof(c));};//把指针初始化为零指针
    void init();
    chess* get(int x,int y){return c[x][y];}
    int getid(int x,int y){ if(c[x][y]!=NULL) return c[x][y]->get();return 0;}
    void show();
    void play();
    bool move(int startx,int starty,int aimx,int aimy);
    ~chessboard();//析构函数
    static bool end;//判断结束
    static int player;
};
 
bool chessboard::end=true;
int chessboard::player=-1;
 
bool chessboard::move(int startx,int starty,int aimx,int aimy){
    if(startx>=0&&startx<10&&starty>=0&&starty<9//初步判断传入的点是否符合规则
       &&aimx>=0&&aimx<10&&aimy>=0&&aimy<9
       &&getid(startx,starty)&&getid(startx,starty)*player>0
       &&c[startx][starty]->judge_move(*this,startx,starty,aimx,aimy)){
        if(c[aimx][aimy]!=NULL) delete c[aimx][aimy];//吃子
        c[aimx][aimy]=c[startx][starty];
        c[startx][starty]=NULL;
    player*=-1;
    if(turn==0)
  turn=1;
    else
  turn=0;
    return true;
    }
    //cout<<"走法错误,不符合规则"<<endl;
    return false;
}
 
class horse : public chess{//马的实现
public:
    horse(int i) : chess((i==0?-2:2)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&(tempx*tempx+tempy*tempy==5)&&!cb.get(startx+tempx/2,starty+tempy/2))
        return true;
        return false;
    }
};
 
class soldier : public chess{//兵(卒)的实现
public:
    soldier(int c) : chess((c==0?-1:1)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&sid*tempx<=0){
            if(abs(tempx)==1&&tempy==0) return true;
            if(abs(tempy)==1&&tempx==0)
                if((startx/5==0&&sid>0)||(startx/5==1&&sid<0)) return true;
            return false;
        }
        return false;
    }
};
 
class general : public chess{//帅(将)的实现
public:
    general(int c) : chess((c==0?-7:7)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&tempy*tempy+tempx*tempx==1&&aimx%7>=0&&aimx%7<=2&&aimy>=3&&aimy<=5)
            return true;
        return false;
    }
    ~general(){chessboard::end=false;}
};
 
class elephant : public chess{//象(相)的实现
public:
    elephant(int c) : chess((c==0?-6:6)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&tempy*tempy+tempx*tempx==8&&startx/5==aimx/5&&!cb.get(startx+tempx/2,starty+tempy/2))
            return true;
        return false;
    }
};
 
class cannon : public chess{//炮的实现
public:
    cannon(int c) : chess((c==0?-5:5)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&!(tempx&&tempy)&&(tempx+tempy)){
            int tot=0;
            if(tempx!=0){
                int sign=tempx>0?1:-1;
                for(int i=1;i<abs(tempx);i++)
                    if(cb.get(startx+sign*i,starty)) tot++;
            }
            else{
                int sign=tempy>0?1:-1;
                for(int i=1;i<abs(tempy);i++)
                    if(cb.get(startx,starty+sign*i)) tot++;
            }
            if(!aid)
            {if(!tot) return true;}
            else
            {if(tot==1) return true;}
        }
        return false;
    }
};
 
class guard: public chess{//士(仕)的实现
public:
    guard(int c) : chess((c==0?-4:4)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&tempy*tempy+tempx*tempx==2&&aimx%7>=0&&aimx%7<=2&&aimy>=3&&aimy<=5)
            return true;
        return false;
    }
};
 
class rook : public chess{//车的实现
public:
    rook(int c) : chess((c==0?-3:3)){}
    bool judge_move(chessboard &cb,int startx,int starty,int aimx,int aimy){
        int tempx=aimx-startx,tempy=aimy-starty;
        int sid=cb.getid(startx, starty),aid=cb.getid(aimx, aimy);
        if(sid*aid<=0&&!(tempx&&tempy)&&(tempx+tempy)){
            if(tempx!=0){
                int sign=tempx>0?1:-1;
                for(int i=1;i<abs(tempx);i++)
                    if(cb.get(startx+sign*i,starty)) return false;
            }
            else{
                int sign=tempy>0?1:-1;
                for(int i=1;i<abs(tempy);i++)
                    if(cb.get(startx,starty+sign*i)) return false;
            }
                return true;
        }
        return false;
    }
};
 
chessboard :: ~chessboard(){
    for(int i=0;i<10;i++)
        for(int j=0;j<9;j++)
            if(c[i][j]!=NULL){
                delete c[i][j];
                c[i][j]=NULL;
            }
}
 
void chessboard :: init(){//初始化,棋子的生成
    c[0][0]=new rook(0);        c[0][8]=new rook(0);
    c[0][1]=new horse(0);       c[0][7]=new horse(0);
    c[0][2]=new elephant(0);    c[0][6]=new elephant(0);
    c[0][3]=new guard(0);       c[0][5]=new guard(0);
    c[0][4]=new general(0);     c[9][4]=new general(1);
    c[2][1]=new cannon(0);      c[2][7]=new cannon(0);
    c[3][0]=new soldier(0);     c[3][2]=new soldier(0);
    c[3][4]=new soldier(0);     c[3][6]=new soldier(0);
    c[3][8]=new soldier(0);     c[6][8]=new soldier(1);
    c[6][0]=new soldier(1);     c[6][2]=new soldier(1);
    c[6][4]=new soldier(1);     c[6][6]=new soldier(1);
    c[7][1]=new cannon(1);      c[7][7]=new cannon(1);
    c[9][0]=new rook(1);        c[9][8]=new rook(1);
    c[9][1]=new horse(1);       c[9][7]=new horse(1);
    c[9][2]=new elephant(1);    c[9][6]=new elephant(1);
    c[9][3]=new guard(1);       c[9][5]=new guard(1);
}
 
void chessboard :: show(){
    cout<<fg_yellow<<"    零一二三四五六七八"<<endl<<endl;
    char num[10][4]={"零","一","二","三","四","五","六","七","八","九"};
    for(int i=0;i<6/*10*/;i++){
        if(i==5) cout<<fg_white<<"   ——楚 河 汉 界——"<<endl;
        cout<<fg_yellow<<num[i]<<"  ";
        for(int j=0;j<9;j++){
            if(c[i][j]!=NULL)
            {
             if(c[i][j]->get()>0)
              cout<<fg_red<<chessword[c[i][j]->get()+7];
    else
     cout<<fg_green<<chessword[c[i][j]->get()+7];
            }
            else if((i==1&&j==4)||(i==8&&j==4))
                cout<<fg_yellow<<"米";
            else
                cout<<fg_yellow<<"十";
        }
        cout<<endl;
    }
    
    for(int i=6;i<10/*10*/;i++){
        cout<<fg_yellow<<num[i]<<"  ";
        for(int j=0;j<9;j++){
            if(c[i][j]!=NULL)
            {
             if(c[i][j]->get()>0)
              cout<<fg_red<<chessword[c[i][j]->get()+7];
    else
     cout<<fg_green<<chessword[c[i][j]->get()+7];
            }
            else if((i==1&&j==4)||(i==8&&j==4))
                cout<<fg_yellow<<"米";
            else
                cout<<fg_yellow<<"十";
        }
        cout<<endl;
    }
    
    
}
 
void chessboard::play(){
 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
 HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
 
 CONSOLE_SCREEN_BUFFER_INFO bInfo;
 INPUT_RECORD mouseRec;
 DWORD res;
    this->init();
    this->show();
   do{
       int startx,starty,aimx,aimy;
        int sid,aid;
        do{
            sid=aid=0;
            if(turn==0)
            {
             clrscr();
          this->show();
             cout<<fg_blue<<"请绿方行动" <<endl;
             //turn=1;
   }
   else
   {
    clrscr();
          this->show();
    cout<<fg_blue<<"请红方行动"<<endl;
    //turn=0;
   }  
   
        repeat:
  while(1){
  Sleep(110);
  //this->show();
  ReadConsoleInput(hIn, &mouseRec, 1, &res);
  if(mouseRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED){
   //system("cls");
   //this->show();
   if(mouseRec.Event.MouseEvent.dwMousePosition.X%2==1)
    starty=(mouseRec.Event.MouseEvent.dwMousePosition.X-5)/2;
   else
    starty=(mouseRec.Event.MouseEvent.dwMousePosition.X-4)/2;
   if(mouseRec.Event.MouseEvent.dwMousePosition.Y<7)
    startx=mouseRec.Event.MouseEvent.dwMousePosition.Y-2;
   else
    startx=mouseRec.Event.MouseEvent.dwMousePosition.Y-3;
   if(c[startx][starty]==NULL)
    goto repeat;
   //cout<<"startx:"<<startx<<endl;
   //cout<<"starty:"<<starty<<endl;
   break;
  }
  }
  cout<<"please give me next position"<<endl;
  while(1){
  Sleep(110);
  //this->show();
  ReadConsoleInput(hIn, &mouseRec, 1, &res);
  if(mouseRec.Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED){
   //system("cls");
   //this->show();
   if(mouseRec.Event.MouseEvent.dwMousePosition.X%2==1)
    aimy=(mouseRec.Event.MouseEvent.dwMousePosition.X-5)/2;
   else
    aimy=(mouseRec.Event.MouseEvent.dwMousePosition.X-4)/2;
   if(mouseRec.Event.MouseEvent.dwMousePosition.Y<7)
    aimx=mouseRec.Event.MouseEvent.dwMousePosition.Y-2;
   else
    aimx=mouseRec.Event.MouseEvent.dwMousePosition.Y-3;
   
   //cout<<"aimx:"<<aimx<<endl;
   //cout<<"aimy:"<<aimy<<endl;
   break;
  }
  }
   
   //cin>>startx>>starty>>aimx>>aimy;
        }while(!this->move(startx,starty,aimx,aimy));
        //clrscr();
        //this->show();
    }while(chessboard::end);
    if(chessboard::player==1)
     cout<<"结束,赢家是绿方"<<endl;
    else
  cout<<"结束,赢家是红方" <<endl;
}
 
int main(){
 HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
 DWORD mode;
 GetConsoleMode(hStdin, &mode);
 mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
 //mode &= ~ENABLE_INSERT_MODE; //移除插入模式
 //mode &= ~ENABLE_MOUSE_INPUT;
 SetConsoleMode(hStdin, mode);
    chessboard C;
    C.play();
}

运行图片

居中的图片:

C++实现鼠标控制的黑框象棋

总结

本质类似与键盘输入的象棋小游戏和鼠标控制的五子棋小游戏的综合。其中碰到一个小问题,就是黑窗要把快速便捷模式取消了才可以利用鼠标点击,为了解决这个问题,我在主函数插入了自动取消快速编辑的函数。

?
1
2
3
4
5
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
 DWORD mode;
 GetConsoleMode(hStdin, &mode);
 mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
 SetConsoleMode(hStdin, mode);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq473626818/article/details/116702339