中国象棋(一)

  上期学人工智能,自己试着写了一个中国象棋。总要用的是

Alpha-Bata减支发,这期一看其实就是分支定界法。图像见面是在用网上搜到。自己试了一下有几岁儿童的智能(除那些神童外)。

考虑到代码有点多就分开附上。

 

package org.china.dailiyun.chinese.mian;

/**
 * @author dailiyun
 * @version 0.1
 * @date 2009.10.12
 */

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;

import org.china.dailiyun.chinesechess.piece.BlackJiang;
import org.china.dailiyun.chinesechess.piece.BlackJu;
import org.china.dailiyun.chinesechess.piece.BlackMa;
import org.china.dailiyun.chinesechess.piece.BlackPao;
import org.china.dailiyun.chinesechess.piece.BlackShi;
import org.china.dailiyun.chinesechess.piece.BlackXiang;
import org.china.dailiyun.chinesechess.piece.BlackZhu;
import org.china.dailiyun.chinesechess.piece.RedBing;
import org.china.dailiyun.chinesechess.piece.RedJu;
import org.china.dailiyun.chinesechess.piece.RedMa;
import org.china.dailiyun.chinesechess.piece.RedPao;
import org.china.dailiyun.chinesechess.piece.RedShi;
import org.china.dailiyun.chinesechess.piece.RedShuai;
import org.china.dailiyun.chinesechess.piece.RedXiang;
import org.china.dailiyun.chinesechess.util.DefaultChesspiece;
import org.china.dailiyun.chinesechess.util.Info;
import org.china.dailiyun.chinesechess.util.Rule;
import org.china.dailiyun.chinesechess.util.Step;
import org.china.dailiyun.search.AlphaBetaSearch;
import org.china.dailiyun.search.OneStepSearch;
import org.china.dailiyun.search.Search;

// 主类
public class ChessFrame {
    public static void main(String args[]) throws InterruptedException {
        new ChessMainFrame("中国象棋Java版");

    }
}

// 主框架类
class ChessMainFrame extends JFrame implements ActionListener, MouseListener {
    // 玩家
    DefaultChesspiece play[] = new DefaultChesspiece[32];

    // 棋盘
    JLabel qiPanImage;

    // 窗格
    Container con;

    // 工具栏
    JToolBar toolBar;

    // 重新开始
    JButton reNew;

    // 悔棋
    JButton repent;

    // 打开
    JButton showOpen;

    // 保存
    JButton showSave;

    // 退出
    JButton exit;

    // 当前信息
    JLabel text;

    // 棋盘的每个棋子的位置
    int[][][] location;

    int[][] qiZhis;// 棋盘

    // 每格的长宽
    final int weight;
    final int height;

    static DefaultChesspiece choosed;// 现在被选中的棋子

    // 控制棋子闪耀的线程
    Thread shan;

    int flag;// 现在谁走棋

    Rule rule;// 控制棋子行走的规定

    // 搜素引擎
    Search searchEnging;

