// 生成文本棋盘(红子用()表示,黑子用[]表示) void BoardText(char *szBoard, const PositionStruct &pos, bool bAnsi) { char *lpBoard; int i, j, pc; lpBoard = szBoard; if (bAnsi) { lpBoard += sprintf(lpBoard, "\33[0m"); } for (i = 0; i < 19; i ++) { if (i % 2 == 0) { for (j = FILE_LEFT; j <= FILE_RIGHT; j ++) { pc = pos.ucpcSquares[COORD_XY(j, i / 2 + RANK_TOP)]; if ((pc & SIDE_TAG(0)) != 0) { lpBoard += sprintf(lpBoard, bAnsi ? "(\33[1;31m%.2s\33[0m)" : "(%.2s)", (const char *) &lpcwPiece2Word[0][PIECE_TYPE(pc)]); } else if ((pc & SIDE_TAG(1)) != 0) { lpBoard += sprintf(lpBoard, bAnsi ? "[\33[1;32m%.2s\33[0m]" : "[%.2s]", (const char *) &lpcwPiece2Word[1][PIECE_TYPE(pc)]); } else { lpBoard += sprintf(lpBoard, "%.4s", lpcszBoardStr[i] + (j - FILE_LEFT) * 4); } } lpBoard += sprintf(lpBoard, "\r\n"); } else { lpBoard += sprintf(lpBoard, "%s\r\n", lpcszBoardStr[i]); } } }
void ToFen(char *szFen) { int i, j, k, pc; char *lpFen; lpFen = szFen; for (i = RANK_TOP; i <= RANK_BOTTOM; i ++) { k = 0; for (j = FILE_LEFT; j <= FILE_RIGHT; j ++) { pc = Square[COORD_XY(j, i)]; if (pc != 0) { if (k > 0) { *lpFen = k + '0'; lpFen ++; k = 0; } *lpFen = PIECE_BYTE(PIECE_TYPE(pc)) ; //*lpFen = PIECE_BYTE(PIECE_TYPE(pc)) + (pc < 32 ? 0 : 'a' - 'A'); lpFen ++; } else { k ++; } } if (k > 0) { *lpFen = k + '0'; lpFen ++; } *lpFen = '/'; lpFen ++; } *(lpFen - 1) = ' '; // 把最后一个'/'替换成' ' *lpFen = 'w';//(this->sdPlayer == 0 ? 'w' : 'b'); lpFen ++; *lpFen = '\0'; }
// 绘制棋盘 static void DrawBoard(HDC hdc) { int x, y, xx, yy, sq, pc; HDC hdcTmp; // 画棋盘 hdcTmp = CreateCompatibleDC(hdc); SelectObject(hdcTmp, Xqwl.bmpBoard); BitBlt(hdc, 0, 0, BOARD_WIDTH, BOARD_HEIGHT, hdcTmp, 0, 0, SRCCOPY); // 画棋子 for (x = FILE_LEFT; x <= FILE_RIGHT; x ++) { for (y = RANK_TOP; y <= RANK_BOTTOM; y ++) { if (Xqwl.bFlipped) { xx = BOARD_EDGE + (FILE_FLIP(x) - FILE_LEFT) * SQUARE_SIZE; yy = BOARD_EDGE + (RANK_FLIP(y) - RANK_TOP) * SQUARE_SIZE; } else { xx = BOARD_EDGE + (x - FILE_LEFT) * SQUARE_SIZE; yy = BOARD_EDGE + (y - RANK_TOP) * SQUARE_SIZE; } sq = COORD_XY(x, y); pc = pos.ucpcSquares[sq]; if (pc != 0) { DrawTransBmp(hdc, hdcTmp, xx, yy, Xqwl.bmpPieces[pc]); } if (sq == Xqwl.sqSelected || sq == SRC(Xqwl.mvLast) || sq == DST(Xqwl.mvLast)) { DrawTransBmp(hdc, hdcTmp, xx, yy, Xqwl.bmpSelected); } } } DeleteDC(hdcTmp); }
void FromFen(const char *szFen) { int i, j, k; int pcWhite[7]; int pcBlack[7]; const char *lpFen; // FEN串的识别包括以下几个步骤: // 1. 初始化,清空棋盘 pcWhite[0] = SIDE_TAG(0) + KING_FROM; pcWhite[1] = SIDE_TAG(0) + ADVISOR_FROM; pcWhite[2] = SIDE_TAG(0) + BISHOP_FROM; pcWhite[3] = SIDE_TAG(0) + KNIGHT_FROM; pcWhite[4] = SIDE_TAG(0) + ROOK_FROM; pcWhite[5] = SIDE_TAG(0) + CANNON_FROM; pcWhite[6] = SIDE_TAG(0) + PAWN_FROM; for (i = 0; i < 7; i ++) { pcBlack[i] = pcWhite[i] + 16; } /* 数组"pcWhite[7]"和"pcBlack[7]"分别代表红方和黑方每个兵种即将占有的序号, * 以"pcWhite[7]"为例,由于棋子16到31依次代表“帅仕仕相相马马车车炮炮兵兵兵兵兵”, * 所以最初应该是"pcWhite[7] = {16, 17, 19, 21, 23, 25, 27}",每添加一个棋子,该项就增加1, * 这种做法允许添加多余的棋子(例如添加第二个帅,就变成仕了),但添加前要做边界检测 */ // ClearBoard(); lpFen = szFen; if (*lpFen == '\0') { // SetIrrev(); return; } // 2. 读取棋盘上的棋子 i = RANK_TOP; j = FILE_LEFT; while (*lpFen != ' ') { if (*lpFen == '/') { j = FILE_LEFT; i ++; if (i > RANK_BOTTOM) { break; } } else if (*lpFen >= '1' && *lpFen <= '9') { for (k = 0; k < (*lpFen - '0'); k ++) { if (j >= FILE_RIGHT) { break; } j ++; } } else if (*lpFen >= 'A' && *lpFen <= 'Z') { if (j <= FILE_RIGHT) { k = FenPiece(*lpFen); if (k < 7) { if (pcWhite[k] < 32) { //if (this->ucsqPieces[pcWhite[k]] == 0) { AddPiece(COORD_XY(j, i), pcWhite[k]); pcWhite[k] ++; //} } } j ++; } } else if (*lpFen >= 'a' && *lpFen <= 'z') { if (j <= FILE_RIGHT) { //k = FenPiece(*lpFen + 'A' - 'a'); k = FenPiece(*lpFen); if (6<k < 14) { if (pcBlack[k-7] < 48) { //if (this->ucsqPieces[pcBlack[k]] == 0) { AddPiece(COORD_XY(j, i), pcBlack[k-7]); pcBlack[k-7] ++; //} } } j ++; } } lpFen ++; if (*lpFen == '\0') { //SetIrrev(); return; } } lpFen ++; // 3. 确定轮到哪方走 // if (this->sdPlayer == (*lpFen == 'b' ? 0 : 1)) { // ChangeSide(); // } // // 4. 把局面设成“不可逆” // SetIrrev(); }
// 窗体事件捕捉过程 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int x, y; HDC hdc; RECT rect; PAINTSTRUCT ps; MSGBOXPARAMS mbp; switch (uMsg) { // 新建窗口 case WM_CREATE: // 调整窗口位置和尺寸 GetWindowRect(hWnd, &rect); x = rect.left; y = rect.top; rect.right = rect.left + BOARD_WIDTH; rect.bottom = rect.top + BOARD_HEIGHT; AdjustWindowRect(&rect, WINDOW_STYLES, TRUE); MoveWindow(hWnd, x, y, rect.right - rect.left, rect.bottom - rect.top, TRUE); break; // 退出 case WM_DESTROY: PostQuitMessage(0); break; // 菜单命令 case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_FILE_RED: case IDM_FILE_BLACK: Xqwl.bFlipped = (LOWORD(wParam) == IDM_FILE_BLACK); Startup(); hdc = GetDC(Xqwl.hWnd); DrawBoard(hdc); ReleaseDC(Xqwl.hWnd, hdc); break; case IDM_FILE_EXIT: DestroyWindow(Xqwl.hWnd); break; case IDM_HELP_HOME: ShellExecute(NULL, NULL, "http://www.xqbase.com/", NULL, NULL, SW_SHOWNORMAL); break; case IDM_HELP_ABOUT: // 弹出带象棋小巫师图标的对话框 MessageBeep(MB_ICONINFORMATION); mbp.cbSize = sizeof(MSGBOXPARAMS); mbp.hwndOwner = hWnd; mbp.hInstance = Xqwl.hInst; mbp.lpszText = cszAbout; mbp.lpszCaption = "关于象棋小巫师"; mbp.dwStyle = MB_USERICON; mbp.lpszIcon = MAKEINTRESOURCE(IDI_APPICON); mbp.dwContextHelpId = 0; mbp.lpfnMsgBoxCallback = NULL; mbp.dwLanguageId = 0; MessageBoxIndirect(&mbp); break; } break; // 绘图 case WM_PAINT: hdc = BeginPaint(Xqwl.hWnd, &ps); DrawBoard(hdc); EndPaint(Xqwl.hWnd, &ps); break; // 鼠标点击 case WM_LBUTTONDOWN: x = FILE_LEFT + (LOWORD(lParam) - BOARD_EDGE) / SQUARE_SIZE; y = RANK_TOP + (HIWORD(lParam) - BOARD_EDGE) / SQUARE_SIZE; if (x >= FILE_LEFT && x <= FILE_RIGHT && y >= RANK_TOP && y <= RANK_BOTTOM) { ClickSquare(COORD_XY(x, y)); } break; // 其他事件 default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return FALSE; }