中国象棋(引用自百度百科)
中国象棋是起源于中国的一种棋戏,属于二人对抗性游戏的一种,在中国有着悠久的历史。由于用具简单,趣味性强,成为流行极为广泛的棋艺活动。 中国象棋是中国棋文化也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规则简明易懂,千百年来长盛不衰。中国象棋是模拟的古代战争、直线战争、陆地战争、平面战争。在中国古代,象棋被列为士大夫们的修身之艺。现在,则被视为是怡神益智的一种有益身心的活动。象棋集文化、科学、艺术、竞技于一身,不但可以开发智力,启迪思维,锻炼辨证分析能力和培养顽强的意志,而且可以修心养性,陶冶情操,丰富文化生活,深受广大群众的喜爱。古今中外男女老少皆宜,由于用具简单,趣味性强,大街小巷常常可见纹枰对弈的中国象棋爱好者。中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈,棋盘上有十条横线、九条竖线共分成90个交叉点;中国象棋的棋子共有32个,每种颜色16个棋子,分为7个兵种,摆放和活动在交叉点上。双方交替行棋,先把对方的将(帅)“将死”的一方获胜(因为擒贼先擒王)。已有几千年历史、充满东方智慧的中国象棋在中国的群众中基础远远超过围棋,一直是普及最广的棋类项目。
前面bb的并不是本次讨论的重点,下面我们就装逼起飞。。。。。。。
首先我们还是来看下最后做出来的效果吧,一个只会堆代码的程序猿会让人很崩溃!!!!!!
或者你又想加点其他效果(这里对棋子加了辐射渐变效果)。。。。此处省略一万字。。。。。。然并卵,想要更好的效果就去找UI小姐姐或度娘吧。。。。。。
装逼完成了,,,,接下来我们来看下这个简单的页面如何用代码绘制出来。
我们做自定义控件是首先整理下逻辑,首先是继承问题我选择了 extends View 这样的话棋盘,棋子都是需要自己动手画的,更好练手。
整体思路:
1.绘制棋盘背景;
2.绘制棋局范围边框;
3.绘制棋盘网格(很简单);
4.绘制中心文字--楚河汉界
5.绘制炮-兵-卒特殊位置辅助线、将帅位置辅助线;
6.绘制棋子(背景+棋子文字);
7.最后就是走棋规则的处理,有效点击区域判断;
8.被将军的提示(这里应该是整个流程中最难的环节);
那么下面就分布实现:
信息解释:
private Paint linePaint;//画线的笔
private Paint qiPaint;//棋子文子画笔
private Paint qibackPaint;//棋子背景画笔
private int h;
private int w;
private int startX,startY;//起始绘制位置
private int defaultPadding=50;
private int hang = 9;//行
private int lie = 8; //列
private int space;
//存放所有位置信息 [X,Y,0,车] 依次对应 【x坐标、y坐标、红黑方、棋子】
private List<List<String>> allDatas=new ArrayList<>();
private List<List<String>> allDatasDefault=new ArrayList<>();
private List<List<List<String>>> back_datas=new ArrayList<>();//下棋落子记录,用于悔棋时调用
private boolean isInit=true;//是否第一次进来————初始化棋盘
private int step;//走棋步数 单数黑 双数红
//画棋盘
private int b_color=0xffF0F0F0;//棋盘背景
private final String back = "悔棋";
private final String reset = "复盘";
private final String per1 = "楚河";
private final String per2 = "汉界";
private final String[] chess1={"车","马","相","士","将"};
private final String[] chess1_d={"车","马","象","仕","帅"};
1.绘制棋盘背景;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initSetting();
//绘制整个背景
canvas.drawColor(b_color);
}
2.绘制棋局范围边框;
//绘制外边框
linePaint.setStrokeWidth((defaultPadding/2)*2/3);
canvas.drawRect(startX-defaultPadding/2,startY-defaultPadding/2,startX+space*8+defaultPadding/2,startY+space*9+defaultPadding/2,linePaint);
3.绘制棋盘网格(很简单);
//绘制网格
linePaint.setStrokeWidth(strokeWidth);
for (int i = 0; i <=hang ; i++) {
canvas.drawLine(startX,startY+space*i,startX+space*8,startY+space*i,linePaint);
}
for (int i = 0; i <=lie ; i++) {
canvas.drawLine(startX+space*i,startY,startX+space*i,startY+space*9,linePaint);
}
4.绘制中心文字--楚河汉界
//绘制楚河汉界区域
linePaint.setColor(b_color);
linePaint.setStyle(Paint.Style.FILL);
int left=startX+strokeWidth/2;
int top=startY+space*4+strokeWidth/2;
int right=startX+space*8-strokeWidth/2;
int bottom=startY+space*5-strokeWidth/2;
canvas.drawRect(left,top,right,bottom,linePaint);
//绘制文字楚河汉界
linePaint.setColor(0xffFFD39B);
linePaint.setTextSize(50);
linePaint.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.BOLD));
Rect rect = new Rect();
linePaint.getTextBounds(per2,0,per2.length(),rect);
int per_width = rect.width();
int per_height = rect.height();
canvas.drawText(per1,startX+space/2,(top+bottom)/2+per_height/2,linePaint);
canvas.drawText(per2,right-space/2-per_width,(top+bottom)/2+per_height/2,linePaint);
//绘制提示当前走棋方
linePaint.setTextSize(35);
String text;
if (currRole.equals("1")){
linePaint.setColor(0xffff0000);
text="红方走棋";
}else{
linePaint.setColor(0xff000000);
text="黑方走棋";
}
Rect rect1 = new Rect();
linePaint.getTextBounds(text,0,text.length(),rect1);
int per_width1 = rect1.width();
int per_height1 = rect1.height();
canvas.drawText(text,w/2-per_width1/2,(top+bottom)/2+per_height1/2,linePaint);
5.绘制炮-兵-卒特殊位置辅助线、将帅位置辅助线;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制辅助线---将帅斜线
linePaint.setColor(lineColor);
float [] dts = {
startX+space*3,startY,startX+space*5,startY+space*2,
startX+space*3,startY+space*2,startX+space*5,startY,
startX+space*3,startY+space*7,startX+space*5,startY+space*9,
startX+space*3,startY+space*9,startX+space*5,startY+space*7
};
canvas.drawLines(dts,linePaint);
//绘制交点折线--炮-兵-卒
for (int i = 0; i <=hang ; i++) {//获取Y值---行
int y = startY+space*i;
for (int j = 0; j <=lie; j++) {//获取X值---列
int x = startX+space*j;
if (i==2&&(j==1||j==7)){
addlines(canvas,x,y,0);
}
if (i==7&&(j==1||j==7)){
addlines(canvas,x,y,0);
}
if (i==3&&j%2==0){
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}
if (i==6&&j%2==0){
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}
}
}
}
上面用到的addlines()方法如下:
private int tPadding=10;//角落辅助线的间隔
private int tlength=20;
/**
* 绘制特殊位置辅线---角落辅助线
* @param canvas
* @param x 交点x
* @param y 交点y
* @param type 1都有 1只有左边 2只有右边
*/
private void addlines(Canvas canvas,int x,int y,int type) {
Path path=new Path();
//左上
int sx;
int sy;
int sx1;
int sy1;
int sx2;
int sy2;
if (type==0||type==1){
//左上
sx= x-tPadding;
sy = y-tPadding;
sx1=sx-tlength;
sy1=sy;
sx2=sx;
sy2=sy-tlength;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
//左下
sx=x-tPadding;
sy=y+tPadding;
sx1=sx;
sy1=sy+tlength;
sx2=sx-tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
}
if (type==0||type==2){
//右上
sx=x+tPadding;
sy=y-tPadding;
sx1=sx;
sy1=sy-tlength;
sx2=sx+tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
//右下
sx= x+tPadding;
sy = y+tPadding;
sx1=sx;
sy1=sy+tlength;
sx2=sx+tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
}
linePaint.setColor(lineColor);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(3);
canvas.drawPath(path,linePaint);
}
6.绘制棋子(背景+棋子文字);
//画棋子
private int radius=40;
private boolean isFirst=true;
@Override
public void onDrawForeground(Canvas canvas) {
super.onDrawForeground(canvas);
Rect rect=new Rect();
qiPaint.getTextBounds(chess1[0],0,1,rect);
int per_width2 = rect.width();
int per_height2 = rect.height();
qiPaint.setTextSize(40);
//获取棋盘上所有放置位置
Log.e("棋盘大小111"," ---"+allDatas.size()+" ---" +allDatas.toString());
//根据棋盘棋子位置变化更新棋盘
for (int i = 0; i < allDatas.size(); i++) {
if (allDatas.get(i).get(2).equals("1")){//表示红棋
qiPaint.setColor(0xffff0000);
//该自己走棋才改变棋子背景颜色
if (i==currPosition &&currRole.equals("1")){
qibackPaint.setColor(selectColor);
}else{
qibackPaint.setColor(redColor);
}
canvas.drawCircle(Float.valueOf(allDatas.get(i).get(0)),Float.valueOf(allDatas.get(i).get(1)),radius,qibackPaint);
int x=Integer.valueOf(allDatas.get(i).get(0));
int y=Integer.valueOf(allDatas.get(i).get(1));
int lx= x-per_width2/2-strokeWidth;
int ly= y+per_height2/2-strokeWidth;
canvas.drawText(allDatas.get(i).get(3),lx,ly,qiPaint);
}else if (allDatas.get(i).get(2).equals("2")){//表示黑棋--其他无棋位置不做处理
qiPaint.setColor(0xff000000);
//该自己走棋才改变棋子背景颜色
if (i==currPosition&&currRole.equals("2")){
qibackPaint.setColor(selectColor);
}else{
qibackPaint.setColor(blockColor);
}
canvas.drawCircle(Float.valueOf(allDatas.get(i).get(0)),Float.valueOf(allDatas.get(i).get(1)),radius,qibackPaint);
int x=Integer.valueOf(allDatas.get(i).get(0));
int y=Integer.valueOf(allDatas.get(i).get(1));
int lx= x-per_width2/2-strokeWidth;
int ly= y+per_height2/2-strokeWidth;
canvas.drawText(allDatas.get(i).get(3),lx,ly,qiPaint);
}
}
if (isFirst){
isFirst=false;
invalidate();
}
}
前面的绘制都是在onDraw(Canvas canvas)方法内绘制,这里绘制棋子我是在onDrawForeground(Canvas canvas)方法里面绘制的,不过你在onDraw(Canvas canvas)方法里里绘制也是可以的。记住,这里绘制的不仅是默认棋盘,后续棋局变化刷新后也是直行该代码来刷新棋盘的。根据allDatas内数据的变化。。。。。。。这里是重点,我们来理下里面的逻辑。
我们要理解存放模式,alldatas是存放所有棋盘位置的数据集合对象:
private List<List<String>> allDatas=new ArrayList<>();//每个位置信息包括四个元素 [X,Y,0,车] 依次对应 【x坐标、y坐标、红黑方、棋子】
//获取棋盘上所有放置位置---基础
if (isInit){//---默认棋盘位置信息只需要执行一次
isInit=false;
allDatas.clear();
for (int i = 0; i <=hang ; i++) {//获取Y值---行
int y = startY+space*i;
for (int j = 0; j <=lie; j++) {//获取X值---列
int x = startX+space*j;
List<String> data=new ArrayList<>();
data.add(x+"");
data.add(y+"");
if (i==0){
data.add("1");
data.add(chess1[j<=4?j%5:3-j%5]);//{"车","马","相","士","将"}
}else if (i==9){
data.add("2");
data.add(chess1_d[j<=4?j%5:3-j%5]);//{"车","马","象","仕","帅"}
}else if (i==2){
if (j==1||j==7){
data.add("1");
data.add("炮");
addlines(canvas,x,y,0);
}else{
data.add("");
data.add("");
}
}else if (i==7){
if (j==1||j==7){
data.add("2");
data.add("炮");
addlines(canvas,x,y,0);
}else{
data.add("");
data.add("");
}
}else if (i==3){
if (j%2==0){
data.add("1");
data.add("兵");
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}else{
data.add("");
data.add("");
}
}else if (i==6 ){
if (j%2==0){
data.add("2");
data.add("卒");
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}else{
data.add("");
data.add("");
}
}else{
data.add("");
data.add("");
}
allDatas.add(data);
}
}
List<List<String>> temp=new ArrayList<>();
for (int j = 0; j < allDatas.size(); j++) {
List<String> temp1=new ArrayList<>();
List<String> temp2=new ArrayList<>();
for (int k = 0; k < allDatas.get(j).size(); k++) {
temp1.add(allDatas.get(j).get(k));
temp2.add(allDatas.get(j).get(k));
}
temp.add(temp1);
allDatasDefault.add(temp2);
}
back_datas.add(temp);
}
看了上面代码,你一定会很好奇,怎么还有一个temp呢,这个是用来做什么的,这不是画蛇添足吗,allDatasDefault和temp装了一样的数据,但是你会发现back_datas.add(temp);这句代码, 哇!!!!真牛逼!!!正如你所想,这是为悔棋做的准备,悔棋操作装的第一次数据啦。。。。。。。。这里先略过,不是重点,下面继续看!!!!!
7.最后就是走棋规则的处理,有效点击区域判断;
这里很重要的一步就是要确定棋盘上各个交叉点位置数据,因为我们后续的逻辑都是建立在棋子放置位置来进行的。首先需要获取棋盘的初始位置信息。这里只需要进行一次获取就行了,我们在onDraw(Canvas canvas)方法内做这个操作。说明:allDatasDefault是初始棋局保存的数据,聪明的你一定想到了一开始我们展示的gif中的复盘实现的数据基础。
走棋的有效区域即为棋盘内部--准确说应该是棋子所在位置可以响应的范围。比如棋子位置中心,棋子半径区域点击了为有效区域。往下看。。。。。。。。。。。
private String currRole="1";//当前一轮走棋方 1 红方 2 黑方
private int currPosition=-1;//当前一轮走棋方选中棋子 默认-1 未选中 其他表示选中位置 移动前位置
private int currTouch=-1;//当前触摸位置 -----------------------------------------
@Override
public boolean onTouchEvent(MotionEvent event) {
//触摸位置
int cx=0;
int cy=0;
int x;
int y;
if (event.getAction()==MotionEvent.ACTION_DOWN){
cx= (int) event.getX();
cy= (int) event.getY();
//有效触摸范围
for (int i = 0; i <allDatas.size() ; i++) {
x=Integer.valueOf(allDatas.get(i).get(0));
y=Integer.valueOf(allDatas.get(i).get(1));
if (cx>x-radius&& cx<x+radius && cy>y-radius &&cy<y+radius){ //有效点击区域
Log.e("点击了有效区域","======"+i);
currTouch=i;
//要区分事件---之前是否选中
if (currPosition==-1){//没选中任何棋子
Log.e("没棋子-","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("没棋子-点了自己棋子","==");
}
}else{
Log.e("有棋子--","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("有棋子--点了自己棋子","==");
}else{
Log.e("有棋子--判断走棋","==");
//这里有两种可能,一是有别人的棋子,一是无子
//这里做走棋规则判断是否可以落子--落子后清除状态 currTouch=-1,
}
}
invalidate();
}
}
}
return true;
}
相信各位都能够看懂上面的操作都做了什么,没层代码解释得很清楚。前面做的一系列判断略过,我们在意最后一个else后面怎么操作,也就是点击/触摸事件有效。有效的点击/触摸事件可能分两种情况,一种情况是此处有棋子,另一种情况是此处没有棋子。(注:能走到这个else里面来都是已经选中了自己棋子,这里是落子的操作了,至于能不能在此处落子就要看你)----根据各个棋子的走棋规则来决定,如果满足,执行落子操作,不满足则忽略此次点击/触摸事件。
- 1 兵、卒的走棋约束:
/**
* 1 兵的走棋约束
* @return 是否有效走棋
*/
public boolean bing(){
int x;
int y;
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
if (currRole.equals("1")){//红方
if (y<startY+space*5){//在自己这边
if (y+space==Integer.valueOf(allDatas.get(currTouch).get(1)) && x==Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是兵直行
return true;
}else{
return false;
}
}else{//已过河
if (y+space==Integer.valueOf(allDatas.get(currTouch).get(1)) && x==Integer.valueOf(allDatas.get(currTouch).get(0)) //这里是兵直行
||y==Integer.valueOf(allDatas.get(currTouch).get(1)) && x+space==Integer.valueOf(allDatas.get(currTouch).get(0))//这里是右行
||y==Integer.valueOf(allDatas.get(currTouch).get(1)) && x-space==Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是左行
return true;
}else{
return false;
}
}
}else{//黑方
if (y>startY+space*4){//在自己这边
if (y-space==Integer.valueOf(allDatas.get(currTouch).get(1)) && x==Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是兵直行
return true;
}else{
return false;
}
}else{//已过河
if (y-space==Integer.valueOf(allDatas.get(currTouch).get(1)) && x==Integer.valueOf(allDatas.get(currTouch).get(0)) //这里是兵直行
||y==Integer.valueOf(allDatas.get(currTouch).get(1)) && x+space==Integer.valueOf(allDatas.get(currTouch).get(0))//这里是右行
||y==Integer.valueOf(allDatas.get(currTouch).get(1)) && x-space==Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是左行
return true;
}else{
return false;
}
}
}
}
return false;
}
- 2 炮的走棋约束
/**
* 2 炮的走棋约束
* @return 是否有效走棋
*/
public boolean pao(){
int x;
int y;
int lx;
int ly;
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
if ((x!=lx && y!=ly) ||(x==lx&&y==ly)){//这种情况是无效的走棋
return false;
}
if (y==ly){//横向
int step_x =Math.abs( (lx-x)/space);//横向间隔步数
if (Math.abs(step_x)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(3).equals("")){
return true;
}else{
return false;
}
}
int count=0;//沒棋子时计数
int count2=0;//有棋子时计数
//中间没有棋子时
for (int i = 1; i <step_x; i++) {
if (lx>x){//向右走棋
if (allDatas.get(currPosition+i).get(3).equals("")){
count++;
}else{
count2++;
}
}else{//向左走棋时
if (allDatas.get(currPosition-i).get(3).equals("")){
count++;
}else{
count2++;
}
}
}
if (allDatas.get(currTouch).get(3).equals("")){//中间无棋子,终点无棋子时可可以落子
if (count==step_x-1){
return true;
}else{
return false;
}
}else{
if (count2==1){//中间有一颗棋子,终点为对方棋子时可以落子
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)|| allDatas.get(currTouch).get(2).equals("")){
return false;
}else{
return true;
}
}else{
return false;
}
}
}else{//竖向
int step_y = Math.abs((ly-y)/space);//竖向间隔步数
if (Math.abs(step_y)==1){//间隔一步没棋子可以落子
if (allDatas.get(currTouch).get(3).equals("")){
return true;
}else{
return false;
}
}
int count=0;//沒棋子时计数
int count2=0;//有棋子时计数
//中间没有棋子时
for (int i = 1; i <step_y; i++) {
if (ly>y){//向下走棋
if (allDatas.get(currPosition+9*i).get(3).equals("")){
count++;
}else{
count2++;
}
}else{//向上走棋时
if (allDatas.get(currPosition-9*i).get(3).equals("")){
count++;
}else{
count2++;
}
}
}
if (allDatas.get(currTouch).get(3).equals("")){//中间无棋子,终点无棋子时可可以落子
if (count==step_y-1){
return true;
}else{
return false;
}
}else{
if (count2==1){//中间有一颗棋子,终点为对方棋子时可以落子
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)|| allDatas.get(currTouch).get(2).equals("")){
return false;
}else{
return true;
}
}else{
return false;
}
}
}
}
return false;
}
-
3 车的走棋约束
/**
* 3 车的走棋约束
* @return 是否有效走棋
*/
public boolean che(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
if ((x!=lx && y!=ly) ||(x==lx&&y==ly)){//这种情况是无效的走棋
return false;
}
Log.e("ttt22222","==");
if (y==ly){//横向
Log.e("ttt33333","==");
int step_x =Math.abs( (lx-x)/space);
if (Math.abs(step_x)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt44444","==");
return false;
}else{
Log.e("ttt5555","==");
return true;
}
}
int count=0;//沒棋子时计数
for (int i = 1; i <step_x; i++) {
if (lx>x){//向右走棋
if (allDatas.get(currPosition+i).get(3).equals("")){
count++;
}else{
return false;
}
}else{//向左走棋时
if (allDatas.get(currPosition-i).get(3).equals("")){
count++;
}else{
return false;
}
}
if (i==step_x-1){//如果中间位置检查完毕
Log.e("ttt666666","==");
if(count==i){
//判断终点有别人棋子就可以走,否则不能走
if (!allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt88888","==");
return true;
}else{
Log.e("ttt999999","==");
return false;
}
}else{
Log.e("tttmmmm","==");
return false;//其他为有多子的情况
}
}
}
}else{//竖向
Log.e("ttt33333","==");
int step_y =Math.abs( (ly-y)/space);
if (Math.abs(step_y)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt44444","==");
return false;
}else{
Log.e("ttt5555","==");
return true;
}
}
int count=0;//沒棋子时计数
for (int i = 1; i <step_y; i++) {
if (ly>y){//向下走棋
if (allDatas.get(currPosition+9*i).get(3).equals("")){
count++;
}else{
return false;
}
}else{//向上走棋时
if (allDatas.get(currPosition-9*i).get(3).equals("")){
count++;
}else{
return false;
}
}
if (i==step_y-1){//如果中间位置检查完毕
Log.e("ttt666666","==");
if(count==i){
//判断终点有别人棋子就可以走,否则不能走
if (!allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt88888","==");
return true;
}else{
Log.e("ttt999999","==");
return false;
}
}else{
Log.e("tttmmmm","==");
return false;//其他为有多子的情况
}
}
}
}
}
return false;
}
-
4 马的走棋约束
/**
* 4 马的走棋约束
* @return 是否有效走棋
*/
public boolean ma(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if (Math.abs(ly-y)==2*space &&Math.abs(lx-x)==1*space){//上下方向
//上
if (ly-y<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-9).get(3))){
return false;
}
}
if (ly-y>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+9).get(3))){
return false;
}
}
return true;
}else if (Math.abs(lx-x)==2*space&&Math.abs(ly-y)==1*space){//左右方向
//左
if (lx-x<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-1).get(3))){
return false;
}
}
if (lx-x>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+1).get(3))){
return false;
}
}
return true;
}else{
return false;
}
}
}
return false;
}
-
5 象的走棋约束
/**
* 5 象的走棋约束
* @return 是否有效走棋
*/
public boolean xiang(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
//象不能过河限制
if (allDatas.get(currPosition).get(3).equals("相")&& Integer.valueOf(allDatas.get(currTouch).get(1))>startY+4*space){
return false;
}
if (allDatas.get(currPosition).get(3).equals("象")&& Integer.valueOf(allDatas.get(currTouch).get(1))<startY+5*space){
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if (Math.abs(ly-y)==2*space &&Math.abs(lx-x)==2*space){//上下方向
//向上
if (ly-y<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-9-1).get(3)) && currTouch<currPosition-2*9){//不能左飞
return false;
}
if (!TextUtils.isEmpty(allDatas.get(currPosition-9+1).get(3))&& currTouch>currPosition-2*9){//不能右飞
return false;
}
}
//向下
if (ly-y>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+9-1).get(3)) && currTouch<currPosition+2*9){//不能左飞
return false;
}
if (!TextUtils.isEmpty(allDatas.get(currPosition+9+1).get(3))&& currTouch>currPosition+2*9){//不能右飞
return false;
}
}
return true;
}else{
return false;
}
}
}
return false;
}
-
6 仕的走棋约束
/**
* 6 仕的走棋约束
* @return 是否有效走棋
*/
public boolean shi(){
int x;
int y;
int lx;
int ly;
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
//仕限制
if (allDatas.get(currPosition).get(3).equals("士")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))>startY+2*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space || Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
Log.e("tttXXXX1","==");
return false;
}
if (allDatas.get(currPosition).get(3).equals("仕")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))<startY+7*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space || Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
Log.e("tttXXXX2","==");
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
Log.e("tttXXXX3","==");
return false;
}else{
if (Math.abs(ly-y)==1*space &&Math.abs(lx-x)==1*space){
Log.e("tttXXXX4","==");
return true;
}else{
Log.e("tttXXXX5","==");
return false;
}
}
}
return false;
}
-
7 将帅的走棋约束
/**
* 7 将帅的走棋约束
* @return 是否有效走棋
*/
public boolean shuai(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x=Integer.valueOf(allDatas.get(currPosition).get(0));
y=Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx=Integer.valueOf(allDatas.get(currTouch).get(0));
ly=Integer.valueOf(allDatas.get(currTouch).get(1));
//仕限制
if (allDatas.get(currPosition).get(3).equals("将")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))>startY+2*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space ||Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
return false;
}
if (allDatas.get(currPosition).get(3).equals("帅")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))<startY+7*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space||Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if ((Math.abs(ly-y)==1*space &&Math.abs(lx-x)==0) ||(Math.abs(ly-y)==0 &&Math.abs(lx-x)==1*space)){
return true;
}
}
}
return false;
}
上面的走棋约束有备注,聪明的大家只要理解了其中一个相信会举一反百吧,这里不再做过多无用解释。棒棒哒!!!!!!!
8.被将军的提示(这里应该是整个流程中最难的环节);
这个环节暂时还未实现,请多关注更新。。。。。。。^-^ ^-^ ^-^ ^-^ ^-^
列举了上面这么多的内容,说实话没,写到此处,手已经酸了,赶紧找个按摩店,,,,,走起!!!!!
不过貌似还有东邪还没有说完,555555,摸一摸包也确实没钱啦,可怜的代码仔还是老老实实地继续撸代码吧。。。。。
前面说到了复盘的操作,就是重置到初始状态呗。还难不到我。往下看。。。。。。。。。
public void fupan(){
currRole="1";
currPosition=-1;
currTouch=-1;
allDatas.clear();
for (int k = 0; k < allDatasDefault.size(); k++) {
List<String> temp=new ArrayList<>();
for (int i = 0; i <allDatasDefault.get(k).size() ; i++) {
temp.add(allDatasDefault.get(k).get(i));
}
allDatas.add(temp);
}
invalidate();
}
然后不是还有悔棋吗,继续撸。。。。。
public void huiqi(){
Log.e("huiqi",back_datas.size()+""+back_datas.toString());
if (back_datas.size()>1){
allDatas.clear();
back_datas.remove(back_datas.size()-1);
//遍历获取当前悔棋后棋子位置信息
for (int k = 0; k < back_datas.get(back_datas.size()-1).size(); k++) {
List<String> temp=new ArrayList<>();
for (int i = 0; i <back_datas.get(back_datas.size()-1).get(k).size() ; i++) {
temp.add(back_datas.get(back_datas.size()-1).get(k).get(i));
}
allDatas.add(temp);
}
Log.e("huiqi=====",allDatas.toString());
if (currRole.equals("1")){//重置当前走棋状态
currRole="2";
currPosition=-1;
currTouch=-1;
}else{
currRole="1";
currPosition=-1;
currTouch=-1;
}
invalidate();
}else{
Toast.makeText(getContext(),"当前无法继续悔棋了",Toast.LENGTH_SHORT).show();
}
}
实现起来还是很简单的。
我们看下走棋约束、复盘、悔棋的调用时机是在onTouchEvent(MotionEvent event)中,源码:
private String currRole="1";//当前一轮走棋方 1 红方 2 黑方
private int currPosition=-1;//当前一轮走棋方选中棋子 默认-1 未选中 其他表示选中位置 移动前位置
private int currTouch=-1;//当前触摸位置 -----------------------------------------
@Override
public boolean onTouchEvent(MotionEvent event) {
//触摸位置
int cx=0;
int cy=0;
int x;
int y;
if (event.getAction()==MotionEvent.ACTION_DOWN){
cx= (int) event.getX();
cy= (int) event.getY();
//有效触摸范围
for (int i = 0; i <allDatas.size() ; i++) {
x=Integer.valueOf(allDatas.get(i).get(0));
y=Integer.valueOf(allDatas.get(i).get(1));
if (cx>x-radius&& cx<x+radius && cy>y-radius &&cy<y+radius){ //有效点击区域
Log.e("点击了有效区域","======"+i);
currTouch=i;
//要区分事件---之前是否选中
if (currPosition==-1){//没选中任何棋子
Log.e("没棋子-","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("没棋子-点了自己棋子","==");
}
}else{
Log.e("有棋子--","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("有棋子--点了自己棋子","==");
}else{
Log.e("有棋子--判断走棋","==");
//这里有两种可能,一是有别人的棋子,一是无子
//这里做走棋规则判断是否可以落子--落子后清除状态 currTouch=-1,
boolean result=false;
if (allDatas.get(currPosition).get(3).equals("兵")||allDatas.get(currPosition).get(3).equals("卒")){
result=bing();
}
//走炮的规则
if (allDatas.get(currPosition).get(3).equals("炮")){
result=pao();
}
if (allDatas.get(currPosition).get(3).equals("车")){
result=che();
}
if (allDatas.get(currPosition).get(3).equals("马")){
result=ma();
}
if (allDatas.get(currPosition).get(3).equals("象")||allDatas.get(currPosition).get(3).equals("相")){
result=xiang();
}
if (allDatas.get(currPosition).get(3).equals("仕")||allDatas.get(currPosition).get(3).equals("士")){
result=shi();
}
if (allDatas.get(currPosition).get(3).equals("将")||allDatas.get(currPosition).get(3).equals("帅")){
result=shuai();
}
if (result){
//if (meet()){
step++;
VibrateUtil.getInstance((Activity) getContext()).playRing();
//更新棋子状态
allDatas.get(i).set(2,allDatas.get(currPosition).get(2));
allDatas.get(i).set(3,allDatas.get(currPosition).get(3));
allDatas.get(currPosition).set(2,"");
allDatas.get(currPosition).set(3,"");
if (currRole.equals("1")){
currRole="2";
}else{
currRole="1";
}
//这里做棋局结束的判断
int countj =0;
int counts =0;
for (int j = 0; j <allDatas.size() ; j++) {
if (allDatas.get(j).get(3).equals("将")){
countj++;
}
if (allDatas.get(j).get(3).equals("帅")){
counts++;
}
}
if (countj==0){
Toast.makeText(getContext(),"黑方胜利",Toast.LENGTH_LONG).show();
}
if (counts==0){
Toast.makeText(getContext(),"红方胜利",Toast.LENGTH_LONG).show();
}
//走子成功后存入新棋盘
if (back_datas.size()>5){
back_datas.remove(0);
}
List<List<String>> temp=new ArrayList<>();
for (int j = 0; j < allDatas.size(); j++) {
List<String> temp1=new ArrayList<>();
for (int k = 0; k < allDatas.get(j).size(); k++) {
temp1.add(allDatas.get(j).get(k));
}
temp.add(temp1);
}
back_datas.add(temp);
Log.e("huiqi----",back_datas.size()+"");
/*}else{
Toast.makeText(getContext(),"将帅不能见面",Toast.LENGTH_SHORT).show();
}*/
}
}
}
invalidate();
}
}
//点击了自绘的悔棋按钮
if (cx>startX&& cx<startX+2*space && cy>tPadding &&cy<tPadding+space){
huiqi();
}
//点击了自绘的悔棋按钮
if (cx>startX+2*space&& cx<startX+2*space+2*space && cy>tPadding &&cy<tPadding+space){
fupan();
}
}
return true;
}
在这里我们回顾下之前的坑,为什么要使用两个对象保存而不是直接赋值添加到集合。这是因为对象的指向问题,当你执行
allDatas.clear();
back_datas.remove(back_datas.size()-1);
allDatas.addAll(back_datas.get(back_datas.size()-1));
前面不遍历数据使用另外变量存储数据的话,后续引用的指向是同一个对象,就会使数据同时该变而一起被清空,执行allDatas.clear();后再添加拿到的数据就为空白数据。另外就是上面对象的复制是同过遍历实现,你如果觉得麻烦的话,可以将对象写到内存中(需要序列化请先序列化(Serializable), ), 然后再读出,也很简单。
至此,自绘的中国象棋就实现了。
下面贴上该空间全部源码
package com.goldvsspace.chinesechess;
import android.app.Activity;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* email:1040152329@qq.com
* Created by gold on 2019/10/30
* Describe:
**/
public class ChineseChessView extends View {
private Paint linePaint;//画线的笔
private Paint qiPaint;//棋子文子画笔
private Paint qibackPaint;//棋子背景画笔
private int lineColor=0xffEEDC82;
private int redColor=0xffFFA54F;
private int blockColor=0xff008B00;
private int selectColor=0xff3A5FCD;
public ChineseChessView(Context context) {
this(context,null);
}
private int strokeWidth=5;
private void initView() {
linePaint=new Paint();
qibackPaint=new Paint();
qiPaint=new Paint();
initSetting();
}
private void initSetting() {
linePaint.setAntiAlias(true);
linePaint.setColor(lineColor);
linePaint.setStyle(Paint.Style.STROKE);
qiPaint.setAntiAlias(true);
qiPaint.setColor(lineColor);
qiPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
qibackPaint.setColor(0xffEEDC82);
qibackPaint.setStyle(Paint.Style.FILL);
//qibackPaint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.NORMAL));
qibackPaint.setAntiAlias(true);
}
public ChineseChessView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public ChineseChessView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private int h;
private int w;
private int startX,startY;//起始绘制位置
private int defaultPadding=50;
private int hang = 9;//行
private int lie = 8; //列
private int space;
//存放所有位置信息 [X,Y,0,车] 依次对应 【x坐标、y坐标、红黑方、棋子】
private List<List<String>> allDatas=new ArrayList<>();
private List<List<String>> allDatasDefault=new ArrayList<>();
private List<List<List<String>>> back_datas=new ArrayList<>();//下棋落子记录,用于悔棋时调用
private boolean isInit=true;//是否第一次进来————初始化棋盘
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.h=h;
this.w=w;
int realWidth=w-defaultPadding*2;
int realHeight=realWidth*9/8;
space=realWidth/8;
startX=defaultPadding;
startY=(h-realHeight)/2;
}
//画棋盘
private int b_color=0xffF0F0F0;//棋盘背景
private final String back = "悔棋";
private final String reset = "复盘";
private final String per1 = "楚河";
private final String per2 = "汉界";
private final String[] chess1={"车","马","相","士","将"};
private final String[] chess1_d={"车","马","象","仕","帅"};
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initSetting();
//绘制整个背景
canvas.drawColor(b_color);
//canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.background),new Rect(0,0,w,h),new Rect(0,0,w,h),linePaint);
//绘制外边框
linePaint.setStrokeWidth((defaultPadding/2)*2/3);
canvas.drawRect(startX-defaultPadding/2,startY-defaultPadding/2,startX+space*8+defaultPadding/2,startY+space*9+defaultPadding/2,linePaint);
//绘制网格
linePaint.setStrokeWidth(strokeWidth);
for (int i = 0; i <=hang ; i++) {
canvas.drawLine(startX,startY+space*i,startX+space*8,startY+space*i,linePaint);
}
for (int i = 0; i <=lie ; i++) {
canvas.drawLine(startX+space*i,startY,startX+space*i,startY+space*9,linePaint);
}
//绘制楚河汉界区域
linePaint.setColor(b_color);
linePaint.setStyle(Paint.Style.FILL);
int left=startX+strokeWidth/2;
int top=startY+space*4+strokeWidth/2;
int right=startX+space*8-strokeWidth/2;
int bottom=startY+space*5-strokeWidth/2;
canvas.drawRect(left,top,right,bottom,linePaint);
//绘制文字楚河汉界
linePaint.setColor(0xffFFD39B);
linePaint.setTextSize(50);
linePaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
Rect rect = new Rect();
linePaint.getTextBounds(per2,0,per2.length(),rect);
int per_width = rect.width();
int per_height = rect.height();
canvas.drawText(per1,startX+space/2,(top+bottom)/2+per_height/2,linePaint);
canvas.drawText(per2,right-space/2-per_width,(top+bottom)/2+per_height/2,linePaint);
//绘制提示当前走棋方
linePaint.setTextSize(35);
String text;
if (currRole.equals("1")){
linePaint.setColor(0xffff0000);
text="红方走棋";
}else{
linePaint.setColor(0xff000000);
text="黑方走棋";
}
Rect rect1 = new Rect();
linePaint.getTextBounds(text,0,text.length(),rect1);
int per_width1 = rect1.width();
int per_height1 = rect1.height();
canvas.drawText(text,w/2-per_width1/2,(top+bottom)/2+per_height1/2,linePaint);
//绘制辅助线---将帅斜线
linePaint.setColor(lineColor);
float [] dts = {
startX+space*3,startY,startX+space*5,startY+space*2,
startX+space*3,startY+space*2,startX+space*5,startY,
startX+space*3,startY+space*7,startX+space*5,startY+space*9,
startX+space*3,startY+space*9,startX+space*5,startY+space*7
};
canvas.drawLines(dts,linePaint);
//获取棋盘上所有放置位置---基础
if (isInit){
isInit=false;
allDatas.clear();
for (int i = 0; i <=hang ; i++) {//获取Y值---行
int y = startY+space*i;
for (int j = 0; j <=lie; j++) {//获取X值---列
int x = startX+space*j;
List<String> data=new ArrayList<>();
data.add(x+"");
data.add(y+"");
if (i==0){
data.add("1");
data.add(chess1[j<=4?j%5:3-j%5]);//{"车","马","相","士","将"}
}else if (i==9){
data.add("2");
data.add(chess1_d[j<=4?j%5:3-j%5]);//{"车","马","象","仕","帅"}
}else if (i==2){
if (j==1||j==7){
data.add("1");
data.add("炮");
addlines(canvas,x,y,0);
}else{
data.add("");
data.add("");
}
}else if (i==7){
if (j==1||j==7){
data.add("2");
data.add("炮");
addlines(canvas,x,y,0);
}else{
data.add("");
data.add("");
}
}else if (i==3){
if (j%2==0){
data.add("1");
data.add("兵");
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}else{
data.add("");
data.add("");
}
}else if (i==6 ){
if (j%2==0){
data.add("2");
data.add("卒");
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}else{
data.add("");
data.add("");
}
}else{
data.add("");
data.add("");
}
allDatas.add(data);
}
}
List<List<String>> temp=new ArrayList<>();
for (int j = 0; j < allDatas.size(); j++) {
List<String> temp1=new ArrayList<>();
List<String> temp2=new ArrayList<>();
for (int k = 0; k < allDatas.get(j).size(); k++) {
temp1.add(allDatas.get(j).get(k));
temp2.add(allDatas.get(j).get(k));
}
temp.add(temp1);
allDatasDefault.add(temp2);
}
back_datas.add(temp);
}
//绘制交点折线
for (int i = 0; i <=hang ; i++) {//获取Y值---行
int y = startY+space*i;
for (int j = 0; j <=lie; j++) {//获取X值---列
int x = startX+space*j;
if (i==2&&(j==1||j==7)){
addlines(canvas,x,y,0);
}
if (i==7&&(j==1||j==7)){
addlines(canvas,x,y,0);
}
if (i==3&&j%2==0){
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}
if (i==6&&j%2==0){
if (j==0){
addlines(canvas,x,y,2);
}else if (j==8){
addlines(canvas,x,y,1);
}else{
addlines(canvas,x,y,0);
}
}
}
}
//绘制悔棋按钮
linePaint.setStyle(Paint.Style.FILL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
linePaint.setColor(lineColor);
Rect rect3=new Rect();
linePaint.getTextBounds(back,0,back.length(),rect3);
int h_width = rect3.width();
int h_height = rect3.height();
canvas.drawRoundRect(startX,tPadding,startX+2*space,tPadding+space,30,30,linePaint);
linePaint.setColor(blockColor);
canvas.drawText(back,startX+space-h_width/2,tPadding+space/2+h_height/2,linePaint);
}
//绘制复盘按钮
linePaint.setStyle(Paint.Style.FILL);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
linePaint.setColor(lineColor);
Rect rect3=new Rect();
linePaint.getTextBounds(reset,0,reset.length(),rect3);
int h_width = rect3.width();
int h_height = rect3.height();
canvas.drawRoundRect(startX+2*space,tPadding,startX+2*space+2*space,tPadding+space,30,30,linePaint);
linePaint.setColor(blockColor);
canvas.drawText(reset,startX+2*space+2*space/2-h_width/2,tPadding+space/2+h_height/2,linePaint);
}
}
private int tPadding=10;//角落辅助线的间隔
private int tlength=20;
/**
* 绘制特殊位置辅线---角落辅助线
* @param canvas
* @param x 交点x
* @param y 交点y
* @param type 1都有 1只有左边 2只有右边
*/
private void addlines(Canvas canvas, int x, int y, int type) {
Path path=new Path();
//左上
int sx;
int sy;
int sx1;
int sy1;
int sx2;
int sy2;
if (type==0||type==1){
//左上
sx= x-tPadding;
sy = y-tPadding;
sx1=sx-tlength;
sy1=sy;
sx2=sx;
sy2=sy-tlength;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
//左下
sx=x-tPadding;
sy=y+tPadding;
sx1=sx;
sy1=sy+tlength;
sx2=sx-tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
}
if (type==0||type==2){
//右上
sx=x+tPadding;
sy=y-tPadding;
sx1=sx;
sy1=sy-tlength;
sx2=sx+tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
//右下
sx= x+tPadding;
sy = y+tPadding;
sx1=sx;
sy1=sy+tlength;
sx2=sx+tlength;
sy2=sy;
path.moveTo(sx1,sy1);
path.lineTo(sx,sy);
path.lineTo(sx2,sy2);
}
linePaint.setColor(lineColor);
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setStrokeWidth(3);
canvas.drawPath(path,linePaint);
}
//画棋子
private int radius=40;
private boolean isFirst=true;
@Override
public void onDrawForeground(Canvas canvas) {
super.onDrawForeground(canvas);
Rect rect=new Rect();
qiPaint.getTextBounds(chess1[0],0,1,rect);
int per_width2 = rect.width();
int per_height2 = rect.height();
qiPaint.setTextSize(40);
//获取棋盘上所有放置位置
Log.e("棋盘大小111"," ---"+allDatas.size()+" ---" +allDatas.toString());
//根据棋盘棋子位置变化更新棋盘
for (int i = 0; i < allDatas.size(); i++) {
if (allDatas.get(i).get(2).equals("1")){//表示红棋
qiPaint.setColor(0xffff0000);
//该自己走棋才改变棋子背景颜色
if (i==currPosition &&currRole.equals("1")){
qibackPaint.setColor(selectColor);
}else{
qibackPaint.setColor(redColor);
}
canvas.drawCircle(Float.valueOf(allDatas.get(i).get(0)), Float.valueOf(allDatas.get(i).get(1)),radius,qibackPaint);
int x= Integer.valueOf(allDatas.get(i).get(0));
int y= Integer.valueOf(allDatas.get(i).get(1));
int lx= x-per_width2/2-strokeWidth;
int ly= y+per_height2/2-strokeWidth;
canvas.drawText(allDatas.get(i).get(3),lx,ly,qiPaint);
}else if (allDatas.get(i).get(2).equals("2")){//表示黑棋--其他无棋位置不做处理
qiPaint.setColor(0xff000000);
//该自己走棋才改变棋子背景颜色
if (i==currPosition&&currRole.equals("2")){
qibackPaint.setColor(selectColor);
}else{
qibackPaint.setColor(blockColor);
}
canvas.drawCircle(Float.valueOf(allDatas.get(i).get(0)), Float.valueOf(allDatas.get(i).get(1)),radius,qibackPaint);
int x= Integer.valueOf(allDatas.get(i).get(0));
int y= Integer.valueOf(allDatas.get(i).get(1));
int lx= x-per_width2/2-strokeWidth;
int ly= y+per_height2/2-strokeWidth;
canvas.drawText(allDatas.get(i).get(3),lx,ly,qiPaint);
}
}
if (isFirst){
isFirst=false;
invalidate();
}
}
private String currRole="1";//当前一轮走棋方 1 红方 2 黑方
private int currPosition=-1;//当前一轮走棋方选中棋子 默认-1 未选中 其他表示选中位置 移动前位置
private int currTouch=-1;//当前触摸位置 -----------------------------------------
@Override
public boolean onTouchEvent(MotionEvent event) {
//触摸位置
int cx=0;
int cy=0;
int x;
int y;
if (event.getAction()== MotionEvent.ACTION_DOWN){
cx= (int) event.getX();
cy= (int) event.getY();
//有效触摸范围
for (int i = 0; i <allDatas.size() ; i++) {
x= Integer.valueOf(allDatas.get(i).get(0));
y= Integer.valueOf(allDatas.get(i).get(1));
if (cx>x-radius&& cx<x+radius && cy>y-radius &&cy<y+radius){ //有效点击区域
Log.e("点击了有效区域","======"+i);
currTouch=i;
//要区分事件---之前是否选中
if (currPosition==-1){//没选中任何棋子
Log.e("没棋子-","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("没棋子-点了自己棋子","==");
}
}else{
Log.e("有棋子--","==");
//--当前点击区域是否有棋子
if (currRole.equals(allDatas.get(i).get(2))){//表示当前选中了自己的棋子
currPosition=i;
Log.e("有棋子--点了自己棋子","==");
}else{
Log.e("有棋子--判断走棋","==");
//这里有两种可能,一是有别人的棋子,一是无子
//这里做走棋规则判断是否可以落子--落子后清除状态 currTouch=-1,
boolean result=false;
if (allDatas.get(currPosition).get(3).equals("兵")||allDatas.get(currPosition).get(3).equals("卒")){
result=bing();
}
//走炮的规则
if (allDatas.get(currPosition).get(3).equals("炮")){
result=pao();
}
if (allDatas.get(currPosition).get(3).equals("车")){
result=che();
}
if (allDatas.get(currPosition).get(3).equals("马")){
result=ma();
}
if (allDatas.get(currPosition).get(3).equals("象")||allDatas.get(currPosition).get(3).equals("相")){
result=xiang();
}
if (allDatas.get(currPosition).get(3).equals("仕")||allDatas.get(currPosition).get(3).equals("士")){
result=shi();
}
if (allDatas.get(currPosition).get(3).equals("将")||allDatas.get(currPosition).get(3).equals("帅")){
result=shuai();
}
if (result){
//if (meet()){
VibrateUtil.getInstance((Activity) getContext()).playRing();
//更新棋子状态
allDatas.get(i).set(2,allDatas.get(currPosition).get(2));
allDatas.get(i).set(3,allDatas.get(currPosition).get(3));
allDatas.get(currPosition).set(2,"");
allDatas.get(currPosition).set(3,"");
if (currRole.equals("1")){
currRole="2";
}else{
currRole="1";
}
//这里做棋局结束的判断
int countj =0;
int counts =0;
for (int j = 0; j <allDatas.size() ; j++) {
if (allDatas.get(j).get(3).equals("将")){
countj++;
}
if (allDatas.get(j).get(3).equals("帅")){
counts++;
}
}
if (countj==0){
Toast.makeText(getContext(),"黑方胜利", Toast.LENGTH_LONG).show();
}
if (counts==0){
Toast.makeText(getContext(),"红方胜利", Toast.LENGTH_LONG).show();
}
//走子成功后存入新棋盘
List<List<String>> temp=new ArrayList<>();
for (int j = 0; j < allDatas.size(); j++) {
List<String> temp1=new ArrayList<>();
for (int k = 0; k < allDatas.get(j).size(); k++) {
temp1.add(allDatas.get(j).get(k));
}
temp.add(temp1);
}
back_datas.add(temp);
Log.e("huiqi----",back_datas.size()+"");
/*}else{
Toast.makeText(getContext(),"将帅不能见面",Toast.LENGTH_SHORT).show();
}*/
}
}
}
invalidate();
}
}
//点击了自绘的悔棋按钮
if (cx>startX&& cx<startX+2*space && cy>tPadding &&cy<tPadding+space){
huiqi();
}
//点击了自绘的悔棋按钮
if (cx>startX+2*space&& cx<startX+2*space+2*space && cy>tPadding &&cy<tPadding+space){
fupan();
}
}
return true;
}
//========================================************************下面约定走棋规则*********************=============================================
/**
* 1 兵的走棋约束
* @return 是否有效走棋
*/
public boolean bing(){
int x;
int y;
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
if (currRole.equals("1")){//红方
if (y<startY+space*5){//在自己这边
if (y+space== Integer.valueOf(allDatas.get(currTouch).get(1)) && x== Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是兵直行
return true;
}else{
return false;
}
}else{//已过河
if (y+space== Integer.valueOf(allDatas.get(currTouch).get(1)) && x== Integer.valueOf(allDatas.get(currTouch).get(0)) //这里是兵直行
||y== Integer.valueOf(allDatas.get(currTouch).get(1)) && x+space== Integer.valueOf(allDatas.get(currTouch).get(0))//这里是右行
||y== Integer.valueOf(allDatas.get(currTouch).get(1)) && x-space== Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是左行
return true;
}else{
return false;
}
}
}else{//黑方
if (y>startY+space*4){//在自己这边
if (y-space== Integer.valueOf(allDatas.get(currTouch).get(1)) && x== Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是兵直行
return true;
}else{
return false;
}
}else{//已过河
if (y-space== Integer.valueOf(allDatas.get(currTouch).get(1)) && x== Integer.valueOf(allDatas.get(currTouch).get(0)) //这里是兵直行
||y== Integer.valueOf(allDatas.get(currTouch).get(1)) && x+space== Integer.valueOf(allDatas.get(currTouch).get(0))//这里是右行
||y== Integer.valueOf(allDatas.get(currTouch).get(1)) && x-space== Integer.valueOf(allDatas.get(currTouch).get(0))){//这里是左行
return true;
}else{
return false;
}
}
}
}
return false;
}
/**
* 2 炮的走棋约束
* @return 是否有效走棋
*/
public boolean pao(){
int x;
int y;
int lx;
int ly;
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
if ((x!=lx && y!=ly) ||(x==lx&&y==ly)){//这种情况是无效的走棋
return false;
}
if (y==ly){//横向
int step_x = Math.abs( (lx-x)/space);//横向间隔步数
if (Math.abs(step_x)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(3).equals("")){
return true;
}else{
return false;
}
}
int count=0;//沒棋子时计数
int count2=0;//有棋子时计数
//中间没有棋子时
for (int i = 1; i <step_x; i++) {
if (lx>x){//向右走棋
if (allDatas.get(currPosition+i).get(3).equals("")){
count++;
}else{
count2++;
}
}else{//向左走棋时
if (allDatas.get(currPosition-i).get(3).equals("")){
count++;
}else{
count2++;
}
}
}
if (allDatas.get(currTouch).get(3).equals("")){//中间无棋子,终点无棋子时可可以落子
if (count==step_x-1){
return true;
}else{
return false;
}
}else{
if (count2==1){//中间有一颗棋子,终点为对方棋子时可以落子
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)|| allDatas.get(currTouch).get(2).equals("")){
return false;
}else{
return true;
}
}else{
return false;
}
}
}else{//竖向
int step_y = Math.abs((ly-y)/space);//竖向间隔步数
if (Math.abs(step_y)==1){//间隔一步没棋子可以落子
if (allDatas.get(currTouch).get(3).equals("")){
return true;
}else{
return false;
}
}
int count=0;//沒棋子时计数
int count2=0;//有棋子时计数
//中间没有棋子时
for (int i = 1; i <step_y; i++) {
if (ly>y){//向下走棋
if (allDatas.get(currPosition+9*i).get(3).equals("")){
count++;
}else{
count2++;
}
}else{//向上走棋时
if (allDatas.get(currPosition-9*i).get(3).equals("")){
count++;
}else{
count2++;
}
}
}
if (allDatas.get(currTouch).get(3).equals("")){//中间无棋子,终点无棋子时可可以落子
if (count==step_y-1){
return true;
}else{
return false;
}
}else{
if (count2==1){//中间有一颗棋子,终点为对方棋子时可以落子
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)|| allDatas.get(currTouch).get(2).equals("")){
return false;
}else{
return true;
}
}else{
return false;
}
}
}
}
return false;
}
/**
* 3 车的走棋约束
* @return 是否有效走棋
*/
public boolean che(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
if ((x!=lx && y!=ly) ||(x==lx&&y==ly)){//这种情况是无效的走棋
return false;
}
Log.e("ttt22222","==");
if (y==ly){//横向
Log.e("ttt33333","==");
int step_x = Math.abs( (lx-x)/space);
if (Math.abs(step_x)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt44444","==");
return false;
}else{
Log.e("ttt5555","==");
return true;
}
}
int count=0;//沒棋子时计数
for (int i = 1; i <step_x; i++) {
if (lx>x){//向右走棋
if (allDatas.get(currPosition+i).get(3).equals("")){
count++;
}else{
return false;
}
}else{//向左走棋时
if (allDatas.get(currPosition-i).get(3).equals("")){
count++;
}else{
return false;
}
}
if (i==step_x-1){//如果中间位置检查完毕
Log.e("ttt666666","==");
if(count==i){
//判断终点有别人棋子就可以走,否则不能走
if (!allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt88888","==");
return true;
}else{
Log.e("ttt999999","==");
return false;
}
}else{
Log.e("tttmmmm","==");
return false;//其他为有多子的情况
}
}
}
}else{//竖向
Log.e("ttt33333","==");
int step_y = Math.abs( (ly-y)/space);
if (Math.abs(step_y)==1){//只走一步
//判断终点有别人棋子就可以走,否则不能走
if (allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt44444","==");
return false;
}else{
Log.e("ttt5555","==");
return true;
}
}
int count=0;//沒棋子时计数
for (int i = 1; i <step_y; i++) {
if (ly>y){//向下走棋
if (allDatas.get(currPosition+9*i).get(3).equals("")){
count++;
}else{
return false;
}
}else{//向上走棋时
if (allDatas.get(currPosition-9*i).get(3).equals("")){
count++;
}else{
return false;
}
}
if (i==step_y-1){//如果中间位置检查完毕
Log.e("ttt666666","==");
if(count==i){
//判断终点有别人棋子就可以走,否则不能走
if (!allDatas.get(currTouch).get(2).equals(currRole)){
Log.e("ttt88888","==");
return true;
}else{
Log.e("ttt999999","==");
return false;
}
}else{
Log.e("tttmmmm","==");
return false;//其他为有多子的情况
}
}
}
}
}
return false;
}
/**
* 4 马的走棋约束
* @return 是否有效走棋
*/
public boolean ma(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if (Math.abs(ly-y)==2*space && Math.abs(lx-x)==1*space){//上下方向
//上
if (ly-y<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-9).get(3))){
return false;
}
}
if (ly-y>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+9).get(3))){
return false;
}
}
return true;
}else if (Math.abs(lx-x)==2*space&& Math.abs(ly-y)==1*space){//左右方向
//左
if (lx-x<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-1).get(3))){
return false;
}
}
if (lx-x>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+1).get(3))){
return false;
}
}
return true;
}else{
return false;
}
}
}
return false;
}
/**
* 5 象的走棋约束
* @return 是否有效走棋
*/
public boolean xiang(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
//象不能过河限制
if (allDatas.get(currPosition).get(3).equals("相")&& Integer.valueOf(allDatas.get(currTouch).get(1))>startY+4*space){
return false;
}
if (allDatas.get(currPosition).get(3).equals("象")&& Integer.valueOf(allDatas.get(currTouch).get(1))<startY+5*space){
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if (Math.abs(ly-y)==2*space && Math.abs(lx-x)==2*space){//上下方向
//向上
if (ly-y<0){
if (!TextUtils.isEmpty(allDatas.get(currPosition-9-1).get(3)) && currTouch<currPosition-2*9){//不能左飞
return false;
}
if (!TextUtils.isEmpty(allDatas.get(currPosition-9+1).get(3))&& currTouch>currPosition-2*9){//不能右飞
return false;
}
}
//向下
if (ly-y>0){
if (!TextUtils.isEmpty(allDatas.get(currPosition+9-1).get(3)) && currTouch<currPosition+2*9){//不能左飞
return false;
}
if (!TextUtils.isEmpty(allDatas.get(currPosition+9+1).get(3))&& currTouch>currPosition+2*9){//不能右飞
return false;
}
}
return true;
}else{
return false;
}
}
}
return false;
}
/**
* 6 仕的走棋约束
* @return 是否有效走棋
*/
public boolean shi(){
int x;
int y;
int lx;
int ly;
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
//仕限制
if (allDatas.get(currPosition).get(3).equals("士")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))>startY+2*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space || Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
Log.e("tttXXXX1","==");
return false;
}
if (allDatas.get(currPosition).get(3).equals("仕")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))<startY+7*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space || Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
Log.e("tttXXXX2","==");
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
Log.e("tttXXXX3","==");
return false;
}else{
if (Math.abs(ly-y)==1*space && Math.abs(lx-x)==1*space){
Log.e("tttXXXX4","==");
return true;
}else{
Log.e("tttXXXX5","==");
return false;
}
}
}
return false;
}
/**
* 7 将帅的走棋约束
* @return 是否有效走棋
*/
public boolean shuai(){
int x;
int y;
int lx;
int ly;
Log.e("ttt11111","==");
if (currPosition!=-1){
//选中棋子位置
x= Integer.valueOf(allDatas.get(currPosition).get(0));
y= Integer.valueOf(allDatas.get(currPosition).get(1));
//要走的位置
lx= Integer.valueOf(allDatas.get(currTouch).get(0));
ly= Integer.valueOf(allDatas.get(currTouch).get(1));
//仕限制
if (allDatas.get(currPosition).get(3).equals("将")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))>startY+2*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space || Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
return false;
}
if (allDatas.get(currPosition).get(3).equals("帅")&&
(Integer.valueOf(allDatas.get(currTouch).get(1))<startY+7*space||
(Integer.valueOf(allDatas.get(currTouch).get(0))<startX+3*space|| Integer.valueOf(allDatas.get(currTouch).get(0))>startX+5*space))){
return false;
}
if (allDatas.get(currTouch).get(2).equals(currRole)){//如果是自己的棋就不能走
return false;
}else{
if ((Math.abs(ly-y)==1*space && Math.abs(lx-x)==0) ||(Math.abs(ly-y)==0 && Math.abs(lx-x)==1*space)){
return true;
}
}
}
return false;
}
/**
* 8 将帅不能见面的走棋约束 true会 false不会
* @return 是否有效走棋
*/
public boolean meet() {
if (currPosition != -1) {
int j_position = 0;//将的位置
int s_position = 0;//帅的位置
for (int i = 0; i < allDatas.size(); i++) {
if (allDatas.get(i).get(3).equals("将")) {
j_position = i;
} else if (allDatas.get(i).get(3).equals("帅")) {
s_position = i;
}
}
int count = 0;//将帅直线中间有多少个棋子
Log.e("ffff-------------", "==" + allDatas.toString());
if (j_position % 9 == s_position % 9) {//将帅在同一直线上时---中间只有一个棋子不能移动
for (int i = (j_position/9)+1; i < s_position / 9; i++) {
if (!TextUtils.isEmpty(allDatas.get(i * 9 + j_position).get(3))) {
Log.e("ffff-------------", allDatas.get(i * 9 + j_position).get(3)+"==" + count);
count++;
}
}
Log.e("ffff---------11----", "==" + count);
if (count == 1) {
Log.e("ffff-------22------", (currPosition % 9 == j_position % 9) +""+ (currTouch != j_position % 9) +(currPosition>j_position)+(currPosition<s_position)+"==" + count);
if (currPosition % 9 == j_position % 9 && currTouch%9 != j_position % 9 &&currPosition>j_position&&currPosition<s_position) {//只有一棋走开
Log.e("ffff-------333------", "==" + count);
return false;
}
}
}else{
Log.e("ffff------44-------", "==" + count);
if (Math.abs(j_position%9-s_position%9)==1){//将帅所在直线相邻--中间无棋子不能移动见面
Log.e("ffff-----66--------", "==" + count);
if (allDatas.get(currPosition).get(3).equals("将")){
Log.e("ffff------77-------", "==" + count);
if (currTouch%9==s_position%9 && (currTouch==j_position+1||currTouch==j_position-1)){
for (int i = currTouch/9+1; i < s_position / 9; i++) {
if (!TextUtils.isEmpty(allDatas.get(s_position-i * 9 ).get(3))) {
Log.e("ffff-------------", allDatas.get(s_position-i * 9).get(3)+"==" + count);
count++;
}
}
if (count==0){
Log.e("ffff-----88--------", "==" + count);
return false;
}
}
}
if (allDatas.get(currPosition).get(3).equals("帅")){
Log.e("ffff------99-------", "==" + count);
if (currTouch%9==j_position%9&&(currTouch==s_position+1||currTouch==s_position-1)){//帅是在左右移动一步时
for (int i = j_position/9+1; i < currTouch / 9; i++) {
if (!TextUtils.isEmpty(allDatas.get(i * 9 + j_position).get(3))) {
Log.e("ffff-------------", allDatas.get(i * 9 + j_position).get(3)+"==" + count);
count++;
}
}
if (count==0){
Log.e("ffff-----mm--------", "==" + count);
return false;
}
return false;
}
}
}
}
}
return true;
}
public void huiqi(){
Log.e("huiqi",back_datas.size()+""+back_datas.toString());
if (back_datas.size()>1){
allDatas.clear();
back_datas.remove(back_datas.size()-1);
for (int k = 0; k < back_datas.get(back_datas.size()-1).size(); k++) {
List<String> temp=new ArrayList<>();
for (int i = 0; i <back_datas.get(back_datas.size()-1).get(k).size() ; i++) {
temp.add(back_datas.get(back_datas.size()-1).get(k).get(i));
}
allDatas.add(temp);
}
Log.e("huiqi=====",allDatas.toString());
if (currRole.equals("1")){
currRole="2";
currPosition=-1;
currTouch=-1;
}else{
currRole="1";
currPosition=-1;
currTouch=-1;
}
invalidate();
}else{
Toast.makeText(getContext(),"当前无法继续悔棋了", Toast.LENGTH_SHORT).show();
}
}
public void fupan(){
currRole="1";
currPosition=-1;
currTouch=-1;
allDatas.clear();
for (int k = 0; k < allDatasDefault.size(); k++) {
List<String> temp=new ArrayList<>();
for (int i = 0; i <allDatasDefault.get(k).size() ; i++) {
temp.add(allDatasDefault.get(k).get(i));
}
allDatas.add(temp);
}
invalidate();
}
}
欢迎参考与评论留言: