學了兩週的java,想着做點東西玩玩,萌生了寫一個掃雷的想法,這個想法其實在學c語言時就有了,當時並不知道c也有圖形庫,在後來就擱置了,最近看了大概兩週的java,剛好看完 java Swing圖形界面,老師說應該做個小項目檢驗一下學習成果,想着還是掃雷吧。
寫了有兩天,頭一天把基本的的東西做出來了,第二天主要進行了一些優化,最後鼠標右鍵標記雷的功能沒加上,原因是在把按鈕置爲不可用時,居然還是可以雙擊點擊???但在換一個程序中試驗時卻沒有這個現象,經過多方查找還是沒有解決,只好作罷,最後,附上源碼(如有需要圖片等資源,請自行下載文章末尾打包文件,可以直接運行(無Java環境亦可運行))。
注:如果你使用了我的代碼,請隨手點個贊?。
package testone;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Arrays;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;
public class SaoLei {
public static void main(String[] args) {
// JFrame.setDefaultLookAndFeelDecorated(true); //使窗口美觀,創建窗口前使用
GuiSl test = new GuiSl("掃雷",600,300,240,320);
//窗口改變大小,圖片也隨之改變大小以適應窗口
test.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
int w = test.ls.getWidth()/test.x;
int h = test.ls.getHeight()/test.y;
for(int b0 = 0;b0 < test.x;b0++) {
for(int b1 = 0;b1 < test.y;b1++) {
// test.biu[b0][b1].setDisabledIcon(setImageSize0("Image\\SaoLei\\mine.jpg",w,h));
if(!test.book[b0][b1]) continue;
ImageIcon im = (ImageIcon)test.biu[b0][b1].getIcon();
im.setImage(im.getImage().getScaledInstance(w,h,Image.SCALE_DEFAULT));
test.biu[b0][b1].setIcon((Icon)im);
}
}
}
});
}
}
/**
* 建立基本窗口
* @author ds_surk
*
*/
class GuiSl extends JFrame {
JMenuBar bar;
JMenu m1,m2;
JMenuItem i1,i2,i3,i4,i5;
JButton [][] biu; //掃雷界面按鈕
JPanel ls; //容器
int [] mines; //設置mine數量
static int x = 9,y = 9,num = 10,sum=0; //grid行列,雷的數量,已掃的雷
boolean [][] book; //標記數組
Timer time;
JLabel tu; //秒錶圖
JLabel tm0 = new JLabel(); //計時
JTextField re = new JTextField(); //留下姓名文本框
int max1 = 999999; //最大的耗時
GuiSl(){}
GuiSl(String s,int x,int y,int width,int height){
setBounds(x, y, width, height); //設置大小
setLocationRelativeTo(null); //設置爲放在屏幕中央
setVisible(true); //設置窗口可見
// pack(); //設置調整窗口大小以適應組件
setDefaultCloseOperation(3); //設置關閉方式
inits(s);
setVisible(true);
}
/**
* 獲取窗口本身
* @return
*/
GuiSl getck() {
return this;
}
void inits(String s){
init0(s);
init1();
}
void init0(String s) {
setTitle(s);
setIconImage(getToolkit().getImage("Image\\SaoLei\\0.jpg")); //設置圖標
bar = new JMenuBar();
m1 = new JMenu("遊戲");
m2 = new JMenu("幫助");
i1 = new JMenuItem("新遊戲");
i2 = new JMenuItem("設置");
i3 = new JMenuItem("排名");
i4 = new JMenuItem("help");
i5 = new JMenuItem("關於");
i1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ini();
}
}); //設置監視器
i1.setAccelerator(KeyStroke.getKeyStroke("F2")); //設置快捷鍵
i2.addActionListener(new Set0());
i2.setAccelerator(KeyStroke.getKeyStroke("F4"));
i3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
paiHang();
}
});
i3.setAccelerator(KeyStroke.getKeyStroke("F6"));
i4.addActionListener(new Help());
i5.addActionListener(new GYu());
m1.add(i1);
m1.addSeparator(); //添加菜單項分界線
m1.add(i2);
m1.addSeparator();
m1.add(i3);
m2.add(i4);
m2.addSeparator();
m2.add(i5);
bar.add(m1);
bar.add(m2);
setJMenuBar(bar);
}
void init1() {
setGrid(x,y); //設置網格
setRand(num); //設置雷的位置
tm0.setText("0");
Box tim = Box.createHorizontalBox();
tu = new JLabel(":");
tu.setIcon(new ImageIcon("Image\\SaoLei\\time.jpg"));
ls = new JPanel();
ls.setLayout(new GridLayout(x,y));
biu = new JButton[x][y];
book = new boolean[x][y];
sum = 0;
for(int i = 0;i < x;i++) {
for(int j = 0;j < y;j++) {
biu[i][j] = new JButton();
biu[i][j].setIcon(new ImageIcon("Image\\SaoLei\\1.jpg"));
biu[i][j].addMouseListener(new BiuListener());
ls.add(biu[i][j]);
book[i][j] = false;
}
}
//設置計時器
time = new Timer(1000,new ActionListener() {
public void actionPerformed(ActionEvent e) {
int i = Integer.parseInt(tm0.getText());
tm0.setText(String.valueOf(i+1));
}
});
add(ls,BorderLayout.CENTER);
tim.add(Box.createHorizontalStrut(10));
tim.add(tu);
tim.add(tm0);
add(tim,BorderLayout.SOUTH);
// add(ls,BorderLayout.CENTER);
// add(bi,BorderLayout.WEST);
}
/**
* 設置並返回給定寬高的圖片
* @param s爲圖片地址
* @param width爲設置寬
* @param height爲設置高
* @return ImageIcon對象
*/
ImageIcon setImageSize0(String s,int width,int height) {
ImageIcon im = new ImageIcon(s); //按如下方法設置任意寬高圖片
im.setImage(im.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
return im;
}
/**
* 按鈕監聽器
* @author ds_surk
*
*/
class BiuListener extends MouseAdapter{
public void mouseClicked(MouseEvent e) {
if(tm0.getText().equals("0")) //點擊第一個按鈕時啓動計時器
time.start();
int i,j,k;
int w = ls.getWidth()/y;
int h = ls.getHeight()/x;
JButton button = (JButton)e.getSource(); //獲取事件源
for(i = 0;i < x;i++) {
for(k = 0;k < y;k++) {
if(biu[i][k] == button) { //找到對應按鈕
// if(e.getModifiers() == InputEvent.BUTTON3_MASK) { //鼠標右鍵
// if(biu[i][k].getIcon().toString()==new ImageIcon("Image\\SaoLei\\1.jpg").toString()) {
// biu[i][k].setDisabledIcon((Icon)setImageSize0("Image\\SaoLei\\mine.jpg",w,h));
// biu[i][k].setEnabled(!biu[i][k].isEnabled());
// }
// return;
// }
for(j = 0;j < mines.length;j++) {
if(mines[j] == i*x+k+1) { //掃到雷了
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\2.jpg",w,h));
time.stop(); //停止計時
detonateMine(w,h); //引爆所有雷
popDialog0(); //彈出對話框
break;
}
}
if(j == mines.length) { //未掃到雷
searchMine(i,k,w,h); //查找周邊雷並顯示
if(sum == x * y - num) { //遊戲勝利
time.stop(); //停止計時
if(Integer.parseInt(tm0.getText()) < max1)
addFile0(); // 記錄排名
popDialog0(); //彈出對話框
}
}
return;
}
}
}
}
}
/**
* 創建文件存儲對象
*/
class File0{
int a;
String s;
File0(){
a = 999999;
s = null;
}
}
/**
* 響應排行榜選項,打開排行榜
*/
void paiHang(){
int f10;
String type1=null,rerecord2=null;
if(num==10)
type1 = "簡單";
else if(num==40)
type1 = "中等";
else
type1 = "困難";
JDialog pq0 = new JDialog(getck(),type1+"排行榜",true);
pq0.setBounds(600, 300, 300, 200);
Box pq1 = Box.createVerticalBox();
pq1.add(Box.createVerticalStrut(30));
JLabel[] jl = new JLabel[3];
jl[0] = new JLabel();
jl[1] = new JLabel();
jl[2] = new JLabel();
try {
File file = new File("Rank",type1+"排行.txt");
FileReader af1 = new FileReader(file);
BufferedReader af2 = new BufferedReader(af1);
for(f10 = 0;(rerecord2 = af2.readLine())!=null;f10++) {
jl[f10].setText(" 姓名:"+rerecord2 +" 用時:"+af2.readLine()+"s");
pq1.add(jl[f10]);
}
af2.close();
af1.close();
}catch(Exception e) {}
pq0.add(pq1);
pq0.setVisible(true);
}
/**
* 添加排名文件
*/
void addFile0() {
JDialog addfile = new JDialog(getck(),"破紀錄!留下大名(最長8位)",true);
addfile.add(re);
addfile.setBounds(600, 300, 300, 200);
re.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
int f10;
String name0 = null;
if(num==10)
name0 = "簡單";
else if(num==40)
name0 = "中等";
else
name0 = "困難";
File file10 = new File("Rank");
file10.mkdir();
File file = new File(file10,name0+"排行.txt");
if(!file.exists())
file.createNewFile();
FileReader af1 = new FileReader(file);
BufferedReader af2 = new BufferedReader(af1);
String record1 = null,record2 = null;
//獲取最多8位字符
record2 = re.getText().substring(0, 8<re.getText().length()?8:re.getText().length());
File0[] f1 = new File0[3];
f1[0] = new File0();
f1[1] = new File0();
f1[2] = new File0();
for(f10 = 0;(record1 = af2.readLine())!=null;f10++) {
f1[f10].s = record1;
f1[f10].a = Integer.parseInt(af2.readLine());
}
for(f10 = 0;f10 < 3;f10++) {
if(f1[f10].a > Integer.parseInt(tm0.getText())) {
for(int f11 = 2;f11 > f10;f11--) {
f1[f11].a = f1[f11 - 1].a;
f1[f11].s = f1[f11 - 1].s;
}
break;
}
}
af2.close();
af1.close();
f1[f10].a = Integer.parseInt(tm0.getText());
if(record2==null || record2.equals(""))
record2="無名大蝦";
f1[f10].s = record2;
FileWriter af = new FileWriter(file);
BufferedWriter af0 = new BufferedWriter(af);
for(f10 = 0;f10 < 3;f10++) {
if(f1[f10].a==999999) {
continue;
}
af0.write(f1[f10].s);
af0.newLine();
af0.write(String.valueOf(f1[f10].a));
af0.newLine();
}
max1 = f1[2].a;
af0.close();
af.close();
}catch(Exception ee) {
System.out.println(ee.toString());
}
addfile.setVisible(false);
}
});
addfile.setVisible(true);
}
/**
* 遊戲失敗,彈出對話框
*/
void popDialog0() {
JDialog jCkou = new JDialog(getck(), "遊戲結束", true);
jCkou.setBounds(600, 300, 300, 200);
JButton b1,b2;
JLabel hint;
hint = new JLabel("您輸了,下次加油。",JLabel.CENTER);
b1 = new JButton("退出");
b2 = new JButton("再來一局");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ini();
jCkou.setVisible(false);
}
});
jCkou.setLayout(new FlowLayout());
Box b,c;
b = Box.createVerticalBox();
c = Box.createHorizontalBox();
if(sum == x * y - num) {
hint.setText("恭喜,您贏了! 用時:" + tm0.getText() + "s");
}
b.add(Box.createVerticalStrut(30));
b.add(hint);
b.add(Box.createVerticalStrut(60));
c.add(b1);
c.add(Box.createHorizontalStrut(80));
c.add(b2);
jCkou.add(b);
jCkou.add(c);
jCkou.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
ini();
jCkou.setVisible(false);
}
});
jCkou.setVisible(true);
}
/**
* 周邊數組,配合searchArray()使用
* @author ds_surk
*
*/
class Aa {
int a,b;
}
/**
* 調用該方法返回周邊位置數組
* @param i當前位置i
* @param k當前位置k
* @return 周邊位置數組
*/
Aa[] searchArray(int i,int k) {
Aa [] a;
a = new Aa[8];
for(int ia = 0;ia < a.length;ia++) {
a[ia] = new Aa();
a[ia].a = -1;
a[ia].b = -1;
}
if(i - 1 >= 0 && k - 1 >= 0 && !book[i-1][k-1]) {
a[0].a = i - 1;
a[0].b = k - 1;
}
if(i - 1 >= 0 && !book[i-1][k]) {
a[1].a = i - 1;
a[1].b = k;
}
if(i - 1 >= 0 && k + 1 < y && !book[i-1][k+1]) {
a[2].a = i - 1;
a[2].b = k + 1;
}
if(k - 1 >= 0 && !book[i][k-1]) {
a[3].a = i;
a[3].b = k - 1;
}
if(k + 1 < y && !book[i][k+1]) {
a[4].a = i;
a[4].b = k + 1;
}
if(i + 1 < x && k - 1 >= 0 && !book[i+1][k-1]) {
a[5].a = i + 1;
a[5].b = k - 1;
}
if(i + 1 < x && !book[i+1][k]) {
a[6].a = i + 1;
a[6].b = k;
}
if(i + 1 < x && k + 1 < y && !book[i+1][k+1]) {
a[7].a = i + 1;
a[7].b = k + 1;
}
return a;
}
/**
* 搜索周邊的雷,顯示出周邊雷數量
* 若當前點擊位置周邊無雷,則調用該方法自動"點擊"周邊按鈕,遞歸調用,直到周邊沒有無雷的按鈕。
*/
void searchMine(int i,int k,int w,int h) {
if(!book[i][k]) { //計數已點擊按鈕數
sum++;
}
book[i][k] = true; //標記當前位置
Aa[] a = searchArray(i,k).clone(); //返回周邊位置
int fa = 0; //周圍雷的數量
for(int jm = 0;jm < mines.length;jm++) {
for(Aa ia:a) {
if(ia.a == -1)
continue;
if(mines[jm] == ia.a * x + ia.b + 1) {
fa++;
break;
}
}
}
//按照相應的雷數替換相應圖片
switch(fa) {
case 1:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d1.jpg",w,h));
break;
case 2:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d2.jpg",w,h));
break;
case 3:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d3.jpg",w,h));
break;
case 4:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d4.jpg",w,h));
break;
case 5:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d5.jpg",w,h));
break;
case 6:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d6.jpg",w,h));
break;
case 7:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d7.jpg",w,h));
break;
case 8:
biu[i][k].setIcon(setImageSize0("Image\\SaoLei\\d8.jpg",w,h));
break;
case 0:
biu[i][k].setIcon(new ImageIcon(""));
for(Aa ia:a) {
if(ia.a == -1)
continue;
searchMine(ia.a,ia.b,w,h); //遞歸調用
}
break;
} //switch
}
/**
* 引爆所有的雷
*/
void detonateMine(int w,int h) {
for(int ii = 0;ii < x;ii++) { //引爆所有雷
for(int kk = 0;kk < y;kk++) {
for(int jj = 0;jj < mines.length;jj++) {
if(ii*x+kk+1 == mines[jj]) {
book[ii][kk] = true;
biu[ii][kk].setIcon(setImageSize0("Image\\SaoLei\\2.jpg",w,h));
// try {
// Thread.sleep(200); //延時執行
// }catch(Exception ee) {}
}
}
}
}
}
/**
* 設置網格行列
* @param x = row
* @param y = column
*/
void setGrid(int x,int y) {
this.x = x;
this.y = y;
}
/**
* 隨機產生mine位置
* @param q爲設置的mine數
*/
void setRand(int q) {
mines = new int[q];
for(int i:mines) i = 0;
mines[0] = -1;
for(int i = 0;i < mines.length;i++) {
int rand = 0,j;
boolean flag = false;
while(!flag) {
rand = (int)(Math.random()*x*y);
if(rand <= 0 || rand > x*y) continue;
if(mines[i]==-1) break;
for(j = 0;j < mines.length;j++) {
if(rand == mines[j])
break;
}
if(j == mines.length) flag = true;
}
mines[i] = rand;
}
Arrays.sort(mines);
}
/**
* 重新初始化
*/
void ini() {
ls.setVisible(false); //隱藏當前容器
remove(ls); //移除當前容器
time.stop(); //停止計時
init1(); //重新初始化
}
/**
* 響應設置選項,啓動設置窗口
* @author ds_surk
*
*/
class Set0 implements ActionListener{
JPanel setJ;
JLabel setJi;
JButton j,j0;
JRadioButton j1 = new JRadioButton("簡單:9X9網格,10個雷"); //單選按鈕
JRadioButton j2 = new JRadioButton("中等:16X16網格,40個雷");
JRadioButton j3 = new JRadioButton("困難:16X30網格,99個雷");
Box b,b1;
ButtonGroup bg = new ButtonGroup(); //按鈕組
JRadioButton jc = j1,ja = j1; //存儲所選選項
class Se extends JFrame implements ItemListener{
Se(){}
Se(String s,int x,int y,int width,int height){
inits(s);
setBounds(x,y,width,height);
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(2);
}
void inits(String s) {
setTitle(s);
setIconImage(getToolkit().getImage("Image\\SaoLei\\Se.jpg"));
setJ = new JPanel();
b = Box.createVerticalBox();
b1 = Box.createHorizontalBox();
setJi = new JLabel("難度:",JLabel.CENTER);
j = new JButton("確定");
j0 = new JButton("取消");
bg.add(j1);
bg.add(j2);
bg.add(j3);
jc.setSelected(true);
j.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jc = ja;
jc.setSelected(true);
if(jc == j1) {
x = y = 9;
num = 10;
}
else if(jc == j2) {
x = y = 16;
num = 40;
}
else {
x = 16;
y = 30;
num = 99;
}
ini();
dispose(); //銷燬窗口
}
});
j0.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
j1.addItemListener(this);
j2.addItemListener(this);
j3.addItemListener(this);
b.add(Box.createVerticalStrut(10));
b.add(setJi);
b.add(Box.createVerticalStrut(10));
b.add(j1);
b.add(Box.createVerticalStrut(5));
b.add(j2);
b.add(Box.createVerticalStrut(5));
b.add(j3);
b.add(Box.createVerticalStrut(30));
b1.add(j);
b1.add(Box.createHorizontalStrut(80));
b1.add(j0);
setJ.add(b);
setJ.add(b1);
add(setJ);
}
public void itemStateChanged(ItemEvent e) {
ja = (JRadioButton)e.getSource();
}
}
public void actionPerformed(ActionEvent e) {
Se se = new Se("設置",700,400,300,300);
}
} //Set0
} //GuiSl
/**
* 響應help選項,啓動說明界面
* @author ds_surk
*
*/
class Help implements ActionListener{
class Hel extends JFrame{
Hel(){}
Hel(String s,int x,int y,int width,int height){
inits(s);
setBounds(x,y,width,height);
setVisible(true);
setDefaultCloseOperation(2); //設置關閉方式爲關閉當前窗口
}
void inits(String s) {
setTitle(s);
setIconImage(getToolkit().getImage("Image\\SaoLei\\help.jpg"));
JPanel jp0=new JPanel();
JPanel jp1=new JPanel();
Box jBox0 = Box.createVerticalBox();
JButton j = new JButton("確定");
jBox0.add(Box.createHorizontalStrut(35));
jBox0.add(Box.createVerticalStrut(35));
jBox0.add(new JLabel("本程序爲自制遊戲,作爲Java語言學習檢驗。",JLabel.CENTER));
jBox0.add(Box.createVerticalStrut(5));
jBox0.add(new JLabel("玩法與掃雷相同。",JLabel.CENTER));
jBox0.add(Box.createVerticalStrut(15));
jBox0.add(new JLabel("如有疑問,請聯繫開發者。",JLabel.CENTER));
jBox0.add(Box.createVerticalStrut(5));
jBox0.add(new JLabel("開發者:ds_surk",JLabel.CENTER));
jBox0.add(Box.createVerticalStrut(10));
jp1.add(j);
jBox0.add(jp1);
jp0.add(jBox0);
j.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose(); //關閉當前窗口
} });
add(jp0);
}
}
public void actionPerformed(ActionEvent e) {
Hel he = new Hel("Help",570,300,300,260);
}
}
/**
* 響應關於選項,啓動說明界面
* @author ds_surk
*
*/
class GYu implements ActionListener{
class Gyu extends JFrame{
Gyu(){}
Gyu(String s,int x,int y,int width,int height){
inits(s);
setBounds(x,y,width,height);
setVisible(true);
setDefaultCloseOperation(2); //設置關閉方式爲關閉當前窗口
}
void inits(String s) {
setTitle(s);
setIconImage(getToolkit().getImage("Image\\SaoLei\\gyu.jpg"));
JPanel jp0=new JPanel();
JPanel jp1 = new JPanel();
Box jBox = Box.createVerticalBox();
JLabel title = new JLabel("本程序由Java語言編寫!",JLabel.CENTER);
JButton j = new JButton("確定");
jBox.add(Box.createHorizontalStrut(35));
title.setIcon(new ImageIcon("Image\\SaoLei\\index.jpg"));
jBox.add(title);
jBox.add(Box.createVerticalStrut(5));
jBox.add(new JLabel("——————————————",JLabel.CENTER));
jBox.add(new JLabel("名稱:掃雷"));
jBox.add(Box.createVerticalStrut(5));
jBox.add(new JLabel("版本:1.0"));
jBox.add(Box.createVerticalStrut(5));
jBox.add(new JLabel("開發者:ds_surk"));
jBox.add(Box.createVerticalStrut(5));
jBox.add(new JLabel("版權所有,未經許可,禁止作爲商用。",JLabel.CENTER));
jBox.add(Box.createVerticalStrut(10));
jp1.add(j);
jBox.add(jp1);
jp0.add(jBox);
j.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose(); //關閉當前窗口
} });
add(jp0);
}
}
public void actionPerformed(ActionEvent e) {
Gyu yu = new Gyu("關於",590,400,280,280);
}
}
本文未經允許,不可轉載,或作爲他用。
附上打包鏈接(可直接使用):https://download.csdn.net/download/hunt_er/10589346