中國象棋(引用自百度百科)
中國象棋是起源於中國的一種棋戲,屬於二人對抗性遊戲的一種,在中國有着悠久的歷史。由於用具簡單,趣味性強,成爲流行極爲廣泛的棋藝活動。 中國象棋是中國棋文化也是中華民族的文化瑰寶,它源遠流長,趣味濃厚,基本規則簡明易懂,千百年來長盛不衰。中國象棋是模擬的古代戰爭、直線戰爭、陸地戰爭、平面戰爭。在中國古代,象棋被列爲士大夫們的修身之藝。現在,則被視爲是怡神益智的一種有益身心的活動。象棋集文化、科學、藝術、競技於一身,不但可以開發智力,啓迪思維,鍛鍊辨證分析能力和培養頑強的意志,而且可以修心養性,陶冶情操,豐富文化生活,深受廣大羣衆的喜愛。古今中外男女老少皆宜,由於用具簡單,趣味性強,大街小巷常常可見紋枰對弈的中國象棋愛好者。中國象棋使用方形格狀棋盤及紅黑二色圓形棋子進行對弈,棋盤上有十條橫線、九條豎線共分成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:[email protected]
* 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();
}
}
歡迎參考與評論留言: