MainFrame
package gobang;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class MainFrame extends JFrame{
//属性
JMenuBar menuBar;
JMenu game,operator,help;
JMenuItem restart,end,regret,helps;
ChessBord chessBord ;
Timer timer = null;
//方法
public MainFrame() {
Splash sp = new Splash();
MainFrame mf=this;
timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sp.setVisible(false);
mf.setVisible(true);
timer.stop();
}
});
timer.start();
menuBar = new JMenuBar();
game = new JMenu("游戏");
operator = new JMenu("操作");
help = new JMenu("帮助");
restart = new JMenuItem("新游戏");
end = new JMenuItem("退出");
regret = new JMenuItem("悔棋");
helps = new JMenuItem("帮助(H)");
game.add(restart);
game.add(end);
operator.add(regret);
help.add(helps);
menuBar.add(game);
menuBar.add(operator);
menuBar.add(help);
this.setJMenuBar(menuBar);
chessBord = new ChessBord();
add(chessBord);
MyItemListener lis=new MyItemListener();
restart.addActionListener(lis);
end.addActionListener(lis);
regret.addActionListener(lis);
helps.addActionListener(lis);
this.setTitle("五子棋");
this.setSize(530, 580);
this.setLocationRelativeTo(null);
this.setResizable(false);//setResizable()设置窗体的大小为固定值,不可改变
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null);
}
//内部类
private class MyItemListener implements ActionListener{
public void actionPerformed(ActionEvent e){
Object obj=e.getSource();//获得事件源
if(obj==MainFrame.this.restart){
//重新开始
//JFiveFrame.this内部类引用外部类
System.out.println("重新开始");
chessBord.initGame();
}
else if (obj==MainFrame.this.end)
System.exit(0);
else if (obj==MainFrame.this.regret){
System.out.println("悔棋...");
chessBord.goback();
}else if (obj==MainFrame.this.helps)//obj.equals("推出")
JOptionPane.showMessageDialog(null, "五子棋是世界智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏,"
+"\n"+ "是世界智力运动会竞技项目之一,通常双方分别使用黑白两色的棋子,下在棋"
+"\n"+ "盘直线与横线的交叉点上,先形成5子连线者获胜。");
}
}
public static void main(String[] args) {
new MainFrame();
}
}
ChessBord
package gobang;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Stack;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ChessBord extends JPanel implements MouseListener{
private ImageIcon bgImg=new ImageIcon("images/chessbg.jpg");//棋盘背景图
int rowOffset = 32; //行偏移
int colOffset = 32; //列偏移
double gridW = 35; //格子宽度
double gridH = 35; //格子高度
JLabel label = new JLabel(bgImg);
ArrayList<Integer> xList = new ArrayList<>(); //记录行的位置
ArrayList<Integer> yList = new ArrayList<>(); //记录列的位置
ArrayList<Chess> chesses = new ArrayList<>(); //记录每一个棋子
Chess chess1,chess2;
int xIndex,yIndex;//当前刚下棋子的索引
Chess playerChess = null;
public ChessBord() {
this.setLayout(null);
this.setBounds(0, 0, bgImg.getIconWidth(), bgImg.getIconHeight());
label.setBounds(0, 0, bgImg.getIconWidth(), bgImg.getIconHeight());
this.add(label);
this.setVisible(true);
//this.initGame();
this.addMouseListener(this);
}
public void initGame(){
GBBoss.initGame();
xList = new ArrayList<>();
yList = new ArrayList<>();
int x = (int)(Math.random()*2);
System.out.println("x = "+x);
GBBoss.setPc(1-x*2);
Component[] cs = this.getComponents();
for(int i=0;i<cs.length;i++){
if(cs[i]!=label){
cs[i].setVisible(false);
this.remove(cs[i]);
}
}
System.out.println(GBBoss.getPc());
if(GBBoss.getPc()==-1){
//电脑先下
pcFirstSetQizi();
}
}
public void pcFirstSetQizi() {
int r = (int)(Math.random()*15);
int c = (int)(Math.random()*15);
int bw = GBBoss.getCurBW();
int x = bw;
while(r<15&&c<15&&GBBoss.getData(r, c)!=0){
r = (int)(Math.random()*15);
c = (int)(Math.random()*15);
}
Chess qizi = new Chess(bw);
this.add(qizi);
qizi.setLocation((int)(c*gridW+colOffset-gridW/2),(int)(r*gridH+rowOffset-gridH/2) );
this.setComponentZOrder(qizi,0);
GBBoss.setData(r,c,bw);
bw = -bw;
System.out.println(""+x+" "+r+" "+c);
}
private void pcSetQizi() {
int bw = GBBoss.getCurBW();
int x = bw;
int maxValue = 0,tempR=-1,tempC=-1;
for(int i=0;i<15;i++){
for(int j = 0;j<15;j++){
if(GBBoss.getData(i, j)!=0)
continue;
int attack =AI.calValue(i,j,x);//计算攻击的估值,-1
int defend = AI.calValue(i, j, -x)-5;//计算防守的评估值 - 5攻击为主
int max = Math.max(attack, defend);
if(max>maxValue){
tempR= i;
tempC = j;
maxValue = max;
}
}
}
//System.out.println("maxValue = "+maxValue);
//在计算出来的结果处落子
GBBoss.setData(tempR, tempC, bw);
xList.add(tempR);
yList.add(tempC);
Chess qizi = new Chess(bw);
this.add(qizi);
chesses.add(qizi);
qizi.setLocation((int)(tempC*gridW+colOffset-gridW/2),(int)(tempR*gridH+rowOffset-gridH/2) );
this.setComponentZOrder(qizi,0);
if(GBBoss.getWin()!=0){
//System.out.println(bw+"win");
if(bw == -1){
JOptionPane.showMessageDialog(null, "black win!");
return;
}else {
JOptionPane.showMessageDialog(null, "white win!");
return;
}
}
bw = -bw;
System.out.println(""+x+" "+tempR+" "+tempC);
}
public void goback(){
if(xList.isEmpty()||yList.isEmpty()||chesses.isEmpty())
return ;
int k=0;
while(k!=2){
if(xList.isEmpty())
break;
System.out.println("list的size:"+xList.size());
xIndex = xList.get(xList.size()-1);
yIndex = yList.get(yList.size()-1);
GBBoss.setData(xIndex, yIndex);
xList.remove(xList.size()-1);
yList.remove(yList.size()-1);
k++;
}
Component[] cs = this.getComponents();
chess1 = chesses.get(chesses.size()-1);
chesses.remove(chesses.size()-1);
if(!chesses.isEmpty()){
chess2 = chesses.get(chesses.size()-1);
chesses.remove(chesses.size()-1);
}
for(int i=0;i<cs.length;i++){
if(cs[i]==chess1||cs[i]==chess2){
cs[i].setVisible(false);
this.remove(cs[i]);
}
}
chess1 = null;
chess2 = null;
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
//System.out.println("X = "+e.getX());
//System.out.println("Y = " + e.getY());
int r = (int)((e.getY()-this.rowOffset+gridH/2)/gridH);
int c = (int)((e.getX()-this.rowOffset+gridW/2)/gridW);
if(r>=0&&r<15&&c>=0&&c<15){
int bw = GBBoss.getCurBW();
if(GBBoss.setData(r, c, bw)){
//将鼠标点击的坐标位置转换成网格索引
Chess qizi = new Chess(bw);
this.add(qizi);
xList.add(r);
yList.add(c);
chesses.add(qizi);
qizi.setLocation((int)(c*gridW+colOffset-gridW/2),(int)(r*gridH+rowOffset-gridH/2) );
this.setComponentZOrder(qizi,0);
System.out.println(""+(-GBBoss.getCurBW())+" "+ r+ " "+c);
if(GBBoss.getWin()!=0){
//System.out.println(bw+"win");
if(bw == -1){
JOptionPane.showMessageDialog(null, "black win!");
return;
}else {
JOptionPane.showMessageDialog(null, "white win!");
return;
}
}
bw= -bw;
GBBoss.setPc(bw);
pcSetQizi();
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
棋子Chess
package gobang;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
public class Chess extends JLabel{
int x;
int y;
int bw = -1;
private static ImageIcon bImg = new ImageIcon("images/black.png");
private static ImageIcon wImg = new ImageIcon("images/white.png");
//public Chess() { }
public Chess(int bw) {
this.bw = bw;
if(bw==1){
this.setIcon(wImg);
}else
this.setIcon(bImg);
this.setSize(bImg.getIconWidth(),bImg.getIconHeight());
this.setVisible(true);
}
}
进入程序时的界面Splash
package gobang;
import java.awt.Container;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Splash extends JFrame {
private ImageIcon bgImg=new ImageIcon("images/2.jpg");
public Splash() {
this.setTitle("Splash");
this.setSize(bgImg.getIconWidth(),bgImg.getIconHeight());
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JLabel label = new JLabel(bgImg);
label.setBounds(0, 0, bgImg.getIconWidth(), bgImg.getIconHeight());
Container cp = this.getContentPane();
cp.setLayout(null);
cp.add(label);
this.setUndecorated(true);
this.setVisible(true);
}
}
实现人机的简单AI
package gobang;
public class AI {
private static String[] blackKey = new String[]{
"-1-1-1-1-1","0-1-1-1-10","0-1-1-1-1","-1-1-1-10","0-1-1-10","-1-1-10","0-1-1-1","-10-1-1","-1-10-1","0-1-10","-1-1","-1"
};
private static String[] whiteKey = new String[]{
"11111","011110","01111","11110","01110","1110","0111","1011","1101","0110","11","1"
};
private static int[] keyValues = new int[]{
100,90,80,80,70,60,60,60,60,60,50,10
};
//计算每个点的权重
public static int calValue(int row,int col,int bw) {
int max = 0;
int tmpMax = 0;
String[] array = blackKey;
if(bw==1){
array = whiteKey;
}
StringBuilder builder = new StringBuilder();
//竖直方向
for(int i=-4;i<=4;i++) {
int newCol = col + i;
if(newCol<0||newCol>=15)
continue;
if(i==0)
builder.append(bw);
else {
builder.append(GBBoss.getData(row, newCol));
}
}
for(int i = 0;i<array.length;i++){
String key = array[i];
if(builder.indexOf(key)>=0){//当有相同的序列是,即为最大值,直接break
max = keyValues[i];
break;
}
}
if(max == 100)
return max;
builder.delete(0, builder.length());
for(int i = -4;i<=4;i++){
int newRow = row+i;
if(newRow<0||newRow>=15)
continue;
if(i==0){
builder.append(bw);
}else {
builder.append(GBBoss.getData(newRow, col));
}
}
tmpMax =0;
for(int i=0;i<array.length;i++){
String key = array[i];
if(builder.indexOf(key)>=0){
tmpMax = keyValues[i];
break;
}
}
if(tmpMax>max){
max = tmpMax;
}
if(max == 100){
return max;
}
//正45度方向
if(max == 100)
return max;
builder.delete(0, builder.length());
for(int i = -4;i<=4;i++){
int newRow = row-i;
int newCol = col +i;
if(newRow<0||newRow>=15||newCol<0||newCol>=15)
continue;
if(i==0){
builder.append(bw);
}else {
builder.append(GBBoss.getData(newRow, newCol));
}
}
tmpMax =0;
for(int i=0;i<array.length;i++){
String key = array[i];
if(builder.indexOf(key)>=0){
tmpMax = keyValues[i];
break;
}
}
if(tmpMax >max)
max = tmpMax;
//斜45度方向
if(max == 100)
return max;
builder.delete(0, builder.length());
for(int i = -4;i<=4;i++){
int newRow = row+i;
int newCol = col +i;
if(newRow<0||newRow>=15||newCol<0||newCol>=15)
continue;
if(i==0){
builder.append(bw);
}else {
builder.append(GBBoss.getData(newRow, newCol));
}
}
tmpMax =0;
for(int i=0;i<array.length;i++){
String key = array[i];
if(builder.indexOf(key)>=0){
tmpMax = keyValues[i];
break;
}
}
if(tmpMax >max)
max = tmpMax;
return max;
}
}