五子棋编程思路
一.创建主函数,构造窗体方法
public static void main(String[] args){
FiveChessUI ui=new FiveChessUI();
ui.showframe();
}
public void showframe(){
this.setTitle("五子棋");
this.setSize(802,700);
this.setResizable(false);
this.setLayout(new FlowLayout(0,0,0));
//菜单
MenuBarPanel menubarpanel=new MenuBarPanel(g);
menubarpanel.setBounds(0, 0, 800, 40);
this.setJMenuBar(menubarpanel);
//棋盘,功能菜单
chesspanel=new ChessPanel();
chesspanel.setPreferredSize(new Dimension(625,660));
chesspanel.setBackground(new Color(233, 146, 68));
MenuPanel menupanel=new MenuPanel(this,g);
menupanel.setLayout(new FlowLayout(1,30,63));
menupanel.setPreferredSize(new Dimension(161,660));
menupanel.setBackground(Color.LIGHT_GRAY);
this.add(chesspanel);
this.add(menupanel);
//窗体设置
this.setDefaultCloseOperation(3);
this.setVisible(true);
//获取画布
Graphics g=chesspanel.getGraphics();
chesslistener=new ChessListener(g);
}
在窗体方法中添加了菜单,棋盘,功能菜单板块
在棋盘面板上获取画布
添加给棋盘加监听器的方法
添加给棋盘移除监听器的方法
public void addChessListener() {
chesspanel.addMouseListener(chesslistener);
}
// 给棋盘移除监听器的方法
public void removeChessListener() {
chesspanel.removeMouseListener(chesslistener);
}
二.另建菜单,棋盘。功能菜单类,将其添加在窗体上
package wenxiaodong.fivechess;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MenuPanel extends JPanel implements Config{
public MenuPanel(FiveChessUI ui,Graphics g){
MenuListener menulistener=new MenuListener(ui,g);
for(int i=0;i<MENUS.length;i++){
JButton but=new JButton(MENUS[i]);
but.addActionListener(menulistener);
this.add(but);
}
}
}
package wenxiaodong.fivechess;
import java.awt.Graphics;
import java.awt.MenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class MenuBarPanel extends JMenuBar implements Config {
private Graphics g;
public MenuBarPanel(Graphics g){
this.g=g;
for(int i=0;i<MENUBARS.length;i++){
JMenu menu=new JMenu(MENUBARS[i],true);
this.add(menu);
//文件
if(MENUBARS[i]==MENUBARS[0]){
for(int j=0;j<FILES.length;j++){
JMenuItem item=new JMenuItem(FILES[j]);
menu.add(item);
}
}
//游戏
if(MENUBARS[i]==MENUBARS[1]){
for(int j=0;j<GAMES.length;j++){
JMenuItem item=new JMenuItem(GAMES[j]);
menu.add(item);
}
}
}
}
}
package wenxiaodong.fivechess;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class ChessPanel extends JPanel implements Config{
public void paint(Graphics g){
super.paint(g);
drawTable(g);
fillrect(g);
drawChesses(g);
}
//重绘棋盘
public void drawTable(Graphics g){
// 绘制横线
for (int i = 0; i < ROWS; i++) {
g.drawLine(X0, Y0 + SIZE * i, X0 + SIZE * (COLUMNS - 1), Y0 + SIZE
* i);
}
// 绘制竖线
for (int i = 0; i < COLUMNS; i++) {
g.drawLine(X0 + SIZE * i, Y0, X0 + SIZE * i, Y0 + SIZE * (ROWS - 1));
}
}
//重绘标志
public void fillrect(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(X0+3*SIZE-4, Y0+3*SIZE-3,
8, 6);
g.fillRect(X0+3*SIZE-4,Y0+11*SIZE-3,
8, 6);
g.fillRect(X0+11*SIZE-4,Y0+3*SIZE-3,
8, 6);
g.fillRect(X0+11*SIZE-4,Y0+11*SIZE-3,
8, 6);
g.fillRect(X0+7*SIZE-4,Y0+ 7*SIZE-3,
8, 6);
}
//重绘棋子
public void drawChesses(Graphics g){
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
if (CHESSES[i][j] != 0) {
// 根据下标计算坐标
// 得到交叉点的坐标
int x = X0 + j * SIZE;
int y = Y0 + i * SIZE;
if (CHESSES[i][j] == 1) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.WHITE);
}
// 以交叉点为圆心绘制棋子
g.fillOval(x - CHESS_SIZE / 2, y - CHESS_SIZE / 2,
CHESS_SIZE, CHESS_SIZE);
}
}
}
}
}
其中,在棋盘类中添加重绘棋盘和棋子的方法
三,分别创建三个监听器,监听菜单,棋盘,功能菜单,实现各个功能
四,将各个参数值写在一个类中便于修改
package wenxiaodong.fivechess;
public interface Config {
public static final int X0=30;
public static final int Y0=30;
public static final int SIZE=40;
public static final int CHESS_SIZE=30;
public static final int ROWS=15;
public static final int COLUMNS=15;
public static final String[] MENUBARS={"文件","游戏","帮助"};
public static final String[] MENUS = { "开始", "悔棋", "重来", "认输", "结束","退出" };
public static final int[][] CHESSES=new int[ROWS][COLUMNS];
public static final String[] FILES={"单人游戏","双人游戏","多人游戏"};
public static final String[] GAMES={"简单","一般","困难"};
public static final int[][] VALUES=new int[ROWS][COLUMNS];
}
五,算法
分四个方向查找相同棋子的数量
六,机器人
遍历棋盘,给各个空白点赋值,找到值最大的点,返回坐标
七,在棋盘监听器中创建绘棋子的方法,只需传入坐标即可,没放一次判断一次输赢
package wenxiaodong.fivechess;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ChessListener extends MouseAdapter implements Config{
private Graphics g;
SuanFa sf=new SuanFa();
ChessRobot robot=new ChessRobot();
//构造函数
public ChessListener(Graphics g) {
this.g = g;
}
public void mouseReleased(MouseEvent e) {//
int x1 = e.getX();
int y1 = e.getY();
for (int i= 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
int x = X0 + j * SIZE;
int y = Y0 + i * SIZE;
if (Math.abs(x - x1) <= SIZE / 3
&& Math.abs(y - y1) <= SIZE / 3) {
if(CHESSES[i][j]==0){
//人放棋子
putChess(i,j,1);
//机器人放棋子
int[] point=robot.getPoint();
putChess(point[0],point[1],-1);
}
return;
}
}
}
}
//人机对战方法
public void putChess(int r,int c,int flag){
int x = X0 + c * SIZE;
int y = Y0 + r * SIZE;
//棋子颜色
if(flag==1){
g.setColor(Color.BLACK);
}else if(flag==-1){
g.setColor(Color.WHITE);
}
CHESSES[r][c]=flag;
g.fillOval(x - CHESS_SIZE / 2, y - CHESS_SIZE / 2,
CHESS_SIZE, CHESS_SIZE);
//判断输赢
boolean br1 = sf.checkRow(r, c);
boolean br2 = sf.checkColumns(r, c);
boolean br3 = sf.checkXz(r, c);
boolean br4 = sf.checkXy(r, c);
if(br1||br2||br3||br4){
String msg = "";
if(CHESSES[r][c]==1){
msg="黑方赢了!!!";
}else{
msg="白方赢了!!!";
}
javax.swing.JOptionPane.showMessageDialog(null,msg);
}
}
}
这样其他的就是优化和升级方面的问题了