Android studio中国象棋,下棋思路与代码实现

(下载资源在文末)


实现中国象棋之类的游戏都会自定义一个View,本次用到SurfaceView,不了解的小伙伴可以自己了解一下。

  1. 象棋的运行思路

执行过程:点击屏幕(屏幕监听) ——>是否到自己走棋(是) ——>判断是否已经选中棋子(是) ——>判断点击位置是否有自己的棋子(是)——>选中该棋子(true)——>再次点击屏幕——>判断位置是否符合下棋规则(点击位置有对方棋子或空位)——>可以移动,改变棋盘(数组)。

  1. 代码实现

实现棋盘所有功能(1、显示棋盘 2、新局、悔棋、设置、返回功能 )

activity_pvm.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/relativeLayout"
    android:background="@drawable/background"
    tools:context="com.example.a77304.chessgame.PvMActivity">

</RelativeLayout>

button_group.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentStart="true">

    <Button
        android:id="@+id/btn_retry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/btn_recall"
        android:layout_centerVertical="true"
        android:layout_margin="5dp"
        android:background="@drawable/selector_btn2"
        android:textSize="24dp"
        android:text="新局" />

    <Button
        android:id="@+id/btn_recall"
        android:soundEffectsEnabled="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/btn_null"
        android:layout_centerVertical="true"
        android:layout_margin="5dp"
        android:background="@drawable/selector_btn2"
        android:textSize="24dp"
        android:text="悔棋" />

    <Button
        android:id="@+id/btn_null"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="" />

    <Button
        android:id="@+id/btn_setting"
        android:soundEffectsEnabled="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/btn_null"
        android:layout_centerVertical="true"
        android:layout_margin="5dp"
        android:background="@drawable/selector_btn2"
        android:textSize="24dp"
        android:text="设置" />

    <Button
        android:id="@+id/btn_back"
        android:soundEffectsEnabled="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/btn_setting"
        android:layout_centerVertical="true"
        android:layout_margin="5dp"
        android:background="@drawable/selector_btn2"
        android:textSize="24dp"
        android:text="返回" />

</RelativeLayout>

PvMActivity.java


import android.content.SharedPreferences;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.Toast;

import AICore.AI;
import AICore.KnowledgeBase;
import AICore.Move;
import AICore.TransformTable;
import ChessMove.Rule;
import CustomDialog.CommonDialog;
import CustomDialog.RetryDialog;
import CustomDialog.SettingDialog_PvM;
import CustomView.RoundView;
import Info.ChessInfo;
import Info.InfoSet;
import Info.Pos;
import Info.SaveInfo;
import CustomView.ChessView;

import static AICore.AI.getBestMove;
import static com.example.a77304.chessgame.HomeActivity.MIN_CLICK_DELAY_TIME;
import static com.example.a77304.chessgame.HomeActivity.backMusic;
import static com.example.a77304.chessgame.HomeActivity.checkMusic;
import static com.example.a77304.chessgame.HomeActivity.clickMusic;
import static com.example.a77304.chessgame.HomeActivity.curClickTime;
import static com.example.a77304.chessgame.HomeActivity.lastClickTime;
import static com.example.a77304.chessgame.HomeActivity.playEffect;
import static com.example.a77304.chessgame.HomeActivity.playMusic;
import static com.example.a77304.chessgame.HomeActivity.selectMusic;
import static com.example.a77304.chessgame.HomeActivity.setting;
import static com.example.a77304.chessgame.HomeActivity.sharedPreferences;
import static com.example.a77304.chessgame.HomeActivity.stopMusic;
import static com.example.a77304.chessgame.HomeActivity.winMusic;


public class PvMActivity extends AppCompatActivity implements View.OnTouchListener, View.OnClickListener {
    public RelativeLayout relativeLayout;
    public ChessInfo chessInfo;
    public InfoSet infoSet;
    public ChessView chessView;   // 自定义的View,用于绘制棋盘、棋子
    public RoundView roundView;   // 自定义View(显示 红方回合、黑方回合)

    public static KnowledgeBase knowledgeBase;
    public static TransformTable transformTable;

    public Thread AIThread = new Thread(new Runnable() {
        @Override
        public void run() {
            AIMove(chessInfo.IsRedGo, chessInfo.status);
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pvm);
        relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);


        chessInfo = new ChessInfo();
        infoSet = new InfoSet();
        transformTable = new TransformTable();
        knowledgeBase = new KnowledgeBase();


        roundView = new RoundView(this, chessInfo);
        //添加View(红方回合、黑方回合)
        relativeLayout.addView(roundView);

        RelativeLayout.LayoutParams paramsRound = (RelativeLayout.LayoutParams) roundView.getLayoutParams();
        paramsRound.addRule(RelativeLayout.CENTER_IN_PARENT);
        paramsRound.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        paramsRound.setMargins(30, 30, 30, 30);
        roundView.setLayoutParams(paramsRound);
        roundView.setId(R.id.roundView);

        chessView = new ChessView(this, chessInfo);
        chessView.setOnTouchListener(this);
        //添加View(绘制棋盘、棋子)
        relativeLayout.addView(chessView);

        RelativeLayout.LayoutParams paramsChess = (RelativeLayout.LayoutParams) chessView.getLayoutParams();
        paramsChess.addRule(RelativeLayout.BELOW, R.id.roundView);
        chessView.setLayoutParams(paramsChess);
        chessView.setId(R.id.chessView);


        LayoutInflater inflater = LayoutInflater.from(this);
        RelativeLayout buttonGroup = (RelativeLayout) inflater.inflate(R.layout.button_group, relativeLayout, false);
        //添加View(新局、悔棋、设置、返回)
        relativeLayout.addView(buttonGroup);

        RelativeLayout.LayoutParams paramsV = (RelativeLayout.LayoutParams) buttonGroup.getLayoutParams();
        paramsV.addRule(RelativeLayout.BELOW, R.id.chessView);
        buttonGroup.setLayoutParams(paramsV);

        for (int i = 0; i < buttonGroup.getChildCount(); i++) {
            Button btn = (Button) buttonGroup.getChildAt(i);
            btn.setOnClickListener(this);
        }

    }

