1.VS Code有哪些常用的快捷键? Visual Studio Code常用快捷键大全
2.äºè§£go-microä¸çtransport
3.BoltDB源码解析(七)Put和Delete操作
4.用C++编写的小游戏源代码
VS Code有哪些常用的快捷键? Visual Studio Code常用快捷键大全
Visual Studio Code是一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。深受广大用户的喜欢。而,VS Code有哪些常用的好的源码有哪些快捷键?是很多朋友都想知道的问题,今天小编就给大家带来了Visual Studio Code常用快捷键大全,并附有Visual Studio Code官方英文快捷键,需要的朋友一起去看看吧!Visual Studio Code常用快捷键大全
按 Press功能 FunctionCtrl + Shift + P,F1显示命令面板 Show Command PaletteCtrl + P快速打开 Quick OpenCtrl + Shift + N新窗口/实例 New window/instanceCtrl + Shift + W关闭窗口/实例 Close window/instance基础编辑 Basic editing
按 Press功能 FunctionCtrl+X剪切行(空选定) Cut line (empty selection)Ctrl+C复制行(空选定)Copy line (empty selection)Alt+ / 向上/向下移动行 Move line up/downShift+Alt + / 向上/向下复制行 Copy line up/downCtrl+Shift+K删除行 Delete lineCtrl+Enter在下面插入行 Insert line belowCtrl+Shift+Enter在上面插入行 Insert line aboveCtrl+Shift+\跳到匹配的括号 Jump to matching bracketCtrl+] / [缩进/缩进行 Indent/outdent lineHome转到行首 Go to beginning of lineEnd转到行尾 Go to end of lineCtrl+Home转到文件开头 Go to beginning of fileCtrl+End转到文件末尾 Go to end of fileCtrl+ / 向上/向下滚动行 Scroll line up/downAlt+PgUp / PgDown向上/向下滚动页面 Scroll page up/downCtrl+Shift+[折叠(折叠)区域 Fold (collapse) regionCtrl+Shift+]展开(未折叠)区域 Unfold (uncollapse) regionCtrl+K Ctrl+[折叠(未折叠)所有子区域 Fold (collapse) all subregionsCtrl+K Ctrl+]展开(未折叠)所有子区域 Unfold (uncollapse) all subregionsCtrl+K Ctrl+0折叠(折叠)所有区域 Fold (collapse) all regionsCtrl+K Ctrl+J展开(未折叠)所有区域 Unfold (uncollapse) all regionsCtrl+K Ctrl+C添加行注释 Add line commentCtrl+K Ctrl+U删除行注释 Remove line commentCtrl+/切换行注释 Toggle line commentShift+Alt+A切换块注释 Toggle block commentAlt+Z切换换行 Toggle word wrap导航 Navigation
按 Press功能 FunctionCtrl + T显示所有符号 Show all SymbolsCtrl + G转到行... Go to Line...Ctrl + P转到文件... Go to File...Ctrl + Shift + O转到符号... Go to Symbol...Ctrl + Shift + M显示问题面板 Show Problems panelF8转到下一个错误或警告 Go to next error or warningShift + F8转到上一个错误或警告 Go to previous error or warningCtrl + Shift + Tab导航编辑器组历史记录 Navigate editor group historyAlt + /返回/前进 Go back / forwardCtrl + M切换选项卡移动焦点 Toggle Tab moves focus搜索和替换 Search and replace
按 Press功能 FunctionCtrl + F查找 FindCtrl + H替换 ReplaceF3 / Shift + F3查找下一个/上一个 Find next/previousAlt + Enter选择查找匹配的所有出现 Select all occurences of Find matchCtrl + D将选择添加到下一个查找匹配 Add selection to next Find matchCtrl + K Ctrl + D将最后一个选择移至下一个查找匹配项 Move last selection to next Find matchAlt + C / R / W切换区分大小写/正则表达式/整个词 Toggle case-sensitive / regex / whole word多光标和选择 Multi-cursor and selection
按 Press功能 FunctionAlt +单击插入光标 Insert cursorCtrl + Alt +/在上/下插入光标 Insert cursor above / belowCtrl + U撤消上一个光标操作 Undo last cursor operationShift + Alt + I在选定的每一行的末尾插入光标 Insert cursor at end of each line selectedCtrl + I选择当前行 Select current lineCtrl + Shift + L选择当前选择的所有出现 Select all occurrences of current selectionCtrl + F2选择当前字的所有出现 Select all occurrences of current wordShift + Alt + 展开选择 Expand selectionShift + Alt + 缩小选择 Shrink selectionShift + Alt + (拖动鼠标)列(框)选择 Column (box) selectionCtrl + Shift + Alt +(箭头键)列(框)选择 Column (box) selectionCtrl + Shift + Alt + PgUp / PgDown列(框)选择页上/下 Column (box) selection page up/down丰富的语言编辑 Rich languages editing
按 Press功能 FunctionCtrl + 空格触发建议 Trigger suggestionCtrl + Shift + Space触发器参数提示 Trigger parameter hintsTabEmmet 展开缩写 Emmet expand abbreviationShift + Alt + F格式化文档 Format documentCtrl + K Ctrl + F格式选定区域 Format selectionF转到定义 Go to DefinitionAlt + FPeek定义 Peek DefinitionCtrl + K F打开定义到边 Open Definition to the sideCtrl + .快速解决 Quick FixShift + F显示引用 Show ReferencesF2重命名符号 Rename SymbolCtrl + Shift + . /,替换为下一个/上一个值 Replace with next/previous valueCtrl + K Ctrl + X修剪尾随空格 Trim trailing whitespaceCtrl + K M更改文件语言 Change file language编辑器管理 Editor management
按 Press功能 FunctionCtrl+F4, Ctrl+W关闭编辑器 Close editorCtrl+K F关闭文件夹 Close folderCtrl+\拆分编辑器 Split editorCtrl+ 1 / 2 / 3聚焦到第1,第2或第3编辑器组 Focus into 1st, 2nd or 3rd editor groupCtrl+K Ctrl+ /聚焦到上一个/下一个编辑器组 Focus into previous/next editor groupCtrl+Shift+PgUp / PgDown向左/向右移动编辑器 Move editor left/rightCtrl+K / 移动活动编辑器组 Move active editor group文件管理 File management
按 Press功能 FunctionCtrl+N新文件 New FileCtrl+O打开文件... Open File...Ctrl+S保存 SaveCtrl+Shift+S另存为... Save As...Ctrl+K S全部保存 Save AllCtrl+F4关闭 CloseCtrl+K Ctrl+W关闭所有 Close AllCtrl+Shift+T重新打开关闭的编辑器 Reopen closed editorCtrl+K输入保持打开 Enter Keep OpenCtrl+Tab打开下一个 Open nextCtrl+Shift+Tab打开上一个 Open previousCtrl+K P复制活动文件的路径 Copy path of active fileCtrl+K R显示资源管理器中的活动文件 Reveal active file in ExplorerCtrl+K O显示新窗口/实例中的活动文件 Show active file in new window/instance显示 Display
按 Press功能 FunctionF切换全屏 Toggle full screenShift+Alt+1切换编辑器布局 Toggle editor layoutCtrl+ = / -放大/缩小 Zoom in/outCtrl+B切换侧栏可见性 Toggle Sidebar visibilityCtrl+Shift+E显示浏览器/切换焦点 Show Explorer / Toggle focusCtrl+Shift+F显示搜索 Show SearchCtrl+Shift+G显示Git Show GitCtrl+Shift+D显示调试 Show DebugCtrl+Shift+X显示扩展 Show ExtensionsCtrl+Shift+H替换文件 Replace in filesCtrl+Shift+J切换搜索详细信息 Toggle Search detailsCtrl+Shift+C打开新命令提示符/终端 Open new command prompt/terminalCtrl+Shift+U显示输出面板 Show Output panelCtrl+Shift+V切换Markdown预览 Toggle Markdown previewCtrl+K V从旁边打开Markdown预览 Open Markdown preview to the side调试 Debug
按 Press功能 FunctionF9切换断点 Toggle breakpointF5开始/继续 Start/ContinueShift+F5停止 StopF / Shift+F下一步/上一步 Step into/outF跳过 Step overCtrl+K Ctrl+I显示悬停 Show hover集成终端 Integrated terminal
按 Press功能 FunctionCtrl+`显示集成终端 Show integrated terminalCtrl+Shift+`创建新终端 Create new terminalCtrl+Shift+C复制选定 Copy selectionCtrl+Shift+V粘贴到活动端子 Paste into active terminalCtrl+ / 向上/向下滚动 Scroll up/downShift+PgUp / PgDown向上/向下滚动页面 Scroll page up/downCtrl+Home / End滚动到顶部/底部 Scroll to top/bottomVisual Studio Code官方英文快捷键大全
/shortcuts/keyboard-shortcuts-windows.pdf
文章结束,以上就是关于VS Code有哪些常用的快捷键? Visual Studio Code常用快捷键大全的全部内容,是不是很全面呢?如果你觉得这篇文章还不错,而且对你有帮助,那就赶快分享给更多的人看到吧!
äºè§£go-microä¸çtransport
è¿ç¯æç« ä»ç»çtransportä¸æ¯æ们å¦ä¹ çéç¹ï¼å ä¸ºä½ å¯è½ç¨ä¸å°ä»ï¼ä½æ¯ä½ä¸ºå¦ä¹ go-microçä¸é¨åï¼è¿æ¯å¾æä¸ä¸ãtransportç¨äºæå¡é´éä¿¡ï¼åºäºsocketçsend/recvè¯ä¹ãå ¶æ¥å£çæ¹æ³éå¦ä¸ï¼
typeTransportinterface{ Init(...Option)errorOptions()OptionsDial(addrstring,opts...DialOption)(Client,error)Listen(addrstring,opts...ListenOption)(Listener,error)String()string}var(DefaultTransportTransport=NewHTTPTransport()DefaultDialTimeout=time.Second*5)主è¦çä½ç¨ä½ç°å¨DialåListenæ¹æ³ä¸ï¼
func(h*/asim/go-micro/examples/v3/greeter/srv/proto/hello""github.com/asim/go-micro/v3""github.com/asim/go-micro/v3/util/log""google.golang.org/grpc")typeSaystruct{ }func(s*Say)Hello(ctxcontext.Context,req*hello.Request,rsp*hello.Response)error{ log.Log("ReceivedSay.Hellorequest")rsp.Msg="Hello"+req.Namereturnnil}funcmain(){ gofunc(){ for{ grpc.DialContext(context.TODO(),".0.0.1:")time.Sleep(time.Second)}}()service:=micro.NewService(micro.Name("go.micro.srv.greeter"),)//optionallysetupcommandlineusageservice.Init()//RegisterHandlershello.RegisterSayHandler(service.Server(),new(Say))//Runserveriferr:=service.Run();err!=nil{ log.Fatal(err)}}æå ³æå¡é´é信使ç¨çprotoç»æä½
syntax="proto3";packagego.micro.srv.greeter;serviceSay{ rpcHello(Request)returns(Response){ }}messageRequest{ stringname=1;}messageResponse{ stringmsg=1;}å¯å¨æå¡çæ¶åï¼éè¿æ¥å¿è¾åº,å¯ä»¥å¤§è´çäºè§£å¯å¨è¿ç¨
--::file=v3@v3.5.2-0.-cbbbc/service.go:level=infoStarting[service]go.micro.srv.greeter--::file=server/rpc_server.go:level=infoTransport[mit的时候。事务的Commit实现
下面是事务commit的代码简化,保留了重要部分:
Commit的整体流程比较长,下面一点一点进行说明。
tx.root.rebalance(),html画图程序源码这个root是root Bucket,rebalance是对root Bucket下所有子Bucket的所有node进行rebalance。这是什么意思?注意node的初始数据虽然来自一个page,但在经历了一些Delete操作后,有些node里面的数据可能过少,这时会先把这个node和它的左兄弟或右兄弟node合并(node的rebalance方法),合并后node数会减少,但不存在node里数据过少的情况。这个操作对应于B-tree的merge操作,只不过这些node都是Go的内存结构,合并起来非常简单。当然,合并后把这些node spill到page的操作,需要的page总数也会减少。
tx.root.spill(),这个方法是把root Bucket下所有子Bucket的所有node的内容都写入这个事务分配的dirty page里。注意这些dirty page是这个事务临时分配在内存里的,结构和DB文件的page完全一样,但还不是mmap映射的DB的page。
刚开始看到spill这个方法时,感觉它代价有些高,数学模型源码感觉像是把整个B-tree都走了一遍。后来仔细看才发现不是这么回事。这个spill只对有node结构的节点进行处理,那些没修改过的page没有对应的node,根本不会处理。
注意在经过多次Put操作后,node里存放的数据可能出现一个page写不下的情况,比如insert了几千个key value。spill会先把这样的node split成多个大小合适的node(node的split方法),然后把这些node分别写入不同的page中。这个操作对应于B-tree的split操作。和rebalance方法类似的道理,因为这些node都是Go的内存结构,split起来非常容易。
if tx.meta.pgid > opgid,这个判断是看当前事务需要的page数是否大于事务执行前DB文件有的page数,如果大于,说明DB文件放不下了,就调用db.grow增大文件,以容纳新增的page。
紧接着是linux下cp源码freelist的持久化操作,因为写事务可能使用了freelist里的一些page,同时也可能释放了一些page到freelist里,所以freelist很可能发生了变化,需要持久化。
tx.write(),这个方法就是把所有的临时分配的dirty page都写入DB文件对应的page里。
tx.writeMeta(),这个方法是把这个tx里的meta写到meta0或者meta1里面(写事务会交替写这两个meta page,这也是个常用技术,叫ping-pong buffer)。它的代码值得看一下:
首先把meta写到临时分配的buf里,然后用文件IO写到DB文件里,最后调用fdatasync,把OS文件的buffer cache持久化到磁盘上。至此,写事务的所有数据都已经落盘完毕。后面新开启的事务会因为这个meta的txid是最大的,而选择使用这个最新的meta page。而这个meta page包括最新的root bucket,最新的freelist,最新的自由农场源码pgid,这些总体构成了一个DB的最新版本,保证新开启的事务读到最新版本的数据。
看tx.write()和tx.writeMeta()的实现可以发现,写入数据用的是db.ops.writeAt,而这个方法默认值就是File.WriteAt方法,所以实际写入文件用的是文件IO,而不是直接写mmap内存。而BoltDB使用mmap一开始就把mmap映射的内存标记为只读的,压根不允许直接写mmap内存。为什么要这么做呢?
猜测可能是为了安全。前面讲到Get操作为了性能是zero copy的,发现Get返回来的value是mmap上数据的指针,如果mmap设置为可读写的,应用程序代码五花八门,可能会通过指针一不小心修改了mmap上的数据,这样的修改因为走的不是API是无法保证事务的。把mmap设置为只读的消除了这种可能性。反过来说,如果mmap设置为可读写的,Get就不能返回mmap上的指针了,为了安全一定要copy一份数据出来才行,降低了Get的性能。
这里还有个很自然而且很重要的问题是,如果事务commit失败了呢,BoltDB如何保证事务的原子性(ACID的A),确保这个写事务的所有操作,不论是落盘的,还是没落盘的,都不会生效?
原子性要求,不管是commit走到哪一步,哪怕是已经把修改的数据,甚至包括修改的freelist已经落盘,只要最终事务commit失败,都不能对正确性产生任何影响。这里的正确性是指,数据库的状态(有实际的key value数据,freelist, pgid等共同构成)必须是在这个写事务运行之前的状态,数据不能被破坏,这个写事务也不能留下可被后续事务读到的任何更新。
要做到原子性貌似挺难的,因为事务的commit里包括很多步骤,这些步骤都不是原子性的。不过重要的一点是,不论commit运行到哪一步,因为tx.writeMeta是最后一步,只有这一步运行成功commit才算成功,如果说commit失败了,那么tx.writeMeta一定是没运行,或者运行了半截,这个meta page没写完整,机器断电了。总之,这些情况下我们不会得到一个合法的新的meta page(这种情况下meta的validate方法会失败,因为meta的checksum不对)。这时候ping-pong buffer的meta page就起重要的作用了,因为交替写meta page的原因,即使这个写事务新的meta page没写成功,这个写事务运行前版本的meta page还在,而这个meta page包括这个写事务运行前的DB版本所有的状态(kv数据,freelist,pgid等)。这个meta page会被后续事务使用,就像那个失败的写事务从来没有运行过一样。而那个写事务留下的kv数据的page,freelist的page,即使是持久化了,也因为没有写成新的meta,没有机会被用到。
还有个自然的疑问,即使这个失败的写事务写的page因为没有合法的meta无法被引用,不会影响正确性,但无法被引用是不是也意味着这些page无法被回收,浪费了磁盘空间?
答案是也不会。在原来版本的meta里的free list和pgid的共同作用下,这些page会被视为free的,还可以使用,不会出现无法回收这些page的情况。
还有个疑问,既然BoltDB交替写meta0和meta1,是不是连续两个事务commit正好在写meta时失败,数据库就废了?
仔细研究发现,还是没事!因为写事务的txid也是meta的一部分,一个写事务失败,导致txid不会增长,下一次写事务的txid还是一样,meta的交替写是因为txid的变化引起的,既然没变化,就不交替了。所以下一个写事务即使写meta还失败了,也还是写的上一个写事务写的那个meta,不会把两个meta都写坏。
总结一下,ping-pong buffer的meta page真是设计得精巧,是BoltDB达到原子性的关键!
用C++编写的小游戏源代码
五子棋的代码:#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
using namespace std;
const int N=; //*的棋盘
const char ChessBoardflag = ' '; //棋盘标志
const char flag1='o'; //玩家1或电脑的棋子标志
const char flag2='X'; //玩家2的棋子标志
typedef struct Coordinate //坐标类
{
int x; //代表行
int y; //代表列
}Coordinate;
class GoBang //五子棋类
{
public:
GoBang() //初始化
{
InitChessBoard();
}
void Play() //下棋
{
Coordinate Pos1; // 玩家1或电脑
Coordinate Pos2; //玩家2
int n = 0;
while (1)
{
int mode = ChoiceMode();
while (1)
{
if (mode == 1) //电脑vs玩家
{
ComputerChess(Pos1,flag1); // 电脑下棋
if (GetVictory(Pos1, 0, flag1) == 1) //0表示电脑,真表示获胜
break;
PlayChess(Pos2, 2, flag2); //玩家2下棋
if (GetVictory(Pos2, 2, flag2)) //2表示玩家2
break;
}
else //玩家1vs玩家2
{
PlayChess(Pos1, 1, flag1); // 玩家1下棋
if (GetVictory(Pos1, 1, flag1)) //1表示玩家1
break;
PlayChess(Pos2, 2, flag2); //玩家2下棋
if (GetVictory(Pos2, 2, flag2)) //2表示玩家2
break;
}
}
cout << "***再来一局***" << endl;
cout << "y or n :";
char c = 'y';
cin >> c;
if (c == 'n')
break;
}
}
protected:
int ChoiceMode() //选择模式
{
int i = 0;
system("cls"); //系统调用,清屏
InitChessBoard(); //重新初始化棋盘
cout << "***0、退出 1、电脑vs玩家 2、玩家vs玩家***" << endl;
while (1)
{
cout << "请选择:";
cin >> i;
if (i == 0) //选择0退出
exit(1);
if (i == 1 || i == 2)
return i;
cout << "输入不合法" << endl;
}
}
void InitChessBoard() //初始化棋盘
{
for (int i = 0; i < N + 1; ++i)
{
for (int j = 0; j < N + 1; ++j)
{
_ChessBoard[i][j] = ChessBoardflag;
}
}
}
void PrintChessBoard() //打印棋盘,这个函数可以自己调整
{
system("cls"); //系统调用,清空屏幕
for (int i = 0; i < N+1; ++i)
{
for (int j = 0; j < N+1; ++j)
{
if (i == 0) //打印列数字
{
if (j!=0)
printf("%d ", j);
else
printf(" ");
}
else if (j == 0) //打印行数字
printf("%2d ", i);
else
{
if (i < N+1)
{
printf("%c |",_ChessBoard[i][j]);
}
}
}
cout << endl;
cout << " ";
for (int m = 0; m < N; m++)
{
printf("--|");
}
cout << endl;
}
}
void PlayChess(Coordinate& pos, int player, int flag) //玩家下棋
{
PrintChessBoard(); //打印棋盘
while (1)
{
printf("玩家%d输入坐标:", player);
cin >> pos.x >> pos.y;
if (JudgeValue(pos) == 1) //坐标合法
break;
cout << "坐标不合法,重新输入" << endl;
}
_ChessBoard[pos.x][pos.y] = flag;
}
void ComputerChess(Coordinate& pos, char flag) //电脑下棋
{
PrintChessBoard(); //打印棋盘
int x = 0;
int y = 0;
while (1)
{
x = (rand() % N) + 1; //产生1~N的随机数
srand((unsigned int) time(NULL));
y = (rand() % N) + 1; //产生1~N的随机数
srand((unsigned int) time(NULL));
if (_ChessBoard[x][y] == ChessBoardflag) //如果这个位置是空的,也就是没有棋子
break;
}
pos.x = x;
pos.y = y;
_ChessBoard[pos.x][pos.y] = flag;
}
int JudgeValue(const Coordinate& pos) //判断输入坐标是不是合法
{
if (pos.x > 0 && pos.x <= N&&pos.y > 0 && pos.y <= N)
{
if (_ChessBoard[pos.x][pos.y] == ChessBoardflag)
{
return 1; //合法
}
}
return 0; //非法
}
int JudgeVictory(Coordinate pos, char flag) //判断有没有人胜负(底层判断)
{
int begin = 0;
int end = 0;
int begin1 = 0;
int end1 = 0;
//判断行是否满足条件
(pos.y - 4) > 0 ? begin = (pos.y - 4) : begin = 1;
(pos.y + 4) >N ? end = N : end = (pos.y + 4);
for (int i = pos.x, j = begin; j + 4 <= end; j++)
{
if (_ChessBoard[i][j] == flag&&_ChessBoard[i][j + 1] == flag&&
_ChessBoard[i][j + 2] == flag&&_ChessBoard[i][j + 3] == flag&&
_ChessBoard[i][j + 4] == flag)
return 1;
}
//判断列是否满足条件
(pos.x - 4) > 0 ? begin = (pos.x - 4) : begin = 1;
(pos.x + 4) > N ? end = N : end = (pos.x + 4);
for (int j = pos.y, i = begin; i + 4 <= end; i++)
{
if (_ChessBoard[i][j] == flag&&_ChessBoard[i + 1][j] == flag&&
_ChessBoard[i + 2][j] == flag&&_ChessBoard[i + 3][j] == flag&&
_ChessBoard[i + 4][j] == flag)
return 1;
}
int len = 0;
//判断主对角线是否满足条件
pos.x > pos.y ? len = pos.y - 1 : len = pos.x - 1;
if (len > 4)
len = 4;
begin = pos.x - len; //横坐标的起始位置
begin1 = pos.y - len; //纵坐标的起始位置
pos.x > pos.y ? len = (N - pos.x) : len = (N - pos.y);
if (len>4)
len = 4;
end = pos.x + len; //横坐标的结束位置
end1 = pos.y + len; //纵坐标的结束位置
for (int i = begin, j = begin1; (i + 4 <= end) && (j + 4 <= end1); ++i, ++j)
{
if (_ChessBoard[i][j] == flag&&_ChessBoard[i + 1][j + 1] == flag&&
_ChessBoard[i + 2][j + 2] == flag&&_ChessBoard[i + 3][j + 3] == flag&&
_ChessBoard[i + 4][j + 4] == flag)
return 1;
}
//判断副对角线是否满足条件
(pos.x - 1) >(N - pos.y) ? len = (N - pos.y) : len = pos.x - 1;
if (len > 4)
len = 4;
begin = pos.x - len; //横坐标的起始位置
begin1 = pos.y + len; //纵坐标的起始位置
(N - pos.x) > (pos.y - 1) ? len = (pos.y - 1) : len = (N - pos.x);
if (len>4)
len = 4;
end = pos.x + len; //横坐标的结束位置
end1 = pos.y - len; //纵坐标的结束位置
for (int i = begin, j = begin1; (i + 4 <= end) && (j - 4 >= end1); ++i, --j)
{
if (_ChessBoard[i][j] == flag&&_ChessBoard[i + 1][j - 1] == flag&&
_ChessBoard[i + 2][j - 2] == flag&&_ChessBoard[i + 3][j - 3] == flag&&
_ChessBoard[i + 4][j - 4] == flag)
return 1;
}
for (int i = 1; i < N + 1; ++i) //棋盘有没有下满
{
for (int j =1; j < N + 1; ++j)
{
if (_ChessBoard[i][j] == ChessBoardflag)
return 0; //0表示棋盘没满
}
}
return -1; //和棋
}
bool GetVictory(Coordinate& pos, int player, int flag) //对JudgeVictory的一层封装,得到具体那个玩家获胜
{
int n = JudgeVictory(pos, flag); //判断有没有人获胜
if (n != 0) //有人获胜,0表示没有人获胜
{
PrintChessBoard();
if (n == 1) //有玩家赢棋
{
if (player == 0) //0表示电脑获胜,1表示玩家1,2表示玩家2
printf("***电脑获胜***\n");
else
printf("***恭喜玩家%d获胜***\n", player);
}
else
printf("***双方和棋***\n");
return true; //已经有人获胜
}
return false; //没有人获胜
}
private:
char _ChessBoard[N+1][N+1];
};
扩展资料:
设计思路
1、进行问题分析与设计,计划实现的功能为,开局选择人机或双人对战,确定之后比赛开始。
2、比赛结束后初始化棋盘,询问是否继续比赛或退出,后续可加入复盘、悔棋等功能。
3、整个过程中,涉及到了棋子和棋盘两种对象,同时要加上人机对弈时的AI对象,即涉及到三个对象。