- //本程序的目的是用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) ;
- }
- //该片段来自于http://www.codesnippet.cn/detail/280820135393.html
来源: http://www.codesnippet.cn/detail/280820135393.html