赞
踩
(下载资源在文末)
实现中国象棋之类的游戏都会自定义一个View,本次用到SurfaceView,不了解的小伙伴可以自己了解一下。
象棋的运行思路
执行过程:点击屏幕(屏幕监听) ——>是否到自己走棋(是) ——>判断是否已经选中棋子(是) ——>判断点击位置是否有自己的棋子(是)——>选中该棋子(true)——>再次点击屏幕——>判断位置是否符合下棋规则(点击位置有对方棋子或空位)——>可以移动,改变棋盘(数组)。
代码实现
实现棋盘所有功能(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));
- }
- }

未完......
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。