    ChessMainFrame(String Title) throws InterruptedException {

        // 获行客格引用
        con = this.getContentPane();
        con.setLayout(null);

        weight = 48;
        height = 49;

        location = new int[10][9][2];
        qiZhis = new int[10][9];

        // 创建工具栏
        toolBar = new JToolBar();
        text = new JLabel("  热烈欢迎");
        text.setToolTipText("提示信息");
        reNew = new JButton(" 新 游 戏 ");
        reNew.setToolTipText("重新开始新的一局");
        exit = new JButton(" 退  出 ");
        exit.setToolTipText("退出本程序");
        repent = new JButton(" 悔  棋 ");
        repent.setToolTipText("返回到上次走棋的位置");
        showOpen = new JButton("打开");
        showOpen.setToolTipText("打开以前棋局");
        showSave = new JButton("保存");
        showSave.setToolTipText("保存当前棋局");

        // 下棋规则类
        rule = Rule.getInstance();
        rule.setPlay(play);
        rule.setQiZhis(qiZhis);
        // 搜素引擎
        searchEnging = new AlphaBetaSearch(play, qiZhis, 3);

        // 把组件添加到工具栏
        toolBar.setLayout(new GridLayout(0, 6));
        toolBar.add(reNew);
        toolBar.add(repent);
        toolBar.add(showOpen);
        toolBar.add(showSave);
        toolBar.add(exit);
        toolBar.add(text);
        toolBar.setBounds(0, 500, 450, 30);
        con.add(toolBar);

        // init qiZhis and location

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 9; j++) {
                location[i][j][0] = 10 + weight * j;
                location[i][j][1] = 10 + height * i;
                qiZhis[i][j] = Info.KONG;

            }
        }

        // 添加棋子标签
        drawChessMan();

        /* 注册监听者 */

        shan = new Thread(new Listener());

        shan.start();

        // 注册按扭监听
        reNew.addActionListener(this);
        repent.addActionListener(this);
        exit.addActionListener(this);
        showOpen.addActionListener(this);
        showSave.addActionListener(this);

        // 注册棋子移动监听
        for (int i = 0; i < 32; i++) {
            con.add(play[i]);
            play[i].addMouseListener(this);

        }

        // 添加棋盘标签
        con.add(qiPanImage = new JLabel(new ImageIcon("CChess.GIF")));
        qiPanImage.setBounds(0, 0, 445, 498);
        qiPanImage.addMouseListener(this);
        // 注册窗体关闭监听
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });

        // 窗体居中
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = this.getSize();

        if (frameSize.height > screenSize.height) {
            frameSize.height = screenSize.height;
        }
        if (frameSize.width > screenSize.width) {
            frameSize.width = screenSize.width;
        }

        this.setLocation((screenSize.width - frameSize.width) / 2 - 200,
                (screenSize.height - frameSize.height) / 2 - 290);

        this.setIconImage(new ImageIcon("相1.gif").getImage());
        this.setResizable(false);
        this.setTitle(Title);
        this.setSize(450, 555);
        this.setVisible(true);
    }

    /* 添加棋子方法 */
    public void drawChessMan() {

        // 图标
        Icon in;

        // 黑色棋子

        int shu = 0;
        // 车
        in = new ImageIcon("车1.GIF");

        play[shu++] = new BlackJu(in, 0, 0);
        play[shu++] = new BlackJu(in, 0, 8);

        // 马
        in = new ImageIcon("马1.GIF");
        play[shu++] = new BlackMa(in, 0, 1);
        play[shu++] = new BlackMa(in, 0, 7);

        // 相
        in = new ImageIcon("相1.GIF");
        play[shu++] = new BlackXiang(in, 0, 2);
        play[shu++] = new BlackXiang(in, 0, 6);

        // 士
        in = new ImageIcon("士1.GIF");
        play[shu++] = new BlackShi(in, 0, 3);
        play[shu++] = new BlackShi(in, 0, 5);

        // 卒
        in = new ImageIcon("卒1.GIF");
        play[shu++] = new BlackZhu(in, 3, 0);
        play[shu++] = new BlackZhu(in, 3, 2);
        play[shu++] = new BlackZhu(in, 3, 4);
        play[shu++] = new BlackZhu(in, 3, 6);
        play[shu++] = new BlackZhu(in, 3, 8);

        // 炮
        in = new ImageIcon("炮1.GIF");
        play[shu++] = new BlackPao(in, 2, 1);
        play[shu++] = new BlackPao(in, 2, 7);

        // 将
        in = new ImageIcon("将1.GIF");
        play[shu++] = new BlackJiang(in, 0, 4);

        // 红色棋子

        // 车
        in = new ImageIcon("车2.GIF");
        play[shu++] = new RedJu(in, 9, 0);
        play[shu++] = new RedJu(in, 9, 8);

        // 马
        in = new ImageIcon("马2.GIF");
        play[shu++] = new RedMa(in, 9, 1);
        play[shu++] = new RedMa(in, 9, 7);

        // 相
        in = new ImageIcon("相2.GIF");
        play[shu++] = new RedXiang(in, 9, 2);
        play[shu++] = new RedXiang(in, 9, 6);

        // 士
        in = new ImageIcon("士2.GIF");
        play[shu++] = new RedShi(in, 9, 3);
        play[shu++] = new RedShi(in, 9, 5);

        // 兵
        in = new ImageIcon("兵2.GIF");
        play[shu++] = new RedBing(in, 6, 0);
        play[shu++] = new RedBing(in, 6, 2);
        play[shu++] = new RedBing(in, 6, 4);
        play[shu++] = new RedBing(in, 6, 6);
        play[shu++] = new RedBing(in, 6, 8);

        // 炮
        in = new ImageIcon("炮2.GIF");
        play[shu++] = new RedPao(in, 7, 1);
        play[shu++] = new RedPao(in, 7, 7);

        // 帅
        in = new ImageIcon("帅2.GIF");
        play[shu++] = new RedShuai(in, 9, 4);

        for (int i = 0; i < 32; i++) {
            setBoud(play[i], play[i].get_x(), play[i].get_y(), i);

        }

    }

    /**
     *
     * @param e
     *            鼠标所点的地方
     * @return 换算为棋盘的位置
     */

    private int[] getLocaion(MouseEvent e) {

        int[] re = new int[2];
        int y = e.getX() - 26; // 为了方便表示
        int x = e.getY() - 20;
        if (0 < y && y < 405 && 0 < x && x < 460) {
            int tempX = x / 49;
            int tempY = y / 48;
            if (x % 49 < 15 && y % 48 < 15) {
                re[0] = tempX;
                re[1] = tempY;
                return re;

            } else if (x % 49 > 34 && y % 48 < 15) {

                re[0] = tempX + 1;
                re[1] = tempY;
                return re;
            } else if (x % 49 < 15 && y % 48 > 33) {
                re[0] = tempX;
                re[1] = tempY + 1;
                return re;
            } else if (x % 49 > 34 && y % 48 > 33) {
                re[0] = tempX + 1;
                re[1] = tempY + 1;
                return re;
            }
        }
        re[0] = -1;
        re[1] = -1;

        return re;

    }

    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        // 重新开始
        if (e.getSource().equals(reNew))
            reStart();

        // 悔棋

        else if (e.getSource().equals(repent))
            huiQi();

        // 打开棋局
        else if (e.getSource().equals(showOpen))
            openQiJu();

        // 保存当前棋局
        else if (e.getSource().equals(showSave))
            saveQiJu();

        // 退出
        else if (e.getSource().equals(exit))
            exitqiJu();

    }

    // 重新开始
    private void reStart() {

        /**/
        flag = Info.RED_PLAYER;
        choosed = null;
        text.setText("红方走棋");

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 9; j++) {
                qiZhis[i][j] = Info.KONG;
            }
        }
        int shu = 0;

        // 黑棋//
        // 车
        play[shu++].set_xy(0, 0);
        play[shu++].set_xy(0, 8);

        // 马
        play[shu++].set_xy(0, 1);
        play[shu++].set_xy(0, 7);

        // 相
        play[shu++].set_xy(0, 2);
        play[shu++].set_xy(0, 6);

        // 士
        play[shu++].set_xy(0, 3);
        play[shu++].set_xy(0, 5);

        // 卒
        play[shu++].set_xy(3, 0);
        play[shu++].set_xy(3, 2);
        play[shu++].set_xy(3, 4);
        play[shu++].set_xy(3, 6);
        play[shu++].set_xy(3, 8);

        // 炮
        play[shu++].set_xy(2, 1);
        play[shu++].set_xy(2, 7);

        // 将
        play[shu++].set_xy(0, 4);

        // 红色棋子

        // 车
        play[shu++].set_xy(9, 0);
        play[shu++].set_xy(9, 8);

        // 马
        play[shu++].set_xy(9, 1);
        play[shu++].set_xy(9, 7);

        // 相
        play[shu++].set_xy(9, 2);
        play[shu++].set_xy(9, 6);

        // 士
        play[shu++].set_xy(9, 3);
        play[shu++].set_xy(9, 5);

        // 兵
        play[shu++].set_xy(6, 0);
        play[shu++].set_xy(6, 2);
        play[shu++].set_xy(6, 4);
        play[shu++].set_xy(6, 6);
        play[shu++].set_xy(6, 8);

        // 炮

        play[shu++].set_xy(7, 1);
        play[shu++].set_xy(7, 7);

        // 帅
        play[shu++].set_xy(9, 4);

        for (int i = 0; i < 32; i++) {
            setBoud(play[i], play[i].get_x(), play[i].get_y());

            play[i].setVisible(true);
            play[i].setLive(true);

        }

    }

    /**
     * 初始化棋盘计算每个棋子能到的位置
     */

    // 工具方法
    private void setBoud(DefaultChesspiece temp, int x, int y, int num) {

        temp.set_xy(x, y);
        temp.setBounds(location[x][y][0], location[x][y][1], 40, 40);
        temp.setNum(num);
        qiZhis[x][y] = num;

    }

    private void setBoud(DefaultChesspiece temp, int x, int y) {

        temp.set_xy(x, y);
        temp.setBounds(location[x][y][0], location[x][y][1], 40, 40);
        qiZhis[x][y] = temp.getNum();

    }

    // 吃子或走动的时候使用
    private void moveSet(DefaultChesspiece temp, int x, int y) {

        moveSetBoud(temp, x, y);

        Step one = searchEnging.search();
        int num = one.getNum();
        int[] point = one.getPoint();
        x = point[0];
        y = point[1];
        choosed = play[num];
        try {
            new Thread().sleep(500);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        moveSetBoud(play[num], x, y);

    }

    private void moveSetBoud(DefaultChesspiece temp, int x, int y) {

        if (qiZhis[x][y] != Info.KONG) {
            play[qiZhis[x][y]].setVisible(false);
            play[qiZhis[x][y]].setLive(false);
        }
        int tempX = temp.get_x();
        int tempY = temp.get_y();
        temp.set_xy(x, y);

        qiZhis[tempX][tempY] = Info.KONG;// 棋子原来的位置
        qiZhis[x][y] = temp.getNum();// 新位置

        temp.setBounds(location[x][y][0], location[x][y][1], 40, 40);
        choosed = temp;

        if (!play[15].isLive()) {
            win(Info.RED_PLAYER);

        }
        if (!play[31].isLive()) {
            win(Info.BLACK_PLAYER);
        }

        if (check()) {

            if (temp.getPalyer() == Info.RED_PLAYER)

                win(Info.BLACK_PLAYER);

            else
                win(Info.RED_PLAYER);

        }

        swapFlag();

    }

    // 交换主动权
    private void swapFlag() {

        flag = (flag == Info.RED_PLAYER) ? Info.BLACK_PLAYER : Info.RED_PLAYER;
        if (flag == Info.RED_PLAYER)
            text.setText("红方走棋");
        else
            text.setText("黑方走棋");

    }

    private void win(int who) {
        if (who == Info.RED_PLAYER) {
            JOptionPane.showConfirmDialog(this, "红棋胜利", "玩家二胜利",
                    JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);

            text.setText("  红棋胜利");

        } else {
            JOptionPane.showConfirmDialog(this, "黑棋胜利", "玩家一胜利",
                    JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);

            text.setText("  黑棋胜利");

        }
        flag = Info.STOP;

    }

    /**
     * 悔棋
     */
    // 也后在做
    private void huiQi() {

    }

    /**
     * 打开棋谱 也后在做
     */

    private void openQiJu() {

    }

    /**
     * 保存本局棋谱
     */
    private void saveQiJu() {

    }

    /**
     * 离开游戏
     */
    private void exitqiJu() {

    }

    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

        if (flag != Info.STOP) {

            // 单击棋盘(移动棋子)
            if (e.getSource().equals(qiPanImage)) {
                if (choosed != null) {
                    zou(e);
                }

            }
            // 单击棋子
            else {

                DefaultChesspiece temp = (DefaultChesspiece) e.getSource();
                if (choosed != null) {
                    if (temp.equals(choosed)) {
                        choosed = null;

                    } else if (temp.getPalyer() == flag) {

                        choosed = temp;

                    } else if (temp.getPalyer() != flag)
                        chi(temp);
                } else {
                    if (flag == temp.getPalyer()) {
                        choosed = temp;

                    }

                }

            }
        }

    }

    // 走棋子
    private void zou(MouseEvent e) {

        int[] re = getLocaion(e);
        if (re[0] != -1) {

            if (flag == choosed.getPalyer() && choosed.canMoveTo(re[0], re[1])) {

                if (rule.canMove(choosed, re[0], re[1])) {

                    moveSet(choosed, re[0], re[1]);

                }

            }
        }

    }

    // 吃子
    private void chi(DefaultChesspiece to) {

        int[] temp = to.getxy();

        if (choosed.canMoveTo(temp[0], temp[1])) {

            if (rule.canMove(choosed, temp[0], temp[1])) {

                moveSet(choosed, temp[0], temp[1]);
                if (to.getKind() == Info.RED_SHUAI)
                    win(Info.BLACK_PLAYER);
                else if (to.getKind() == Info.BLACK_JIANG)
                    win(Info.RED_PLAYER);
            }

        }

    }

    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    boolean check() {

        int y1 = play[15].get_y();
        int y2 = play[31].get_y();
        if (y1 == y2) {

            int x1 = play[15].get_x();
            int x2 = play[31].get_x();
            for (int i = x1 + 1; i < x2; i++) {

                if (qiZhis[i][y1] != Info.KONG) {

                    return false;
                }
            }

            return true;
        }
        return false;
    }

    class Listener implements Runnable {

        public synchronized void run() {

            while (true) {
                DefaultChesspiece temp = choosed;

                if (temp != null) {

                    temp.setVisible(false);
                    text.setVisible(!text.isVisible());
                    try {
                        new Thread().sleep(500);
                    } catch (InterruptedException e) {

                        e.printStackTrace();
                    }
                    temp.setVisible(true);
                    text.setVisible(!text.isVisible());
                    try {
                        new Thread().sleep(500);
                    } catch (InterruptedException e) {

                        e.printStackTrace();
                    }
                } else
                    try {
                        text.setVisible(!text.isVisible());
                        new Thread().sleep(500);
                    } catch (InterruptedException e) {

                        e.printStackTrace();
                    }

            }

        }

    }

}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值