现在已经把所有的棋子放到上面了,运行即可看到象棋的开局画面,而且已经实现走子了。新手注意:注意不能直接复制代码,那样有行号,鼠标移动到代码上方就有复制按钮了。
//本程序的目的是用c语言+API制作象棋界面
//持续更新中
//平台为vc++2010,如果是vc6删除第一个头文件即可。
//新手学习windows程序设计,请各位多多指教!
//本人知道有easyx库,但是故意不用的。
//qq 675686066
//email leiyang-ge@163.com
#include "stdafx.h"
#include
#include
#include
#include
#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)
{
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) ;
}