📄 mantischessstd.cpp
字号:
/***************************************************************
MantisChessStd.cpp : MantisChess 标准函数
版权所有(C) 共创软件联盟 CChessUG 项目开发小组成员 陈成涛
这一程序是自由软件,你可以遵照自由软件基金会出版的GNU通用公共
许可证条款来修改和重新发布这一程序。或者用许可证的第二版,或者
(根据你的选择)用任何更新的版本。
发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特
定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证。
你应该已经和程序一起收到一份GNU通用公共许可证的副本。
如果还没有,写信给:
The Free Software Foundation,Inc,,675 Mass Ave, Cambridge,
MAO2139,USA
如果你在使用本软件时有什么问题或建议,用以下地址可以与我取得联
系:
http://thecct.51.net
http://cosoft.org.com
或发Email到:
stove@eyou.com
******************************************************************/
#include "StdAfx.h"
#include "MantisChessDef.h"
#include "MantisChessStd.h"
/******************************************************************
CanGo: 判断一步棋合不合法
参数:
manmap: 棋位状态
man: 所移动的棋子
from: 所移动的棋子原始位置
to: 所要移动到的位置
返回值: 合法返回TRUE,不合法返回FALSE
******************************************************************/
BOOL CanGo(int manmap[11][12],int man,const POINT &from,const POINT &to)
{
static int i,j;
if(!IsNormal(ManToType[man],to)) //这个棋子不能放在目标位置
{
//如果不是将/帅 (将/帅可以"照相")
if(ManToType[man]!=RED_K&& ManToType[man]!=BLACK_K)return FALSE;
else if(ManToType[man]==RED_K && //走的是帅
ManToType[manmap[to.x][to.y]]==BLACK_K) //目标是将
{
BOOL flag=FALSE;
for(j= from.y-1;j>0;j--)
{
if (manmap[from.x][j]!=32)
{
if(ManToType[manmap[from.x][j]]==BLACK_K) //照相
flag=TRUE;
break;
}
}
if(flag)return TRUE;
else return FALSE;
}
else if(ManToType[manmap[to.x][to.y]]==RED_K) //走的是将,目标是帅
{
BOOL flag=FALSE;
for(j= from.y+1;j<11;j++)
{
if (manmap[from.x][j]!=32)
{
if(ManToType[manmap[from.x][j]]==RED_K) //照相
flag=TRUE;
break;
}
}
if(flag)return TRUE;
else return FALSE;
}
else return FALSE;
}
//下面几行判断目标点是否己方的棋子:
if(SideOfMan[man]==0)
{
if(manmap[to.x][to.y]!=32&& SideOfMan[manmap[to.x][to.y]]==0)return FALSE;
}
else if(SideOfMan[man]==1)
{
if(manmap[to.x][to.y]!=32&& SideOfMan[manmap[to.x][to.y]]==1)return FALSE;
}
//--------------------------------
//以下是各棋子的规则:
switch(ManToType[man])
{
case RED_B:
//兵不回头:
if(to.y > from.y)return FALSE;
//兵只走一步直线:
if(from.y-to.y+abs(to.x-from.x)>1)return FALSE;
break;
case BLACK_B:
//卒不回头:
if(to.y < from.y)return FALSE;
//卒只走一步直线:
if(to.y-from.y+abs(to.x-from.x)>1)return FALSE;
break;
case RED_S:
case BLACK_S:
//士走斜线一步:
if(abs(from.y-to.y)>1||abs(to.x-from.x)>1)return FALSE;
break;
case RED_X:
case BLACK_X:
//相走田:
if(abs(from.x-to.x)!=2||abs(from.y-to.y)!=2)return FALSE;
//相心:
if(manmap[(from.x+to.x)/2][(from.y+to.y)/2]!=32)return FALSE;
break;
case RED_K:
case BLACK_K:
//将帅只走一步直线:
if(abs(from.y-to.y)+abs(to.x-from.x)>1)return FALSE;
break;
case RED_J:
case BLACK_J:
//车只能走直线:
if(from.y!=to.y&&from.x!=to.x)return FALSE;
//车经过的路线中不能有棋子: -----------
if(from.y==to.y)
{
if(from.x<to.x)
{
for(i=from.x+1;i<to.x;i++)
if(manmap[i][from.y]!=32)return FALSE;
}
else
{
for(i=to.x+1;i<from.x;i++)
if(manmap[i][from.y]!=32)return FALSE;
}
}
else
{
if(from.y<to.y)
{
for(j=from.y+1;j<to.y;j++)
if(manmap[from.x][j]!=32)return FALSE;
}
else
{
for(j=to.y+1;j<from.y;j++)
if(manmap[from.x][j]!=32)return FALSE;
}
}
//以上是车---------------------------------
break;
case RED_P:
case BLACK_P:
//炮只能走直线:
if(from.y!=to.y&&from.x!=to.x)return FALSE;
//炮不吃子时经过的路线中不能有棋子:------------------
if(manmap[to.x][to.y]==32)
{
if(from.y==to.y)
{
if(from.x<to.x)
{
for(i=from.x+1;i<to.x;i++)
if(manmap[i][from.y]!=32)return FALSE;
}
else
{
for(i=to.x+1;i<from.x;i++)
if(manmap[i][from.y]!=32)return FALSE;
}
}
else
{
if(from.y<to.y)
{
for(j=from.y+1;j<to.y;j++)
if(manmap[from.x][j]!=32)return FALSE;
}
else
{
for(j=to.y+1;j<from.y;j++)
if(manmap[from.x][j]!=32)return FALSE;
}
}
}
//以上是炮不吃子-------------------------------------
//吃子时:=======================================
else
{
int count=0;
if(from.y==to.y)
{
if(from.x<to.x)
{
for(i=from.x+1;i<to.x;i++)
if(manmap[i][from.y]!=32)count++;
if(count!=1)return FALSE;
}
else
{
for(i=to.x+1;i<from.x;i++)
if(manmap[i][from.y]!=32)count++;
if(count!=1)return FALSE;
}
}
else
{
if(from.y<to.y)
{
for(j=from.y+1;j<to.y;j++)
if(manmap[from.x][j]!=32)count++;
if(count!=1)return FALSE;
}
else
{
for(j=to.y+1;j<from.y;j++)
if(manmap[from.x][j]!=32)count++;
if(count!=1)return FALSE;
}
}
}
//以上是炮吃子时================================
break;
case RED_M:
case BLACK_M:
//马走日:
if(!(
(abs(to.x-from.x)==1&&abs(to.y-from.y)==2)
||(abs(to.x-from.x)==2&&abs(to.y-from.y)==1)
))return FALSE;
//找马脚:
if (to.x-from.x==2){i=from.x+1;j=from.y;}
else if (from.x-to.x==2){i=from.x-1;j=from.y;}
else if (to.y-from.y==2){i=from.x;j=from.y+1;}
else if (from.y-to.y==2){i=from.x;j=from.y-1;}
//绊马脚:
if(manmap[i][j]!=32)return FALSE;
break;
default:
break;
}
return TRUE; //上面的规则全通过!
}
/******************************************************************
IsNormal: mantype类型的棋子放在point位置是否合法
参数:
mantype: 棋子类型
point: 位置
返回值: 合法返回TRUE,不合法返回FALSE
******************************************************************/
BOOL IsNormal(const int & mantype,const POINT &point)
{
if(point.x<1||point.x>9||point.y<1||point.y>10)return FALSE;
switch(mantype)
{
case RED_K:
//帅不能在红方宫外:
if( point.x>6|| point.x<4|| point.y<8)return FALSE;
break;
case RED_S:
//仕只能在宫内特定点:
if(!(
( point.x==4&& point.y==10)||
( point.x==4&& point.y==8)||
( point.x==5&& point.y==9)||
( point.x==6&& point.y==10)||
( point.x==6&& point.y==8)
))return FALSE;
break;
case RED_X:
//七个相位:
if(!(
( point.x==1&& point.y==8)||
( point.x==3&& point.y==10)||
( point.x==3&& point.y==6)||
( point.x==5&& point.y==8)||
( point.x==7&& point.y==10)||
( point.x==7&& point.y==6)||
( point.x==9&& point.y==8)
))return FALSE;
break;
case RED_B:
//兵不能在兵位后:
if( point.y>7)return FALSE;
//兵过河前不能左右移动:
if( point.y>5&& point.x%2==0)return FALSE;
break;
case BLACK_K:
//帅不能在红方宫外:
if( point.x>6|| point.x<4|| point.y>3)return FALSE;
break;
case BLACK_S:
//仕只能在宫内特定点:
if(!(
( point.x==4&& point.y==1)||
( point.x==4&& point.y==3)||
( point.x==5&& point.y==2)||
( point.x==6&& point.y==1)||
( point.x==6&& point.y==3)
))return FALSE;
break;
case BLACK_X:
//七个相位:
if(!(
( point.x==1&& point.y==3)||
( point.x==3&& point.y==1)||
( point.x==3&& point.y==5)||
( point.x==5&& point.y==3)||
( point.x==7&& point.y==1)||
( point.x==7&& point.y==5)||
( point.x==9&& point.y==3)
))return FALSE;
break;
case BLACK_B:
//兵不能在兵位后:
if( point.y<4)return FALSE;
//兵过河前不能左右移动:
if( point.y<6&& point.x%2==0)return FALSE;
break;
default:
break;
}
return TRUE;
}
/******************************************************************
FixManMap: 根据棋子坐标计算棋位状态
参数:
map: 棋位状态(存放结果)
manpoint: 棋子坐标
side: 轮到哪一方走
返回值: 无
******************************************************************/
void FixManMap(int map[11][12],POINT manpoint[32],int side)
{
memcpy(map,_defaultmap,132*sizeof(int));
static POINT * pman;
static int i;
for(i=0;i<32;i++)
{
pman = & manpoint[i];
if(pman->x)
map[pman->x][pman->y]=i;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -