首页 > 代码库 > 算法实验--棋盘覆盖

算法实验--棋盘覆盖

一、实验目的:

熟悉掌握分治算法设计技术

二、实验要求:

1、按教材所授内容要求,完成“棋盘覆盖问题”算法。得到一个完整正确的程序。

2、棋盘大小:32*32(或16*16)

3、输出最终结果。

三、实验设备及环境:

PC机一台、java虚拟机Eclipsejdk环境

四、问题描述:

通过一门语言写一个棋盘覆盖算法,并对棋盘着色,使L型骨牌能够使用相同的颜色,能够在棋盘中一眼看出棋子所在的地方和对棋盘着色的效果。

五、算法分析:

 

 

 

 

 

 

 

                   添加               按钮

                   对象               引发

                   

                   初始

                    化                                  递归调用

 

                   生成

                   方格

 

                   事件

                   处理

 

 

 

 

 

 

 

算法的字段:tr(开始行号),tc(开始列号),dr(特殊翻个行号),dc(特殊方格列号),size(规模),tile(标记的初始值);red,green,blue(生成颜色的红绿蓝值centerPanel,southPanel,panel(三个面板),button[][](方格数组);TrText, TcText, DrText, DcText, SizeText(行列号输入的值);TrLabel, TcLabel, DrLabel, DcLabel, SizeLabel(行列号标签); OKButton,CancelButton(开始、清除按钮);

chessBoard类:算法的主类,生成整个框架,包含面板个方格。

gridLayout类:生成方格。

ButtonAction类:用于处理按钮引发的事件。

ChessBoard方法(主要算法):算法内部通过递归调用,处理对每个方格的标记和着色

六、代码:

1.gridLayout类

class gridLayout {//形成方格的类

public gridLayout() {

centerPanel.setLayout(new GridLayout(0, size));

button = new JButton[size][size];

for (int i = 0; i < size; i++) {

for (int j = 0; j < size; j++) {

button[i][j] = new JButton();

if (i == dr && j == dc) {

button[i][j].setBackground(Color.BLUE);

button[i][j].setText("<html><font size=‘3‘ color=‘white‘>棋子</font></html>");

}

centerPanel.add(button[i][j]);

button[i][j].setEnabled(false);

}

}

}

    ChessBoard();

}

 

2.ChessBoard()方法

public void ChessBoard(int tr, int tc, int dr, int dc,int size) {// 铺棋子算法实现

if (size == 1)  return;// 棋盘方格大小为1,说明递归到最里层

int t = tile++;// 每次递增1

Random rd = new Random();

red = rd.nextFloat();

green = rd.nextFloat();

blue = rd.nextFloat();

Color col = new Color(red, green, blue);

int s = size / 2; // 棋盘中间的行、列号(相等的)

// 检查特殊方块是否在左上角子棋盘中

if (dr < tr + s && dc < tc + s) // 在

ChessBoard(tr, tc, dr, dc, s);

else // 不在,将该子棋盘右下角的方块视为特殊方块

{

button[tr + s - 1][tc + s - 1].setBackground(col);

button[tr + s - 1][tc + s - 1]

    .setText("<html><Font size=‘4‘,color=‘white‘>" + t

+ "</Font></html>");

ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s);

}

// 检查特殊方块是否在右上角子棋盘中

if (dr < tr + s && dc >= tc + s) // 在

ChessBoard(tr, tc + s, dr, dc, s);

else // 不在,将该子棋盘左下角的方块视为特殊方块

{

button[tr + s - 1][tc + s].setBackground(col);

button[tr + s - 1][tc + s]

.setText("<html><Font size=‘4‘,color=‘white‘>" + t

+ "</Font></html>");

ChessBoard(tr, tc + s, tr + s - 1, tc + s, s);

}

// 检查特殊方块是否在左下角子棋盘中

if (dr >= tr + s && dc < tc + s) // 在

ChessBoard(tr + s, tc, dr, dc, s);

else // 不在,将该子棋盘右上角的方块视为特殊方块

{

button[tr + s][tc + s - 1].setBackground(col);

button[tr + s][tc + s - 1]

.setText("<html><Font size=‘4‘,color=‘white‘>" + t

+ "</Font></html>");

ChessBoard(tr + s, tc, tr + s, tc + s - 1, s);

}

// 检查特殊方块是否在右下角子棋盘中

if (dr >= tr + s && dc >= tc + s) // 在

ChessBoard(tr + s, tc + s, dr, dc, s);

else // 不在,将该子棋盘左上角的方块视为特殊方块

{

button[tr + s][tc + s].setBackground(col);

button[tr + s][tc + s]

.setText("<html><Font size=‘4‘,color=‘white‘>" + t

+ "</Font></html>");

ChessBoard(tr + s, tc + s, tr + s, tc + s, s);

}

}

 

3.ButtonAction类

public class ButtonAction implements ActionListener {// 点按钮时事件响应

public void actionPerformed(ActionEvent e) {//需要调用gridLayout类

if (e.getSource()==OKButton) {

getContentPane().add(centerPanel, BorderLayout.CENTER);

int tR = Integer.parseInt(TrText.getText());

int tC = Integer.parseInt(TcText.getText());

int dR = Integer.parseInt(DrText.getText());

int dC = Integer.parseInt(DcText.getText());

int Size = 1;

for (int i = 0; i < Integer.parseInt(SizeText.getText()); i++)

Size *= 2;

tr = tR;

tc = tC;

dr = dR;

dc = dC;

size = Size;

try {

gridLayout grid = new gridLayout();

grid.ChessBoard(tr, tc, dr, dc, size);

centerPanel.updateUI();

} catch (Exception EX) {

EX.printStackTrace();

}

panel.removeAll();

OKButton.setEnabled(false);

}

if (e.getSource()==CancelButton) {// 当你点下一个提示按钮时的事件响应

JLabel label = new JLabel();

label.setText("<html><Font size=‘+8‘,color=‘black‘><center><b><br> 您清除了前一个棋盘……<br></b></Font></html>");

panel.add(label, centerPanel);

getContentPane().add(panel, BorderLayout.CENTER);

panel.updateUI();

tile = 1;//使得每次刷新都从1开始排数

centerPanel.removeAll();

OKButton.setEnabled(true);

}

}

}

4.导入包和主类

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Random;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

 

public class chessBoard extends JFrame {

private int tr, tc, dr, dc, size;// 定义各成员变量

int tile = 1;

float red, green, blue;//给button配色

JPanel centerPanel,southPanel,panel;

JButton[][] button;

JTextField TrText, TcText, DrText, DcText, SizeText;

JLabel TrLabel, TcLabel, DrLabel, DcLabel, SizeLabel;

JButton OKButton;

JButton CancelButton;

public chessBoard() {

super("棋盘覆盖");

init();

this.setResizable(false);

setVisible(true);

OKButton.addActionListener(new ButtonAction());

CancelButton.addActionListener(new ButtonAction());

TrText.setEnabled(false);

TcText.setEnabled(false);

getContentPane().add(southPanel, BorderLayout.NORTH);

}

private void init() {//添加初始化各个控件

panel = new JPanel();

centerPanel = new JPanel();

southPanel = new JPanel();

OKButton = new JButton("开始");

CancelButton = new JButton("清除");

TrText = new JTextField("0", 2);// 定义各组件

TcText = new JTextField("0", 2);

DrText = new JTextField("0", 2);

DcText = new JTextField("0", 2);

SizeText = new JTextField("4", 2);

Toolkit tk=Toolkit.getDefaultToolkit();

Dimension ds=tk.getScreenSize();  this.setBounds(((int)ds.getWidth()-850)/2,(int)(ds.getHeight()-650)/2, 850, 650);// 设置窗口大小与位置

TrLabel = new JLabel("起始方格坐标x: ");

TcLabel = new JLabel("起始方格坐标y: ");

DrLabel = new JLabel("特殊方格坐标x: ");

DcLabel = new JLabel("特殊方格坐标y: ");

SizeLabel = new JLabel("棋盘规模size:   ");

southPanel.add(OKButton);

southPanel.add(CancelButton);// 添加各组件到窗体

southPanel.add(TrLabel);

southPanel.add(TrText);

southPanel.add(TcLabel);

southPanel.add(TcText);

southPanel.add(DrLabel);

southPanel.add(DrText);

southPanel.add(DcLabel);

southPanel.add(DcText);

southPanel.add(SizeLabel);

southPanel.add(SizeText);

}

new gridLayout();//此处是gridLayout类的代码

new ButtonAction();//此处是ButtonAction类的代码

    public static void main(String[] args) {// 主函数方法实现

new chessBoard();

Runtime.getRuntime().gc();// 手动清除数据垃圾

}

}

 

 

 

 

 

七、调试及运行:

1.特殊方格在12列,规模为5时,结果如下

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.特殊方格在1212列规模为5是调试结果如下

 

八、实验总结

通过这次实验,函数的递归调用有了进一步地深入理解,由于是用java完成,也是对java语言建窗体的一种熟悉,另外还有在编程时需要用到颜色时,各种调用颜色的方法有了进一步了解,这次实验主要是通过方法的递归调用来实现大面积的、有规律的棋盘覆盖问题。重要的是,棋盘问题是我们生活中遇到的一些事件中具有代表性的情况,说明了递归在处理一些操作相似但又出现规律性变化的情况是有很好的体现。

 

算法实验--棋盘覆盖