返回顶部

收藏

用c语言+API制作象棋界面

更多

现在已经把所有的棋子放到上面了,运行即可看到象棋的开局画面,而且已经实现走子了。新手注意:注意不能直接复制代码,那样有行号,鼠标移动到代码上方就有复制按钮了。

[C/C++]代码

//本程序的目的是用c语言+API制作象棋界面
//持续更新中
//平台为vc++2010,如果是vc6删除第一个头文件即可。
//新手学习windows程序设计,请各位多多指教!
//本人知道有easyx库,但是故意不用的。
//qq 675686066
//email leiyang-ge@163.com
#include "stdafx.h"
#include <windows.h>
#include <math.h>
#include <windef.h>
#include <string.h>
#define GridSize 50//格子边长
#define ScreenOffX 50//左边空白
#define ScreenOffY 50//上边空白

HDC hdc;
int turn=1;//轮到谁落子
POINT m={-1,-1};//标记的位置
//存储的时候是以0开始
//但在安放、移动棋子的函数中,为了直观,从1开始
//因此需要少量转换

//棋子文字
int p[10][9]={
    4, 3, 2, 1, 0, 1, 2, 3, 4,
    7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 5, 7, 7, 7, 7, 7, 5, 7,
    6, 7, 6, 7, 6, 7, 6, 7, 6,
    7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7,
    6, 7, 6, 7, 6, 7, 6, 7, 6,
    7, 5, 7, 7, 7, 7, 7, 5, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7,
    4, 3, 2, 1, 0, 1, 2, 3, 4};
    //棋子颜色
    int c[10][9]={
        -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1,
        1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1};

        char P[8][4] = {"将", "士" ,"相", "马", "车", "炮", "兵", " "}; //存放棋子名称的数组

        LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

        int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

            PSTR szCmdLine, int iCmdShow)
        {

            static TCHAR szAppName[] = TEXT ("中国象棋") ;
            HWND hwnd ;
            MSG msg ;
            WNDCLASS wndclass ;

            wndclass.style = CS_HREDRAW | CS_VREDRAW ;
            wndclass.lpfnWndProc= WndProc ;
            wndclass.cbClsExtra = 0 ;
            wndclass.cbWndExtra = 0 ;
            wndclass.hInstance = hInstance ;
            wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
            wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
            wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
            wndclass.lpszMenuName = NULL ;
            wndclass.lpszClassName = szAppName ;

            if (!RegisterClass (&wndclass))
            {
                MessageBox ( NULL, TEXT ("Program requires Windows NT!"),
                    szAppName, MB_ICONERROR) ;
                return 0 ;
            }

            hwnd = CreateWindow ( szAppName, TEXT ("象棋-已经实现走子,不过界面不是很好"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT, CW_USEDEFAULT,
                CW_USEDEFAULT, CW_USEDEFAULT,
                NULL, NULL, hInstance, NULL) ;
            ShowWindow (hwnd, iCmdShow) ;
            UpdateWindow (hwnd) ;

            while (GetMessage (&msg, NULL, 0, 0))
            {
                TranslateMessage (&msg) ;
                DispatchMessage (&msg) ;
            }
            return msg.wParam ;
        }

        void DrawLine(HDC hdc,double x1,double y1,double x2,double y2)//画线
        {
            MoveToEx (hdc, x1, y1, NULL) ;
            LineTo (hdc,x2, y2) ;
        }

        void RemovePiece(HDC hdc,int x,int y)//移除棋子
        {
            double xx=ScreenOffX+GridSize*(x-1);
            double yy=ScreenOffY+GridSize*(y-1);
            double half=GridSize*0.5;
            RECT rect;
            HBRUSH hBrushRed =CreateSolidBrush (RGB (255, 255, 255)) ;
            rect.left =xx-half;
            rect.right =xx+half;
            rect.top =yy-half;
            rect.bottom =yy+half;
            FillRect(hdc,&rect,hBrushRed);
            DrawLine(hdc,xx-half,yy,xx+half,yy);
            DrawLine(hdc,xx,yy-half,xx,yy+half);
        }

        void AddPiece(HDC hdc,int x,int y,int color,char * piece)//某位上填棋子
        {
            int xoff=-15;
            int yoff=-15;

            if(x>=1 && x<=9 && y>=1 && y<=10)
            {
                if (color==1)
                {
                    HFONT hFont = CreateFont(GridSize*2/3,GridSize*1/3,0,0,0,0,0,0,0,0,0,0,0,0);
                    SelectObject(hdc,hFont);

                    SetTextColor(hdc,RGB(255,0,0));
                    TextOutA (hdc, ScreenOffX+GridSize*(x-1)+xoff,ScreenOffY+GridSize*(y-1)+yoff, piece, strlen(piece)) ;
                }
                else if (color==-1)
                {
                    HFONT hFont = CreateFont(GridSize*2/3,GridSize*1/3,0,0,0,0,0,0,0,0,0,0,0,0);
                    SelectObject(hdc,hFont);

                    SetTextColor(hdc,RGB(0,0,0));
                    TextOutA (hdc, ScreenOffX+GridSize*(x-1)+xoff,ScreenOffY+GridSize*(y-1)+yoff, piece, strlen(piece)) ;

                }
            }
        }

        void DrawBoard(HDC hdc)//画棋盘
        {
            int i;
            for( i=0;i<=9;i++)
                DrawLine(hdc,ScreenOffX,ScreenOffY+GridSize*i,ScreenOffX+GridSize*8,ScreenOffY+GridSize*i);
            for( i=0;i<=8;i++)
            {
                DrawLine(hdc,ScreenOffX+GridSize*i,ScreenOffY,ScreenOffX+GridSize*i,ScreenOffY+GridSize*4);
                DrawLine(hdc,ScreenOffX+GridSize*i,ScreenOffY+GridSize*5,ScreenOffX+GridSize*i,ScreenOffY+GridSize*9);
            }
            DrawLine(hdc,ScreenOffX+GridSize*3,ScreenOffY,ScreenOffX+GridSize*5,ScreenOffY+GridSize*2);
            DrawLine(hdc,ScreenOffX+GridSize*3,ScreenOffY+GridSize*7,ScreenOffX+GridSize*5,ScreenOffY+GridSize*9);
            DrawLine(hdc,ScreenOffX+GridSize*3,ScreenOffY+GridSize*2,ScreenOffX+GridSize*5,ScreenOffY);
            DrawLine(hdc,ScreenOffX+GridSize*3,ScreenOffY+GridSize*9,ScreenOffX+GridSize*5,ScreenOffY+GridSize*7);

        }

        POINT MouseP(int xx,int yy)//鼠标所在位置
        {
            int i,j;
            double precise=GridSize/3;
            POINT pp;
            pp.x =-1;
            pp.y =-1;
            for(i=0;i<10;i++)
                for( j=0;j<9;j++)
                    if(abs(ScreenOffX+GridSize*j-xx)<precise && abs(ScreenOffY+GridSize*i-yy)<precise )//&& p[i][j] !=7 && c[i][j]==turn
                    {
                        pp.x =j;
                        pp.y =i;
                        break;
                    }
                    return pp;
        }

        void UnDrawMark(HDC hdc,int x,int y)//取消标记
        {
            if(x>=1 && x<=9 && y>=1 && y<=10)
            {
                double half=GridSize/2-5;
                double xx=ScreenOffX+GridSize*(x-1);
                double yy=ScreenOffY+GridSize*(y-1);
                POINT  rec[8]={xx-half,yy-half,xx-half,yy+half,xx+half,yy+half,xx+half,yy-half,xx-half,yy-half};
                HPEN p= CreatePen(0,1, RGB (255, 255, 255) );
                SelectObject (hdc, p) ;
                Polyline(hdc,rec,5);
            }
        }

        void DrawMark(HDC hdc,int x,int y)//标记
        {
            if(x>=1 && x<=9 && y>=1 && y<=10)
            {
                double half=GridSize/2-5;
                double xx=ScreenOffX+GridSize*(x-1);
                double yy=ScreenOffY+GridSize*(y-1);
                POINT  rec[8]={xx-half,yy-half,xx-half,yy+half,xx+half,yy+half,xx+half,yy-half,xx-half,yy-half};
                HPEN p= CreatePen(0,1, RGB (0, 0, 255) );
                SelectObject (hdc, p) ;
                Polyline(hdc,rec,5);
                m.x=x-1;
                m.y=y-1;
            }
        }

        //移动棋子-f=from,t=to
        void Move(HDC hdc,int fx,int fy,int tx,int ty)
        {
            int x1=fy-1;
            int y1=fx-1;
            int x2=ty-1;
            int y2=tx-1;
            //

            p[x2][y2]=p[x1][y1];
            c[x2][y2]=c[x1][y1];

            AddPiece( hdc, tx, ty,c[x1][y1],P[p[x1][y1]]);
            RemovePiece( hdc,fx,fy);
            c[x1][y1]=0;
            p[x1][y1]=7;

            turn=turn * -1;
        }

        void RefreshPiece(HDC hdc)//重画所有棋子
        {
            int i,j;
            for( i=0;i<10;i++)
                for( j=0;j<9;j++)
                    if(p[i][j]!=7)
                        AddPiece( hdc,j+1, i+1,c[i][j],P[p[i][j]] );

        }
        LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
        {
            PAINTSTRUCT ps ;
            switch (message)
            {
            case WM_SIZE:

                return 0 ;

            case WM_PAINT:
                {
                    hdc = BeginPaint (hwnd, &ps) ;

                    DrawBoard(hdc);

                    RefreshPiece( hdc);
                    DrawMark(hdc,m.x+1,m.y+1);
                    EndPaint (hwnd, &ps) ;
                }
                return 0 ;

            case   WM_LBUTTONDOWN :
                {
                    HDC hdc=GetDC(hwnd);
                    POINT lastm=m;
                    POINT pp =MouseP(LOWORD (lParam), HIWORD (lParam));
                    if(pp.x !=-1 && pp.y !=-1)
                    {
                        if(p[pp.y ][pp.x ]==7)
                        {
                            if(m.x!=-1 && m.y!=-1 && c[lastm.y ][lastm.x]==turn) //
                            {
                                Move(hdc,m.x+1,m.y+1,pp.x +1,pp.y +1);

                                DrawMark(hdc,pp.x+1,pp.y+1);
                            }
                        }

                        else if(c[pp.y ][pp.x]==turn && !(p[pp.y ][pp.x]==p[lastm.y ][lastm.x] && c[pp.y ][pp.x]==c[lastm.y ][lastm.x]) )
                        {
                            DrawMark(hdc,pp.x+1,pp.y+1);
                            if(lastm.x !=-1 && lastm.y !=-1)
                                UnDrawMark(hdc,lastm.x+1,lastm.y+1);

                        }

                    }
                    ReleaseDC(hwnd,hdc);
                    return 0 ;

                }

            case WM_DESTROY:
                PostQuitMessage (0) ;
                return 0 ;
            }

            return DefWindowProc (hwnd, message, wParam, lParam) ;

        }

象棋开局和走子.JPG

imgs/asCode/19154823_Ncyx.jpg

标签:c

收藏

0人收藏

支持

0

反对

0

发表评论