    /**
     * 屏幕监听
     * @param view
     * @param event
     * @return
     */
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        lastClickTime = System.currentTimeMillis();
        if (lastClickTime - curClickTime < MIN_CLICK_DELAY_TIME) {
            return false;
        }
        curClickTime = lastClickTime;

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            float x = event.getX();
            float y = event.getY();
            if (chessInfo.status == 1) {
                if (x >= 0 && x <= chessView.Board_width && y >= 0 && y <= chessView.Board_height) {
                    chessInfo.Select = getPos(event);
                    Pos realPos = Rule.reversePos(new Pos(chessInfo.Select[0], chessInfo.Select[1]), chessInfo.IsReverse);
                    int i = realPos.x, j = realPos.y;

                    if (i >= 0 && i <= 8 && j >= 0 && j <= 9) {
                        if (chessInfo.IsRedGo == true && setting.isPlayerRed == true) {
                            if (chessInfo.IsChecked == false) {
                                if (chessInfo.piece[j][i] >= 8 && chessInfo.piece[j][i] <= 14) {
                                    chessInfo.prePos = new Pos(i, j);
                                    chessInfo.IsChecked = true;
                                    chessInfo.ret = Rule.PossibleMoves(chessInfo.piece, i, j, chessInfo.piece[j][i]);
                                    playEffect(selectMusic);
                                }
                            } else {
                                if (chessInfo.piece[j][i] >= 8 && chessInfo.piece[j][i] <= 14) {
                                    chessInfo.prePos = new Pos(i, j);
                                    chessInfo.ret = Rule.PossibleMoves(chessInfo.piece, i, j, chessInfo.piece[j][i]);
                                    playEffect(selectMusic);
                                } else if (chessInfo.ret.contains(new Pos(i, j))) {
                                    int tmp = chessInfo.piece[j][i];
                                    chessInfo.piece[j][i] = chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x];
                                    chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x] = 0;
                                    if (Rule.isKingDanger(chessInfo.piece, true)) {
                                        chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x] = chessInfo.piece[j][i];
                                        chessInfo.piece[j][i] = tmp;
                                        Toast toast = Toast.makeText(PvMActivity.this, "帅被将军", Toast.LENGTH_SHORT);
                                        toast.setGravity(Gravity.CENTER, 0, 0);
                                        toast.show();
                                    } else {
                                        chessInfo.IsChecked = false;
                                        chessInfo.IsRedGo = false;
                                        chessInfo.curPos = new Pos(i, j);

                                        chessInfo.updateAllInfo(chessInfo.prePos, chessInfo.curPos, chessInfo.piece[j][i], tmp);

                                        try {
                                            infoSet.pushInfo(chessInfo);
                                        } catch (CloneNotSupportedException e) {
                                            e.printStackTrace();
                                        }
                                        playEffect(clickMusic);
                                        int key = 0;
                                        if (Rule.isKingDanger(chessInfo.piece, false)) {
                                            key = 1;
                                        }
                                        if (Rule.isDead(chessInfo.piece, false)) {
                                            key = 2;
                                        }
                                        if (key == 1) {
                                            playEffect(checkMusic);
                                            Toast toast = Toast.makeText(PvMActivity.this, "将军", Toast.LENGTH_SHORT);
                                            toast.setGravity(Gravity.CENTER, 0, 0);
                                            toast.show();
                                        } else if (key == 2) {
                                            playEffect(winMusic);
                                            chessInfo.status = 2;
                                            Toast toast = Toast.makeText(PvMActivity.this, "红方获得胜利", Toast.LENGTH_SHORT);
                                            toast.setGravity(Gravity.CENTER, 0, 0);
                                            toast.show();
                                        }

                                        if (chessInfo.status == 1) {
                                            if (chessInfo.peaceRound >= 60) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "双方60回合内未吃子,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            } else if (chessInfo.attackNum_B == 0 && chessInfo.attackNum_R == 0) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "双方都无攻击性棋子,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            } else if (infoSet.ZobristInfo.get(chessInfo.ZobristKeyCheck) >= 4) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "重复局面出现4次,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            }
                                        }

                                        AIThread = new Thread(new Runnable() {
                                            @Override
                                            public void run() {
                                                try {
                                                    Thread.sleep(400);
                                                } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                                }

                                                chessInfo.isMachine = true;

                                                AIMove(chessInfo.IsRedGo, chessInfo.status);
                                            }
                                        });
                                        AIThread.start();
                                    }
                                }
                            }
                        } else if (chessInfo.IsRedGo == false && setting.isPlayerRed == false) {
                            if (chessInfo.IsChecked == false) {
                                if (chessInfo.piece[j][i] >= 1 && chessInfo.piece[j][i] <= 7) {
                                    chessInfo.prePos = new Pos(i, j);
                                    chessInfo.IsChecked = true;
                                    chessInfo.ret = Rule.PossibleMoves(chessInfo.piece, i, j, chessInfo.piece[j][i]);
                                    playEffect(selectMusic);
                                }
                            } else {
                                if (chessInfo.piece[j][i] >= 1 && chessInfo.piece[j][i] <= 7) {
                                    chessInfo.prePos = new Pos(i, j);
                                    chessInfo.ret = Rule.PossibleMoves(chessInfo.piece, i, j, chessInfo.piece[j][i]);
                                    playEffect(selectMusic);
                                } else if (chessInfo.ret.contains(new Pos(i, j))) {
                                    int tmp = chessInfo.piece[j][i];
                                    chessInfo.piece[j][i] = chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x];
                                    chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x] = 0;
                                    if (Rule.isKingDanger(chessInfo.piece, false)) {
                                        chessInfo.piece[chessInfo.prePos.y][chessInfo.prePos.x] = chessInfo.piece[j][i];
                                        chessInfo.piece[j][i] = tmp;
                                        Toast toast = Toast.makeText(PvMActivity.this, "将被将军", Toast.LENGTH_SHORT);
                                        toast.setGravity(Gravity.CENTER, 0, 0);
                                        toast.show();
                                    } else {
                                        chessInfo.IsChecked = false;
                                        chessInfo.IsRedGo = true;
                                        chessInfo.curPos = new Pos(i, j);

                                        chessInfo.updateAllInfo(chessInfo.prePos, chessInfo.curPos, chessInfo.piece[j][i], tmp);

                                        try {
                                            infoSet.pushInfo(chessInfo);
                                        } catch (CloneNotSupportedException e) {
                                            e.printStackTrace();
                                        }
                                        playEffect(clickMusic);
                                        int key = 0;
                                        if (Rule.isKingDanger(chessInfo.piece, true)) {
                                            key = 1;
                                        }
                                        if (Rule.isDead(chessInfo.piece, true)) {
                                            key = 2;
                                        }
                                        if (key == 1) {
                                            playEffect(checkMusic);
                                            Toast toast = Toast.makeText(PvMActivity.this, "将军", Toast.LENGTH_SHORT);
                                            toast.setGravity(Gravity.CENTER, 0, 0);
                                            toast.show();
                                            try {
                                                Thread.sleep(1000);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        } else if (key == 2) {
                                            playEffect(winMusic);
                                            chessInfo.status = 2;
                                            Toast toast = Toast.makeText(PvMActivity.this, "黑方获得胜利", Toast.LENGTH_SHORT);
                                            toast.setGravity(Gravity.CENTER, 0, 0);
                                            toast.show();
                                        }

                                        if (chessInfo.status == 1) {
                                            if (chessInfo.peaceRound >= 60) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "双方60回合内未吃子,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            } else if (chessInfo.attackNum_B == 0 && chessInfo.attackNum_R == 0) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "双方都无攻击性棋子,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            } else if (infoSet.ZobristInfo.get(chessInfo.ZobristKeyCheck) >= 4) {
                                                chessInfo.status = 2;
                                                Toast toast = Toast.makeText(PvMActivity.this, "重复局面出现4次,此乃和棋", Toast.LENGTH_SHORT);
                                                toast.setGravity(Gravity.CENTER, 0, 0);
                                                toast.show();
                                            }
                                        }

                                        AIThread = new Thread(new Runnable() {
                                            @Override
                                            public void run() {
                                                try {
                                                    Thread.sleep(400);
                                                } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                                }

                                                chessInfo.isMachine = true;

                                                AIMove(chessInfo.IsRedGo, chessInfo.status);
                                            }
                                        });
                                        AIThread.start();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public int[] getPos(MotionEvent e) {
        int[] pos = new int[2];
        double x = e.getX();
        double y = e.getY();
        int[] dis = new int[]{
                chessView.Scale(3), chessView.Scale(41), chessView.Scale(80), chessView.Scale(85)
        };
        x = x - dis[0];
        y = y - dis[1];
        if (x % dis[3] <= dis[2] && y % dis[3] <= dis[2]) {
            pos[0] = (int) Math.floor(x / dis[3]);
            pos[1] = (int) Math.floor(y / dis[3]);
            if (pos[0] >= 9 || pos[1] >= 10) {
                pos[0] = pos[1] = -1;
            }
        } else {
            pos[0] = pos[1] = -1;
        }
        return pos;
    }

    @Override
    public void onClick(View view) {
        lastClickTime = System.currentTimeMillis();
        if (lastClickTime - curClickTime < MIN_CLICK_DELAY_TIME) {
            return;
        }
        curClickTime = lastClickTime;

        playEffect(selectMusic);
        switch (view.getId()) {
            case R.id.btn_retry:
                if (chessInfo.isMachine == true && chessInfo.status == 1) {
                    Toast toast = Toast.makeText(PvMActivity.this, "请等待电脑思考", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    break;
                }
                final RetryDialog retryDialog = new RetryDialog(this);
                retryDialog.setOnClickBottomListener(new RetryDialog.OnClickBottomListener() {

                    @Override
                    public void onPositiveClick() {
                        playEffect(selectMusic);
                        try {
                            chessInfo.setInfo(new ChessInfo());
                            infoSet.newInfo();
                            transformTable.transformInfos.clear();
                        } catch (CloneNotSupportedException e) {
                            e.printStackTrace();
                        }
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        if (setting.isPlayerRed != retryDialog.isPlayerRed) {
                            setting.isPlayerRed = retryDialog.isPlayerRed;
                            editor.putBoolean("isPlayerRed", retryDialog.isPlayerRed);
                            editor.commit();
                        }
                        retryDialog.dismiss();
                        chessInfo.IsReverse = (setting.isPlayerRed == true) ? false : true;
                        if (chessInfo.IsReverse == true) {
                            try {
                                infoSet.curInfo.setInfo(chessInfo);
                            } catch (CloneNotSupportedException e) {
                                e.printStackTrace();
                            }
                        }
                        if (setting.isPlayerRed == false) {
                            try {
                                Thread.sleep(400);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            AIFirstGo();
                        }
                    }

                    @Override
                    public void onNegtiveClick() {
                        playEffect(selectMusic);
                        retryDialog.dismiss();
                    }
                });
                retryDialog.show();
                break;
            case R.id.btn_recall:
                if (chessInfo.isMachine == true && chessInfo.status == 1) {
                    Toast toast = Toast.makeText(PvMActivity.this, "请等待电脑思考", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    break;
                }
                int cnt = 0;
                int total = 2;
                if (chessInfo.status == 2 && chessInfo.isMachine == true) {
                    total = 1;
                }
                if (infoSet.preInfo.size() < total) {
                    break;
                }
                while (!infoSet.preInfo.empty()) {
                    ChessInfo tmp = infoSet.preInfo.pop();
                    cnt++;
                    try {
                        infoSet.recallZobristInfo(chessInfo.ZobristKeyCheck);
                        chessInfo.setInfo(tmp);
                        infoSet.curInfo.setInfo(tmp);
                    } catch (CloneNotSupportedException e) {
                        e.printStackTrace();
                    }
                    if (cnt >= total) {
                        break;
                    }
                }
                break;
            case R.id.btn_setting:
                final SettingDialog_PvM settingDialog_pvm = new SettingDialog_PvM(this);
                settingDialog_pvm.setOnClickBottomListener(new SettingDialog_PvM.OnClickBottomListener() {
                    @Override
                    public void onPositiveClick() {
                        playEffect(selectMusic);
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        boolean flag = false;
                        if (setting.isMusicPlay != settingDialog_pvm.isMusicPlay) {
                            setting.isMusicPlay = settingDialog_pvm.isMusicPlay;
                            if (setting.isMusicPlay) {
                                playMusic(backMusic);
                            } else {
                                stopMusic(backMusic);
                            }
                            editor.putBoolean("isMusicPlay", settingDialog_pvm.isMusicPlay);
                            flag = true;
                        }
                        if (setting.isEffectPlay != settingDialog_pvm.isEffectPlay) {
                            setting.isEffectPlay = settingDialog_pvm.isEffectPlay;
                            editor.putBoolean("isEffectPlay", settingDialog_pvm.isEffectPlay);
                            flag = true;
                        }
                        if (setting.mLevel != settingDialog_pvm.mLevel) {
                            setting.mLevel = settingDialog_pvm.mLevel;
                            editor.putInt("mLevel", settingDialog_pvm.mLevel);
                            flag = true;
                        }
                        if (flag) {
                            editor.commit();
                        }
                        settingDialog_pvm.dismiss();
                    }

                    @Override
                    public void onNegtiveClick() {
                        playEffect(selectMusic);
                        settingDialog_pvm.dismiss();
                    }
                });
                settingDialog_pvm.show();
                break;
            case R.id.btn_back:
                final CommonDialog backDialog = new CommonDialog(this, "返回", "确认要返回吗");
                backDialog.setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {

                    @Override
                    public void onPositiveClick() {
                        playEffect(selectMusic);
                        backDialog.dismiss();
                        finish();
                    }

                    @Override
                    public void onNegtiveClick() {
                        playEffect(selectMusic);
                        backDialog.dismiss();
                    }
                });
                backDialog.show();
                break;
            default:
                break;
        }
    }

    public void AIMove(boolean isRed, int status) {
        if (status != 1) return;
        int depth = setting.mLevel * 2;
        if (isRed == true) {
            // AI获取最佳走法
            Move move = knowledgeBase.readBestMoves(chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, depth);
            if (move == null) {
                long t1 = System.currentTimeMillis();
                move = getBestMove(chessInfo.piece, true, depth, chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, infoSet.ZobristInfo);
                long t2 = System.currentTimeMillis();
                Log.i("AI思考", "AI思考的时间:" + String.valueOf(t2 - t1) + "ms");
                knowledgeBase.saveBestMove(chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, depth, move);
            }

            Pos fromPos = move.fromPos;
            Pos toPos = move.toPos;
            int tmp = chessInfo.piece[toPos.y][toPos.x];
            chessInfo.piece[toPos.y][toPos.x] = chessInfo.piece[fromPos.y][fromPos.x];
            chessInfo.piece[fromPos.y][fromPos.x] = 0;
            chessInfo.IsChecked = false;
            chessInfo.IsRedGo = false;
            chessInfo.Select = new int[]{-1, -1};
            chessInfo.ret.clear();
            chessInfo.prePos = new Pos(fromPos.x, fromPos.y);
            chessInfo.curPos = new Pos(toPos.x, toPos.y);

            chessInfo.updateAllInfo(chessInfo.prePos, chessInfo.curPos, chessInfo.piece[toPos.y][toPos.x], tmp);
            chessInfo.isMachine = false;

            try {
                infoSet.pushInfo(chessInfo);
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }

            playEffect(clickMusic);

            int key = 0;
            if (Rule.isKingDanger(chessInfo.piece, false)) {
                key = 1;
            }
            if (Rule.isDead(chessInfo.piece, false)) {
                key = 2;
            }
            if (key == 1) {
                playEffect(checkMusic);
                Looper.prepare();
                Toast toast = Toast.makeText(PvMActivity.this, "将军", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                Looper.loop();
            } else if (key == 2) {
                playEffect(winMusic);
                chessInfo.status = 2;
                Looper.prepare();
                Toast toast = Toast.makeText(PvMActivity.this, "红方获得胜利", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                Looper.loop();
            }

            if (chessInfo.status == 1) {
                if (chessInfo.peaceRound >= 60) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "双方60回合内未吃子,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                } else if (chessInfo.attackNum_B == 0 && chessInfo.attackNum_R == 0) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "双方都无攻击性棋子,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                } else if (infoSet.ZobristInfo.get(chessInfo.ZobristKeyCheck) >= 4) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "重复局面出现4次,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                }
            }
        } else {
            Move move = knowledgeBase.readBestMoves(chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, depth);
            if (move == null) {
                long t1 = System.currentTimeMillis();
                move = getBestMove(chessInfo.piece, false, depth, chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, infoSet.ZobristInfo);
                long t2 = System.currentTimeMillis();
                Log.i("AI思考", "AI思考的时间:" + String.valueOf(t2 - t1) + "ms");
                knowledgeBase.saveBestMove(chessInfo.ZobristKey, chessInfo.ZobristKeyCheck, depth, move);
            }

            Pos fromPos = move.fromPos;
            Pos toPos = move.toPos;
            int tmp = chessInfo.piece[toPos.y][toPos.x];
            chessInfo.piece[toPos.y][toPos.x] = chessInfo.piece[fromPos.y][fromPos.x];
            chessInfo.piece[fromPos.y][fromPos.x] = 0;
            chessInfo.IsChecked = false;
            chessInfo.IsRedGo = true;
            chessInfo.Select = new int[]{-1, -1};
            chessInfo.ret.clear();
            chessInfo.prePos = new Pos(fromPos.x, fromPos.y);
            chessInfo.curPos = new Pos(toPos.x, toPos.y);

            chessInfo.updateAllInfo(chessInfo.prePos, chessInfo.curPos, chessInfo.piece[toPos.y][toPos.x], tmp);
            chessInfo.isMachine = false;

            try {
                infoSet.pushInfo(chessInfo);
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }

            playEffect(clickMusic);

            int key = 0;
            if (Rule.isKingDanger(chessInfo.piece, true)) {
                key = 1;
            }
            if (Rule.isDead(chessInfo.piece, true)) {
                key = 2;
            }
            if (key == 1) {
                playEffect(checkMusic);
                Looper.prepare();
                Toast toast = Toast.makeText(PvMActivity.this, "将军", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                Looper.loop();
            } else if (key == 2) {
                playEffect(winMusic);
                chessInfo.status = 2;
                Looper.prepare();
                Toast toast = Toast.makeText(PvMActivity.this, "黑方获得胜利", Toast.LENGTH_SHORT);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                Looper.loop();
            }

            if (chessInfo.status == 1) {
                if (chessInfo.peaceRound >= 60) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "双方60回合内未吃子,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                } else if (chessInfo.attackNum_B == 0 && chessInfo.attackNum_R == 0) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "双方都无攻击性棋子,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                } else if (infoSet.ZobristInfo.get(chessInfo.ZobristKeyCheck) >= 4) {
                    chessInfo.status = 2;
                    Looper.prepare();
                    Toast toast = Toast.makeText(PvMActivity.this, "重复局面出现4次,此乃和棋", Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    Looper.loop();
                }
            }
        }
    }

    public void AIFirstGo() {
        Move[] firstMoves = new Move[8];
        firstMoves[0] = new Move(new Pos(1, 9), new Pos(2, 7));     //走马
        firstMoves[1] = new Move(new Pos(7, 9), new Pos(6, 7));     //走马
        firstMoves[2] = new Move(new Pos(2, 9), new Pos(4, 7));     //走相
        firstMoves[3] = new Move(new Pos(6, 9), new Pos(4, 7));     //走相
        firstMoves[4] = new Move(new Pos(1, 7), new Pos(4, 7));     //走炮
        firstMoves[5] = new Move(new Pos(7, 7), new Pos(4, 7));     //走炮
        firstMoves[6] = new Move(new Pos(2, 6), new Pos(2, 5));     //走兵
        firstMoves[7] = new Move(new Pos(6, 6), new Pos(6, 5));     //走兵

        int num = (int) (Math.random() * firstMoves.length);
        //Log.e("chen",String.valueOf(num));
        Move firstMove = firstMoves[num];
        Pos fromPos = firstMove.fromPos;
        Pos toPos = firstMove.toPos;
        int tmp = chessInfo.piece[toPos.y][toPos.x];
        chessInfo.piece[toPos.y][toPos.x] = chessInfo.piece[fromPos.y][fromPos.x];
        chessInfo.piece[fromPos.y][fromPos.x] = 0;
        chessInfo.IsChecked = false;
        chessInfo.IsRedGo = false;
        chessInfo.Select = new int[]{-1, -1};
        chessInfo.ret.clear();
        chessInfo.prePos = new Pos(fromPos.x, fromPos.y);
        chessInfo.curPos = new Pos(toPos.x, toPos.y);

        chessInfo.updateAllInfo(chessInfo.prePos, chessInfo.curPos, chessInfo.piece[toPos.y][toPos.x], tmp);

        try {
            infoSet.pushInfo(chessInfo);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        playEffect(clickMusic);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            final CommonDialog backDialog = new CommonDialog(this, "返回", "确认要返回吗");
            backDialog.setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {

                @Override
                public void onPositiveClick() {
                    playEffect(selectMusic);
                    backDialog.dismiss();
                    finish();
                }

                @Override
                public void onNegtiveClick() {
                    playEffect(selectMusic);
                    backDialog.dismiss();
                }
            });
            backDialog.show();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onPause() {
        stopMusic(backMusic);
        super.onPause();
    }

    @Override
    protected void onStop() {
       /* try {
            SaveInfo.SerializeChessInfo(chessInfo, "ChessInfo_pvm.bin");
            SaveInfo.SerializeInfoSet(infoSet, "InfoSet_pvm.bin");
            SaveInfo.SerializeKnowledgeBase(knowledgeBase, "KnowledgeBase.bin");
            SaveInfo.SerializeTransformTable(transformTable, "TransformTable.bin");
        } catch (Exception e) {
            Log.e("chen", e.toString());
        }*/
        super.onStop();
    }

    @Override
    protected void onStart() {
        playMusic(backMusic);
        if (chessInfo.isMachine) {
            if (AIThread.isAlive() == false) {
                AIThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        AIMove(chessInfo.IsRedGo, chessInfo.status);
                    }
                });
                AIThread.start();
            }
        }
        super.onStart();
    }

}

规则类 Rule.java


import android.util.Log;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import Info.Pos;

public class Rule {
    public static int[][] area = new int[][]{
            {1, 1, 1, 2, 2, 2, 1, 1, 1},
            {1, 1, 1, 2, 2, 2, 1, 1, 1},
            {1, 1, 1, 2, 2, 2, 1, 1, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1},

            {3, 3, 3, 3, 3, 3, 3, 3, 3},
            {3, 3, 3, 3, 3, 3, 3, 3, 3},
            {3, 3, 3, 4, 4, 4, 3, 3, 3},
            {3, 3, 3, 4, 4, 4, 3, 3, 3},
            {3, 3, 3, 4, 4, 4, 3, 3, 3},
    };
    //走棋规则
    public static int[][] offsetX = new int[][]{
            {0, 0, 1, -1},             //帅 将
            {1, 1, -1, -1},            //仕 士
            {2, 2, -2, -2},            //相 象
            {1, 1, -1, -1},            //象眼
            {1, 1, -1, -1, 2, 2, -2, -2},  //马
            {0, 0, 0, 0, 1, 1, -1, -1},    //蹩马腿
            {0},                    //卒
            {-1, 0, 1},               //过河卒
            {0},                    //兵
            {-1, 0, 1},               //过河兵
            {1, 1, -1, -1, 1, 1, -1, -1},  //反向蹩马腿
    };
    public static int[][] offsetY = new int[][]{
            {1, -1, 0, 0},             //帅 将
            {1, -1, 1, -1},            //仕 士
            {2, -2, 2, -2},            //相 象
            {1, -1, 1, -1},            //象眼
            {2, -2, 2, -2, 1, -1, 1, -1},  //马
            {1, -1, 1, -1, 0, 0, 0, 0},    //蹩马腿
            {1},                    //卒
            {0, 1, 0},                //过河卒
            {-1},                   //兵
            {0, -1, 0},               //过河兵
            {1, -1, 1, -1, 1, -1, 1, -1},  //反向蹩马腿
    };

    //生成某个位置的棋子的所有可能走法的位置
    public static List<Pos> PossibleMoves(int[][] piece, int fromX, int fromY, int PieceID) {
        List<Pos> ret = new ArrayList<Pos>();
        int num;
        switch (PieceID) {
            case 1://黑将
                num = 0;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    if (InArea(toX, toY) == 2 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                Pos eatPos1 = flyKing(1, fromX, fromY, piece);
                if (eatPos1.equals(new Pos(-1, -1)) == false) {
                    ret.add(eatPos1);
                }
                break;
            case 2://黑士
                num = 1;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    if (InArea(toX, toY) == 2 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                break;
            case 3://黑象
                num = 2;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    int blockX = fromX + offsetX[num + 1][i];
                    int blockY = fromY + offsetY[num + 1][i];
                    if (InArea(toX, toY) >= 1 && InArea(toX, toY) <= 2 && IsSameSide(PieceID, piece[toY][toX]) == false && piece[blockY][blockX] == 0) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                break;
            case 4://黑马
            case 11://红马
                num = 4;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    int blockX = fromX + offsetX[num + 1][i];
                    int blockY = fromY + offsetY[num + 1][i];
                    if (InArea(toX, toY) != 0 && IsSameSide(PieceID, piece[toY][toX]) == false && piece[blockY][blockX] == 0) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                break;
            case 5://黑车
            case 12: //红车
                for (int i = fromY + 1; i < 10; i++) {//向下走
                    if (CanMove(1, fromX, fromY, fromX, i, piece)) { //可以走时
                        ret.add(new Pos(fromX, i));
                    } else {//不可以走时直接 break
                        break;
                    }
                }
                for (int i = fromY - 1; i > -1; i--) {//向上走
                    if (CanMove(1, fromX, fromY, fromX, i, piece)) {//可以走时
                        ret.add(new Pos(fromX, i));
                    } else {//不可以走时
                        break;
                    }
                }
                for (int j = fromX - 1; j > -1; j--) {//向走走
                    if (CanMove(1, fromX, fromY, j, fromY, piece)) {//可以走时
                        ret.add(new Pos(j, fromY));
                    } else {//不可以走时
                        break;
                    }
                }
                for (int j = fromX + 1; j < 9; j++) {//向右走
                    if (CanMove(1, fromX, fromY, j, fromY, piece)) {//可以走时
                        ret.add(new Pos(j, fromY));
                    } else {//不可以走时
                        break;
                    }
                }
                /*for (int i = 0; i < 9; i++) {
                    for (int j = 0; j < 10; j++) {
                        if (i != fromX || j != fromY) {
                            if (CanMove(1, fromX, fromY, i, j, piece)) {
                                ret.add(new Pos(i, j));
                            }
                        }
                    }
                }*/
                break;
            case 6://黑炮
            case 13://红炮
                for (int i = fromY + 1; i < 10; i++) {//向下走
                    if (CanMove(2, fromX, fromY, fromX, i, piece)) { //可以走时
                        ret.add(new Pos(fromX, i));
                    }
                }
                for (int i = fromY - 1; i > -1; i--) {//向上走
                    if (CanMove(2, fromX, fromY, fromX, i, piece)) {//可以走时
                        ret.add(new Pos(fromX, i));
                    }
                }
                for (int j = fromX - 1; j > -1; j--) {//向走走
                    if (CanMove(2, fromX, fromY, j, fromY, piece)) {//可以走时
                        ret.add(new Pos(j, fromY));
                    }
                }
                for (int j = fromX + 1; j < 9; j++) {//向右走
                    if (CanMove(2, fromX, fromY, j, fromY, piece)) {//可以走时
                        ret.add(new Pos(j, fromY));
                    }
                }

                /*for (int i = 0; i < 9; i++) {
                    for (int j = 0; j < 10; j++) {
                        if (i != fromX || j != fromY) {
                            if (CanMove(2, fromX, fromY, i, j, piece)) {
                                ret.add(new Pos(i, j));
                            }
                        }
                    }
                }*/
                break;
            case 7://黑卒
                if (InArea(fromX, fromY) == 1) {
                    num = 6;
                    for (int i = 0; i < offsetX[num].length; i++) {
                        int toX = fromX + offsetX[num][i];
                        int toY = fromY + offsetY[num][i];
                        if (InArea(toX, toY) != 0 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                            ret.add(new Pos(toX, toY));
                        }
                    }
                } else {
                    num = 7;
                    for (int i = 0; i < offsetX[num].length; i++) {
                        int toX = fromX + offsetX[num][i];
                        int toY = fromY + offsetY[num][i];
                        if (InArea(toX, toY) != 0 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                            ret.add(new Pos(toX, toY));
                        }
                    }
                }
                break;
            case 8://红帅
                num = 0;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    if (InArea(toX, toY) == 4 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                Pos eatPos2 = flyKing(2, fromX, fromY, piece);
                if (eatPos2.equals(new Pos(-1, -1)) == false) {
                    ret.add(eatPos2);
                }
                break;
            case 9://红士
                num = 1;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    if (InArea(toX, toY) == 4 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                break;
            case 10://红象
                num = 2;
                for (int i = 0; i < offsetX[num].length; i++) {
                    int toX = fromX + offsetX[num][i];
                    int toY = fromY + offsetY[num][i];
                    int blockX = fromX + offsetX[num + 1][i];
                    int blockY = fromY + offsetY[num + 1][i];
                    if (InArea(toX, toY) >= 3 && InArea(toX, toY) <= 4 && IsSameSide(PieceID, piece[toY][toX]) == false && piece[blockY][blockX] == 0) {
                        ret.add(new Pos(toX, toY));
                    }
                }
                break;
            case 14://红兵
                if (InArea(fromX, fromY) == 3) {
                    num = 8;
                    for (int i = 0; i < offsetX[num].length; i++) {
                        int toX = fromX + offsetX[num][i];
                        int toY = fromY + offsetY[num][i];
                        if (InArea(toX, toY) != 0 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                            ret.add(new Pos(toX, toY));
                        }
                    }
                } else {
                    num = 9;
                    for (int i = 0; i < offsetX[num].length; i++) {
                        int toX = fromX + offsetX[num][i];
                        int toY = fromY + offsetY[num][i];
                        if (InArea(toX, toY) != 0 && IsSameSide(PieceID, piece[toY][toX]) == false) {
                            ret.add(new Pos(toX, toY));
                        }
                    }
                }
                break;
            default:
                break;
        }
        return ret;
    }

    //判断将、帅是否已经被将军
    public static boolean isKingDanger(int[][] piece, boolean isRedKing) {
        int num = 4;
        int op_block_num = 10;
        if (isRedKing == true) {
            int x = 0, y = 0;
            boolean flag = false;
            for (y = 7; y <= 9; y++) {
                for (x = 3; x <= 5; x++) {
                    if (piece[y][x] == 8) {
                        flag = true;
                        break;
                    }
                }
                if (flag) break;
            }

            for (int i = 0; i < offsetX[num].length; i++) {     //马
                int toX = x + offsetX[num][i];
                int toY = y + offsetY[num][i];
                int blockX = x + offsetX[op_block_num][i];
                int blockY = y + offsetY[op_block_num][i];
                if (InArea(toX, toY) != 0 && piece[toY][toX] == 4 && piece[blockY][blockX] == 0) {
                    return true;
                }
            }
            for (int i = 5; i <= 6; i++) {  //车 炮
                List<Pos> moves = PossibleMoves(piece, x, y, i + 7);
                Iterator<Pos> it = moves.iterator();
                while (it.hasNext()) {
                    Pos pos = it.next();
                    if (piece[pos.y][pos.x] == i) {
                        return true;
                    }
                }
            }
            if (flyKing(2, x, y, piece).equals(new Pos(-1, -1)) == false) { //将
                return true;
            }
            if (piece[y - 1][x] == 7 || piece[y][x - 1] == 7 || piece[y][x + 1] == 7) {
                return true;
            }
        } else {
            int x = 0, y = 0;
            boolean flag = false;
            for (y = 0; y <= 2; y++) {
                for (x = 3; x <= 5; x++) {
                    if (piece[y][x] == 1) {
                        flag = true;
                        break;
                    }
                }
                if (flag) break;
            }

            for (int i = 0; i < offsetX[num].length; i++) {     //马
                int toX = x + offsetX[num][i];
                int toY = y + offsetY[num][i];
                int blockX = x + offsetX[op_block_num][i];
                int blockY = y + offsetY[op_block_num][i];
                if (InArea(toX, toY) != 0 && piece[toY][toX] == 11 && piece[blockY][blockX] == 0) {
                    return true;
                }
            }
            for (int i = 12; i <= 13; i++) {  //车 炮
                List<Pos> moves = PossibleMoves(piece, x, y, i - 7);
                Iterator<Pos> it = moves.iterator();
                while (it.hasNext()) {
                    Pos pos = it.next();
                    if (piece[pos.y][pos.x] == i) {
                        return true;
                    }
                }
            }
            if (flyKing(1, x, y, piece).equals(new Pos(-1, -1)) == false) { //将
                return true;
            }
            if (piece[y + 1][x] == 14 || piece[y][x - 1] == 14 || piece[y][x + 1] == 14) {
                return true;
            }
        }
        return false;
    }

    //判断将、帅是否已经被将军
    public static boolean isDead(int[][] piece, boolean isRedKing) {
        if (isRedKing == true) {
            for (int i = 0; i <= 9; i++) {
                for (int j = 0; j <= 8; j++) {
                    if (piece[i][j] >= 8 && piece[i][j] <= 14) {
                        List<Pos> moves = PossibleMoves(piece, j, i, piece[i][j]);
                        Iterator<Pos> it = moves.iterator();
                        while (it.hasNext()) {
                            Pos pos = it.next();
                            int tmp = piece[pos.y][pos.x];
                            if (tmp == 1) {
                                return false;
                            }
                            piece[pos.y][pos.x] = piece[i][j];
                            piece[i][j] = 0;
                            if (isKingDanger(piece, true) == false) {
                                piece[i][j] = piece[pos.y][pos.x];
                                piece[pos.y][pos.x] = tmp;
                                return false;
                            }
                            piece[i][j] = piece[pos.y][pos.x];
                            piece[pos.y][pos.x] = tmp;
                        }
                    }
                }
            }
        } else {
            for (int i = 0; i <= 9; i++) {
                for (int j = 0; j <= 8; j++) {
                    if (piece[i][j] >= 1 && piece[i][j] <= 7) {
                        List<Pos> moves = PossibleMoves(piece, j, i, piece[i][j]);
                        Iterator<Pos> it = moves.iterator();
                        while (it.hasNext()) {
                            Pos pos = it.next();
                            int tmp = piece[pos.y][pos.x];
                            if (tmp == 8) {
                                return false;
                            }
                            piece[pos.y][pos.x] = piece[i][j];
                            piece[i][j] = 0;
                            if (isKingDanger(piece, false) == false) {
                                piece[i][j] = piece[pos.y][pos.x];
                                piece[pos.y][pos.x] = tmp;
                                return false;
                            }
                            piece[i][j] = piece[pos.y][pos.x];
                            piece[pos.y][pos.x] = tmp;
                        }
                    }
                }
            }
        }
        return true;
    }

    //0 棋盘外 1 黑盘 2 黑十字(九宫) 3 红盘 4 红十字(九宫)
    public static int InArea(int x, int y) {
        if (x < 0 || x > 8 || y < 0 || y > 9) {
            return 0;
        }
        return area[y][x];
    }

    //判断棋子是否为同一方
    public static boolean IsSameSide(int fromID, int toID) {
        if (toID == 0) {
            return false;
        }
        if ((fromID <= 7 && toID <= 7) || (fromID >= 8 && toID >= 8)) {
            return true;
        } else {
            return false;
        }
    }

    //判断将、帅是否见面
    public static Pos flyKing(int id, int fromX, int fromY, int[][] piece) {
        int cnt = 0;
        boolean flag = false;
        int i;
        if (id == 1) {  //将
            for (i = fromY + 1; i <= 9; i++) {
                if (piece[i][fromX] > 0 && piece[i][fromX] != 8) {
                    cnt++;
                } else if (piece[i][fromX] == 8) {
                    flag = true;
                    break;
                }
            }
        } else {       //帅
            for (i = fromY - 1; i >= 0; i--) {
                if (piece[i][fromX] > 0 && piece[i][fromX] != 1) {
                    cnt++;
                } else if (piece[i][fromX] == 1) {
                    flag = true;
                    break;
                }
            }
        }
        if (cnt == 0 && flag == true) {
            return new Pos(fromX, i);
        } else {
            return new Pos(-1, -1);
        }
    }

    //判断是否可以移动
    public static boolean CanMove(int id, int fromX, int fromY, int toX, int toY, int[][] piece) {
        if (fromX == 10 || fromY == 10 || toX == 10 || toY == 10) {
            Log.e("chen", String.valueOf(fromX) + " " + String.valueOf(fromY) + " " + String.valueOf(toX) + " " + String.valueOf(toY));
        }
        if ((fromX != toX && fromY != toY) || IsSameSide(piece[fromY][fromX], piece[toY][toX]) == true) {
            return false;
        }
        if (id == 1) {  //车
            int start, finish;
            if (fromX == toX) {
                if (fromY < toY) {
                    start = fromY + 1;
                    finish = toY;
                } else {
                    start = toY + 1;
                    finish = fromY;
                }
                for (int i = start; i < finish; i++) {
                    if (piece[i][fromX] != 0) {
                        return false;
                    }
                }
            } else {
                if (fromX < toX) {
                    start = fromX + 1;
                    finish = toX;
                } else {
                    start = toX + 1;
                    finish = fromX;
                }
                for (int i = start; i < finish; i++) {
                    if (piece[fromY][i] != 0) {
                        return false;
                    }
                }
            }
        } else {   //炮
            if (piece[toY][toX] == 0) {
                int start, finish;
                if (fromX == toX) {
                    if (fromY < toY) {
                        start = fromY + 1;
                        finish = toY;
                    } else {
                        start = toY + 1;
                        finish = fromY;
                    }
                    for (int i = start; i < finish; i++) {
                        if (piece[i][fromX] != 0) {
                            return false;
                        }
                    }
                } else {
                    if (fromX < toX) {
                        start = fromX + 1;
                        finish = toX;
                    } else {
                        start = toX + 1;
                        finish = fromX;
                    }
                    for (int i = start; i < finish; i++) {
                        if (piece[fromY][i] != 0) {
                            return false;
                        }
                    }
                }
            } else {
                int start, finish;
                int count = 0;
                if (fromX == toX) {
                    if (fromY < toY) {
                        start = fromY + 1;
                        finish = toY;

                    } else {
                        start = toY + 1;
                        finish = fromY;
                    }
                    for (int i = start; i < finish; i++) {
                        if (piece[i][fromX] != 0) {
                            count++;
                        }
                    }
                } else {
                    if (fromX < toX) {
                        start = fromX + 1;
                        finish = toX;
                    } else {
                        start = toX + 1;
                        finish = fromX;
                    }
                    for (int i = start; i < finish; i++) {
                        if (piece[fromY][i] != 0) {
                            count++;
                        }
                    }
                }
                if (count != 1) {
                    return false;
                }
            }
        }
        return true;
    }

    //判断是否为红方,如果不是,则反转。
    public static Pos reversePos(Pos pos, boolean IsReverse) {
        return (IsReverse == false) ? pos : new Pos(8 - pos.x, 9 - pos.y);
    }
}

AI.java


import Info.Pos;
import ChessMove.Rule;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static com.example.a77304.chessgame.HomeActivity.zobrist;
import static com.example.a77304.chessgame.PvMActivity.transformTable;

public class AI {
    //棋子力价值表
    public static int[][][] pieceValue = new int[][][]{
            //黑将
            {
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
            },
            //黑士
            {
                    {0, 0, 0, 20, 0, 20, 0, 0, 0},
                    {0, 0, 0, 0, 23, 0, 0, 0, 0},
                    {0, 0, 0, 20, 0, 20, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
            },
            //黑象
            {
                    {0, 0, 20, 0, 0, 0, 20, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {18, 0, 0, 0, 23, 0, 0, 0, 18},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 20, 0, 0, 0, 20, 0, 0},

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
            },
            //黑马
            {
                    {88, 85, 90, 88, 90, 88, 90, 85, 88},
                    {85, 90, 92, 93, 78, 93, 92, 90, 85},
                    {93, 92, 94, 95, 92, 95, 94, 92, 93},
                    {92, 94, 98, 95, 98, 95, 98, 94, 92},
                    {90, 98, 101, 102, 103, 102, 101, 98, 90},

                    {90, 100, 99, 103, 104, 103, 99, 100, 90},
                    {93, 108, 100, 107, 100, 107, 100, 108, 93},
                    {92, 98, 99, 103, 99, 103, 99, 98, 92},
                    {90, 96, 103, 97, 94, 97, 103, 96, 90},
                    {90, 90, 90, 96, 90, 96, 90, 90, 90},
            },
            //黑车
            {
                    {194, 206, 204, 212, 200, 212, 204, 206, 194},
                    {200, 208, 206, 212, 200, 212, 206, 208, 200},
                    {198, 208, 204, 212, 212, 212, 204, 208, 198},
                    {204, 209, 204, 212, 214, 212, 204, 209, 204},
                    {208, 212, 212, 214, 215, 214, 212, 212, 208},

                    {208, 211, 211, 214, 215, 214, 211, 211, 208},
                    {206, 213, 213, 216, 216, 216, 213, 213, 206},
                    {206, 208, 207, 214, 216, 214, 207, 208, 206},
                    {206, 212, 209, 216, 233, 216, 209, 212, 206},
                    {206, 208, 207, 213, 214, 213, 207, 208, 206},
            },
            //黑炮
            {
                    {96, 96, 97, 99, 99, 99, 97, 96, 96},
                    {96, 97, 98, 98, 98, 98, 98, 97, 96},
                    {97, 96, 100, 99, 101, 99, 100, 96, 97},
                    {96, 96, 96, 96, 96, 96, 96, 96, 96},
                    {95, 96, 99, 96, 100, 96, 99, 96, 95},

                    {96, 96, 96, 96, 100, 96, 96, 96, 96},
                    {96, 99, 99, 98, 100, 98, 99, 99, 96},
                    {97, 97, 96, 91, 92, 91, 96, 97, 97},
                    {98, 98, 96, 92, 89, 92, 96, 98, 98},
                    {100, 100, 96, 91, 90, 91, 96, 100, 100},
            },
            //黑卒
            {

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {7, 0, 7, 0, 15, 0, 7, 0, 7},
                    {7, 0, 13, 0, 16, 0, 13, 0, 7},

                    {14, 18, 20, 27, 29, 27, 20, 18, 14},
                    {19, 23, 27, 29, 30, 29, 27, 23, 19},
                    {19, 24, 32, 37, 37, 37, 32, 24, 19},
                    {19, 24, 34, 42, 44, 42, 34, 24, 19},
                    {9, 9, 9, 11, 13, 11, 9, 9, 9},
            },
            //红帅
            {
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0},
                    {0, 0, 0, 8888, 8888, 8888, 0, 0, 0}
            },
            //红士
            {
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},

                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 20, 0, 20, 0, 0, 0},
                    {0, 0, 0, 0, 23, 0, 0, 0, 0},
                    {0, 0, 0, 20, 0, 20, 0, 0, 0}
            },
            //红象
            {
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},

                    {0, 0, 20, 0, 0, 0, 20, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {18, 0, 0, 0, 23, 0, 0, 0, 18},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 20, 0, 0, 0, 20, 0, 0}
            },
            //红马
            {
                    {90, 90, 90, 96, 90, 96, 90, 90, 90},
                    {90, 96, 103, 97, 94, 97, 103, 96, 90},
                    {92, 98, 99, 103, 99, 103, 99, 98, 92},
                    {93, 108, 100, 107, 100, 107, 100, 108, 93},
                    {90, 100, 99, 103, 104, 103, 99, 100, 90},

                    {90, 98, 101, 102, 103, 102, 101, 98, 90},
                    {92, 94, 98, 95, 98, 95, 98, 94, 92},
                    {93, 92, 94, 95, 92, 95, 94, 92, 93},
                    {85, 90, 92, 93, 78, 93, 92, 90, 85},
                    {88, 85, 90, 88, 90, 88, 90, 85, 88}
            },
            //红车
            {
                    {206, 208, 207, 213, 214, 213, 207, 208, 206},
                    {206, 212, 209, 216, 233, 216, 209, 212, 206},
                    {206, 208, 207, 214, 216, 214, 207, 208, 206},
                    {206, 213, 213, 216, 216, 216, 213, 213, 206},
                    {208, 211, 211, 214, 215, 214, 211, 211, 208},

                    {208, 212, 212, 214, 215, 214, 212, 212, 208},
                    {204, 209, 204, 212, 214, 212, 204, 209, 204},
                    {198, 208, 204, 212, 212, 212, 204, 208, 198},
                    {200, 208, 206, 212, 200, 212, 206, 208, 200},
                    {194, 206, 204, 212, 200, 212, 204, 206, 194}
            },
            //红炮
            {

                    {100, 100, 96, 91, 90, 91, 96, 100, 100},
                    {98, 98, 96, 92, 89, 92, 96, 98, 98},
                    {97, 97, 96, 91, 92, 91, 96, 97, 97},
                    {96, 99, 99, 98, 100, 98, 99, 99, 96},
                    {96, 96, 96, 96, 100, 96, 96, 96, 96},

                    {95, 96, 99, 96, 100, 96, 99, 96, 95},
                    {96, 96, 96, 96, 96, 96, 96, 96, 96},
                    {97, 96, 100, 99, 101, 99, 100, 96, 97},
                    {96, 97, 98, 98, 98, 98, 98, 97, 96},
                    {96, 96, 97, 99, 99, 99, 97, 96, 96}
            },
            //红兵
            {
                    {9, 9, 9, 11, 13, 11, 9, 9, 9},
                    {19, 24, 34, 42, 44, 42, 34, 24, 19},
                    {19, 24, 32, 37, 37, 37, 32, 24, 19},
                    {19, 23, 27, 29, 30, 29, 27, 23, 19},
                    {14, 18, 20, 27, 29, 27, 20, 18, 14},

                    {7, 0, 13, 0, 16, 0, 13, 0, 7},
                    {7, 0, 7, 0, 15, 0, 7, 0, 7},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0},
                    {0, 0, 0, 0, 0, 0, 0, 0, 0}
            }
    };
    public static final int INF = 0x3f3f3f3f;   //正无穷大
    public static final int Win = 88888;
    public static final int hashfEXACT = 1;
    public static final int hashfALPHA = 2;
    public static final int hashfBETA = 3;
    public static boolean isMachineRed;
    public static int ZobristKey;
    public static long ZobristKeyCheck;
    public static int maxDepth;
    public static int goodValue;
    public static int[][][][] historyTable = new int[9][10][9][10];  //历史表
    public static int searchCnt = 0;

    public AI() {

    }

    //迭代加深
    public static Move getBestMove(int[][] piece, boolean isRedGo, int depth, int startZobristKey, long startZobristKeyCheck, Map<Long, Integer> ZobristInfo) {
        int[][] pieceClone = new int[10][9];
        for (int i = 0; i <= 9; i++) {
            pieceClone[i] = piece[i].clone();
        }

        searchCnt = 0;
        Move goodMove = new Move(new Pos(-1, -1), new Pos(-1, -1));
        Move bestMove = new Move(new Pos(-1, -1), new Pos(-1, -1));
        clearHistory();
        for (int i = 2; i <= depth; i += 2) {
            goodMove = getGoodMove(pieceClone, isRedGo, i, startZobristKey, startZobristKeyCheck, ZobristInfo);
            if (goodValue >= -Win / 2) {
                bestMove = goodMove;
            }
        }

        if (bestMove.fromPos.equals(new Pos(-1, -1)) == true) {
            bestMove = getLegalMove(pieceClone, isRedGo);
        }
        //Log.i("博弈树搜索算法比对","搜索结点数:"+String.valueOf(searchCnt));
        return bestMove;
    }

    //PVS+置换表+历史表
    public static Move getGoodMove(int[][] piece, boolean isRedGo, int depth, int startZobristKey, long startZobristKeyCheck, Map<Long, Integer> ZobristInfo) {
        Move goodMove = new Move(new Pos(-1, -1), new Pos(-1, -1));

        isMachineRed = isRedGo;
        boolean FoundPv = false;
        int value = -INF;
        int alpha = -INF, beta = INF;
        boolean isKingAlive = true;
        ZobristKey = startZobristKey;
        ZobristKeyCheck = startZobristKeyCheck;
        maxDepth = depth;

        LinkedList<Move> sortedMoves = allPossibleMoves(piece, isRedGo, depth, alpha, beta);
        Iterator<Move> it = sortedMoves.iterator();
        while (it.hasNext()) {
            Move move = it.next();
            Pos fromPos = move.fromPos;
            Pos toPos = move.toPos;
            int pieceID = piece[toPos.y][toPos.x];
            piece[toPos.y][toPos.x] = piece[fromPos.y][fromPos.x];
            piece[fromPos.y][fromPos.x] = 0;

            updateZobrist(fromPos, toPos, piece[toPos.y][toPos.x], pieceID);

            if (pieceID == 1 || pieceID == 8) {
                isKingAlive = false;
            }

            if (ZobristInfo.get(ZobristKeyCheck) != null) {
                value = -INF;
            } else {
                if (FoundPv) {
                    value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -alpha - 1, -alpha, isKingAlive);
                    if ((value > alpha) && (value < beta)) {
                        value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -beta, -alpha, isKingAlive);
                    }
                } else {
                    value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -beta, -alpha, isKingAlive);
                }
            }

            updateZobrist(fromPos, toPos, piece[toPos.y][toPos.x], pieceID);

            piece[fromPos.y][fromPos.x] = piece[toPos.y][toPos.x];
            piece[toPos.y][toPos.x] = pieceID;
            if (pieceID == 1 || pieceID == 8) {
                isKingAlive = true;
            }

            if (value > alpha) {
                alpha = value;
                FoundPv = true;
                goodMove = new Move(fromPos, toPos);
            }
        }
        goodValue = alpha;
        addHistory(goodMove.fromPos, goodMove.toPos, (maxDepth - depth + 1) * (maxDepth - depth + 1));
        return goodMove;
    }


    //通过算法获得最佳结果
    public static int PVS(int[][] piece, boolean isRedGo, int depth, int alpha, int beta, boolean isKingAlive) {
        int value = transformTable.readTransformTable(ZobristKey, ZobristKeyCheck, maxDepth - depth, alpha, beta);   //局面评分
        if (value != INF) {
            return value;
        }

        if (isKingAlive == false) {
            if (isMachineRed == true && isRedGo == true) {
                return -Win + (maxDepth - depth);
            } else if (isMachineRed == true && isRedGo == false) {
                return Win - (maxDepth - depth);
            } else if (isMachineRed == false && isRedGo == true) {
                return Win - (maxDepth - depth);
            } else {
                return -Win + (maxDepth - depth);
            }
        }

        if (depth <= 0) {
            searchCnt++;
            if (Rule.isDead(piece, isMachineRed)) {
                value = -Win + (maxDepth - depth + 2);
            } else {
                value = evaluate(piece);
            }
            return value;
        }

        boolean FoundPv = false;
        int hashf = hashfALPHA;
        int fatherZobristKey = ZobristKey;
        long fatherZobristKeyCheck = ZobristKeyCheck;
        value = -INF;
        Move goodMove = new Move(new Pos(-1, -1), new Pos(-1, -1));

        LinkedList<Move> sortedMoves = allPossibleMoves(piece, isRedGo, depth, alpha, beta);
        Iterator<Move> it = sortedMoves.iterator();
        while (it.hasNext()) {
            Move move = it.next();
            Pos fromPos = move.fromPos;
            Pos toPos = move.toPos;
            int pieceID = piece[toPos.y][toPos.x];
            if (maxDepth == 6 && depth == 1 && pieceID == 0) continue;

            piece[toPos.y][toPos.x] = piece[fromPos.y][fromPos.x];
            piece[fromPos.y][fromPos.x] = 0;

            updateZobrist(fromPos, toPos, piece[toPos.y][toPos.x], pieceID);

            if (pieceID == 1 || pieceID == 8) {
                isKingAlive = false;
            }

            if (FoundPv) {
                value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -alpha - 1, -alpha, isKingAlive);
                if ((value > alpha) && (value < beta)) {
                    value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -beta, -alpha, isKingAlive);
                }
            } else {
                value = -PVS(piece, (isRedGo == true) ? false : true, depth - 1, -beta, -alpha, isKingAlive);
            }

            updateZobrist(fromPos, toPos, piece[toPos.y][toPos.x], pieceID);

            piece[fromPos.y][fromPos.x] = piece[toPos.y][toPos.x];
            piece[toPos.y][toPos.x] = pieceID;
            if (pieceID == 1 || pieceID == 8) {
                isKingAlive = true;
            }

            if (value >= beta) {
                transformTable.saveTransformTable(fatherZobristKey, fatherZobristKeyCheck, maxDepth - depth, beta, hashfBETA);
                addHistory(fromPos, toPos, (maxDepth - depth + 1) * (maxDepth - depth + 1));
                return beta;
            }
            if (value > alpha) {
                alpha = value;
                FoundPv = true;
                hashf = hashfEXACT;
                goodMove = new Move(fromPos, toPos);
            }
        }

        transformTable.saveTransformTable(fatherZobristKey, fatherZobristKeyCheck, maxDepth - depth, alpha, hashf);
        if (hashf == hashfEXACT) {
            addHistory(goodMove.fromPos, goodMove.toPos, (maxDepth - depth + 1) * (maxDepth - depth + 1));
        }
        return alpha;
    }

    //生成所有可能走法
    public static LinkedList<Move> allPossibleMoves(int[][] piece, boolean isRedGo, int depth, int alpha, int beta) {
        LinkedList<Move> sortedMoves = new LinkedList<Move>();
        LinkedList<Move> transformMoves = new LinkedList<Move>();
        LinkedList<Move> eatMoves = new LinkedList<Move>();
        LinkedList<Move> historyMoves = new LinkedList<Move>();
        //遍历整个棋盘
        for (int i = 0; i <= 9; i++) {
            for (int j = 0; j <= 8; j++) {
                if ((isRedGo == false && piece[i][j] >= 1 && piece[i][j] <= 7) || (isRedGo == true && piece[i][j] >= 8 && piece[i][j] <= 14)) {
                    List<Pos> ret = Rule.PossibleMoves(piece, j, i, piece[i][j]);  //某个位置的棋子的全部走法
                    Pos fromPos = new Pos(j, i);
                    Iterator<Pos> it = ret.iterator();
                    while (it.hasNext()) {
                        Pos toPos = it.next();
                        updateZobrist(fromPos, toPos, piece[fromPos.y][fromPos.x], piece[toPos.y][toPos.x]);
                        if (transformTable.readTransformTable(ZobristKey, ZobristKeyCheck, maxDepth - depth, alpha, beta) != INF) {
                            transformMoves.add(new Move(fromPos, toPos));
                        } else {
                            if (piece[toPos.y][toPos.x] != 0) {
                                eatMoves.add(new Move(fromPos, toPos));
                            } else {
                                if (historyMoves.isEmpty()) {
                                    historyMoves.add(new Move(fromPos, toPos));
                                } else {
                                    Move firstMove = historyMoves.getFirst();
                                    int firstVal = getHistory(firstMove.fromPos, firstMove.toPos);
                                    int curVal = getHistory(fromPos, toPos);
                                    if (curVal >= firstVal) {
                                        historyMoves.addFirst(new Move(fromPos, toPos));
                                    } else {
                                        historyMoves.addLast(new Move(fromPos, toPos));
                                    }
                                }
                            }
                        }
                        updateZobrist(fromPos, toPos, piece[fromPos.y][fromPos.x], piece[toPos.y][toPos.x]);
                    }
                }
            }
        }
        sortedMoves.addAll(transformMoves);
        sortedMoves.addAll(eatMoves);
        sortedMoves.addAll(historyMoves);
        return sortedMoves;
    }

    public static void clearHistory() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < 9; k++) {
                    for (int p = 0; p < 10; p++) {
                        historyTable[i][j][k][p] = historyTable[i][j][k][p] = 0;
                    }
                }
            }
        }
    }

    public static int getHistory(Pos fromPos, Pos toPos) {
        return historyTable[fromPos.x][fromPos.y][toPos.x][toPos.y];
    }

    public static void addHistory(Pos fromPos, Pos toPos, int val) {
        historyTable[fromPos.x][fromPos.y][toPos.x][toPos.y] += val;
    }
   
    
    public static void updateZobrist(Pos fromPos, Pos toPos, int fromID, int toID) {
        ZobristKey = ZobristKey ^ zobrist.ZobristTable[fromID - 1][fromPos.y][fromPos.x];
        ZobristKeyCheck = ZobristKeyCheck ^ zobrist.ZobristTableCheck[fromID - 1][fromPos.y][fromPos.x];
        ZobristKey = ZobristKey ^ zobrist.ZobristTable[fromID - 1][toPos.y][toPos.x];
        ZobristKeyCheck = ZobristKeyCheck ^ zobrist.ZobristTableCheck[fromID - 1][toPos.y][toPos.x];
        if (toID > 0) {
            ZobristKey = ZobristKey ^ zobrist.ZobristTable[toID - 1][toPos.y][toPos.x];
            ZobristKeyCheck = ZobristKeyCheck ^ zobrist.ZobristTableCheck[toID - 1][toPos.y][toPos.x];
        }
    }

    //局面评分
    public static int evaluate(int[][] piece) {
        int score = 0;
        for (int i = 0; i <= 9; i++) {
            for (int j = 0; j <= 8; j++) {
                if (piece[i][j] >= 1 && piece[i][j] <= 7) {
                    score += pieceValue[piece[i][j] - 1][i][j];
                } else if (piece[i][j] >= 8 && piece[i][j] <= 14) {
                    score -= pieceValue[piece[i][j] - 1][i][j];
                }
            }
        }
        if (isMachineRed) score *= -1;
        return score;
    }

    //判断是否有杀招走法
    public static Move getLegalMove(int piece[][], boolean isRedKing) {   //参数true表示红棋
        if (isRedKing == true) {
            for (int i = 0; i <= 9; i++) {
                for (int j = 0; j <= 8; j++) {
                    if (piece[i][j] >= 8 && piece[i][j] <= 14) {
                        //生成某个位置的棋子的所有走法的位置
                        List<Pos> moves = Rule.PossibleMoves(piece, j, i, piece[i][j]);
                        Iterator<Pos> it = moves.iterator();
                        while (it.hasNext()) {
                            Pos pos = it.next();
                            int tmp = piece[pos.y][pos.x]; //标记可以走的位置的其他棋子号
                            if (tmp == 1) {  //当前棋子下一步可以吃掉黑方将
                                return new Move(new Pos(j, i), pos);   //返回杀招的走法
                            }
                            piece[pos.y][pos.x] = piece[i][j];
                            piece[i][j] = 0;
                            if (Rule.isKingDanger(piece, true) == false) {  //非当前棋子的可以吃掉将
                                piece[i][j] = piece[pos.y][pos.x];
                                piece[pos.y][pos.x] = tmp;
                                return new Move(new Pos(j, i), pos);   //返回杀招的走法
                            }
                            piece[i][j] = piece[pos.y][pos.x];
                            piece[pos.y][pos.x] = tmp;
                        }
                    }
                }
            }
        } else {    //参数false表示黑棋
            for (int i = 0; i <= 9; i++) {
                for (int j = 0; j <= 8; j++) {
                    if (piece[i][j] >= 1 && piece[i][j] <= 7) {
                        List<Pos> moves = Rule.PossibleMoves(piece, j, i, piece[i][j]);
                        Iterator<Pos> it = moves.iterator();
                        while (it.hasNext()) {
                            Pos pos = it.next();
                            int tmp = piece[pos.y][pos.x];
                            if (tmp == 8) {
                                return new Move(new Pos(j, i), pos);
                            }
                            piece[pos.y][pos.x] = piece[i][j];
                            piece[i][j] = 0;
                            if (Rule.isKingDanger(piece, false) == false) {
                                piece[i][j] = piece[pos.y][pos.x];
                                piece[pos.y][pos.x] = tmp;
                                return new Move(new Pos(j, i), pos);
                            }
                            piece[i][j] = piece[pos.y][pos.x];
                            piece[pos.y][pos.x] = tmp;
                        }
                    }
                }
            }
        }
        return new Move(new Pos(-1, -1), new Pos(-1, -1));
    }
}

未完......

点击下载资源

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android 《开发》

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值