五子棋游戏设计
1.引言
1.1 五子棋介绍
五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連
珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row 的缩
写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种
称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴
阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和
高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既
有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结
晶。
1.2 选题背景
随着社会的发展,越来越多人接触和使用计算机,网上进行的棋类运动也随
之普及。许多人喜欢上了下棋,但有时又苦于没有对手。作为一个计算机专业的
学生,我对五子棋有很浓厚的兴趣,平时也一直和同学下棋,有时也和电脑下棋,
我对计算机人机对弈智能算法如何与人脑对抗产生了极大的兴趣,当然人机对弈
的算法有很多种,许多人也对此有所研究。有些算法的智能程度甚至已经与人脑
不相上下。这类程序的开发最重要的莫过于智能算法的实现,然后就是判断胜负
的方法。当前网络上流传的五子棋游戏功能并不尽善尽美,其中最主要的问题就
是人机对战和网络对战不能够一起实现,所以我决定开发[1]一个既能够人机对
战,又能够进行网络对战的五子棋系统。
1.3 系统所要解决的问题
1)棋盘和棋子的绘制
2)计算机对下一步落棋的计算
3)棋盘的载入
4)难度的模式选择
5)棋盘的状态判断
2.系统设计
2.1 系统框架
五子棋
棋盘
人机对弈
人人对弈
判断输赢
游戏结束
考虑到整个的下棋过程(无论对方是电脑或是其他网络玩家)可以分为:己
方落子、等待对方落子、对方落子、设置己方棋盘数据这一系列过程,因此一人
游戏类、二人游戏类和棋盘类之间的关系是不同的
2.2 五子棋棋子
五子棋采用两种颜色棋子,黑色棋子和白色棋子,与围棋相同
2.3 五子棋规则
五子棋就是五个棋子连在一起就算赢,黑棋先行,下棋下在棋盘交叉线上,
由于黑棋先行,优势太大,所以对黑棋设了禁手,又规定了“三手交换”,就是
黑棋下第 2 手棋,盘面第 3 着棋之后,白方在应白 2 之前,如感觉黑方棋形
不利于己方,可出交换,即执白棋一方变为执黑棋一方。和“五手两打法”,就
是黑棋在下盘面上关键的第 5 手时,必须下两步棋,让白方在这两步棋中任选
一步,然后再续下。不过一般爱好者不需要遵循这么多规则。
2
3.程序流程
4.代码设计与分析
4.1、main 函数
main 方法创建了 ChessFrame 类的一个实例对象(cf),并启动屏幕显示该实例对象。
public class FiveChessAppletDemo {
public static void main(String args[]){
ChessFrame cf = new ChessFrame();
cf.show();
}
}
4.2、用 ChessFrame 创建五子棋游戏主窗体和菜单
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.io.PrintStream;
import javax.swing.JComponent;
import javax.swing.JPanel;
class ChessFrame extends JFrame implements ActionListener {
3
private String[] strsize={"20x15","30x20","40x30"};
private String[] strmode={"人机对弈","人人对弈"};
public static boolean iscomputer=true,checkcomputer=true;
private int width,height;
private ChessModel cm;
private MainPanel mp;
4.3、构造五子棋游戏的主窗体
public ChessFrame() {
this.setTitle("五子棋游戏");
cm=new ChessModel(1);
mp=new MainPanel(cm);
Container con=this.getContentPane();
con.add(mp,"Center");
this.setResizable(false);
this.addWindowListener(new ChessWindowEvent());
MapSize(20,15);
JMenuBar mbar = new JMenuBar();
this.setJMenuBar(mbar);
JMenu gameMenu = new JMenu("游戏");
mbar.add(makeMenu(gameMenu, new Object[] {
"开局", "棋盘","模式", null, "退出"
}, this));
JMenu lookMenu =new JMenu("视图");
mbar.add(makeMenu(lookMenu,new Object[] {
"Metal","Motif","Windows"
},this));
JMenu helpMenu = new JMenu("帮助");
mbar.add(makeMenu(helpMenu, new Object[] {
"关于"
}, this));
}
4.4、构造五子棋游戏的主菜单
public JMenu makeMenu(Object parent, Object items[], Object target){
JMenu m = null;
if(parent instanceof JMenu)
m = (JMenu)parent;
else if(parent instanceof String)
m = new JMenu((String)parent);
else
return null;
for(int i = 0; i < items.length; i++)
if(items[i] == null)
4
m.addSeparator();
else if(items[i] == "棋盘"){
JMenu jm = new JMenu("棋盘");
ButtonGroup group=new ButtonGroup();
JRadioButtonMenuItem rmenu;
for (int j=0;j
4.6、构造五子棋游戏的单选按钮式菜单项
public JRadioButtonMenuItem makeRadioButtonMenuItem(
Object item, Object target){
JRadioButtonMenuItem r = null;
if(item instanceof String)
r = new JRadioButtonMenuItem((String)item);
else if(item instanceof JRadioButtonMenuItem)
r = (JRadioButtonMenuItem)item;
else
return null;
return r;
}
if(target instanceof ActionListener)
r.addActionListener((ActionListener)target);
public void MapSize(int w,int h){
setSize(w * 20+50 , h * 20+100 );
if(this.checkcomputer)
this.iscomputer=true;
else
this.iscomputer=false;
mp.setModel(cm);
mp.repaint();
}
public boolean getiscomputer(){
return this.iscomputer;
}
public void restart(){
int modeChess = cm.getModeChess();
if(modeChess <= 3 && modeChess >= 1){
cm = new ChessModel(modeChess);
MapSize(cm.getWidth(),cm.getHeight());
System.out.println("\u81EA\u5B9A\u4E49");
}else{
}
}
public void actionPerformed(ActionEvent e){
String arg=e.getActionCommand();
try{
if (arg.equals("Windows"))
6
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
else if(arg.equals("Motif"))
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.motif.MotifLookAndFeel");
else
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
SwingUtilities.updateComponentTreeUI(this);
}catch(Exception ee){}
if(arg.equals("20x15")){
this.width=20;
this.height=15;
cm=new ChessModel(1);
MapSize(this.width,this.height);
SwingUtilities.updateComponentTreeUI(this);
}
if(arg.equals("30x20")){
this.width=30;
this.height=20;
cm=new ChessModel(2);
MapSize(this.width,this.height);
SwingUtilities.updateComponentTreeUI(this);
}
if(arg.equals("40x30")){
this.width=40;
this.height=30;
cm=new ChessModel(3);
MapSize(this.width,this.height);
SwingUtilities.updateComponentTreeUI(this);
}
if(arg.equals("人机对弈")){
this.checkcomputer=true;
this.iscomputer=true;
cm=new ChessModel(cm.getModeChess());
MapSize(cm.getWidth(),cm.getHeight());
SwingUtilities.updateComponentTreeUI(this);
}
if(arg.equals("人人对弈")){
this.checkcomputer=false;
this.iscomputer=false;
cm=new ChessModel(cm.getModeChess());
MapSize(cm.getWidth(),cm.getHeight());
SwingUtilities.updateComponentTreeUI(this);
7
}
if(arg.equals("开局")){
restart();
}
if(arg.equals("关于"))
JOptionPane.showMessageDialog(this, "五子棋游戏测试版本", "关于", 0);
if(arg.equals("退出"))
System.exit(0);
}
}
4.7、用类 ChessModel 实现了整个五子棋程序算法的核心
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.io.PrintStream;
import javax.swing.JComponent;
import javax.swing.JPanel;
规定棋盘的高度、宽度和棋盘的模式
private int width,height,modeChess;
规定棋盘方格的横向、纵向坐标
private int x=0,y=0;
棋盘方格的横向、纵向坐标所对应的棋子颜色,数组 arrMapShow 只有 3 个值:
1,2,3,-1,其中 1 代表该棋盘方格上下的棋子为黑子,2 代表该棋盘方格上下
的棋子为白子,3 代表为该棋盘方格上没有棋子,-1 代表该棋盘方格不能够下棋
子
private int[][] arrMapShow;
4.8、交换棋手的标识,棋盘方格上是否有棋子的标识符
private boolean isOdd,isExist;
public ChessModel() {}
4.9、该构造方法根据不同的棋盘模式(modeChess)来构建对应大
小的棋盘
public ChessModel(int modeChess){
this.isOdd=true;
if(modeChess == 1){
8