继《通过一个游戏编程熟悉事件处理》http://blog.csdn.net/flyuniverse_shell/archive/2009/10/23/4719939.aspx
《通过一个游戏编程熟悉文件操作》 http://blog.csdn.net/flyuniverse_shell/archive/2009/11/02/4758566.aspx 之后
我们完成第三个目标,请同行指点。代码如下:
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
class GameButton extends JButton
{
GameButton(String str)
{
super(str);
super.setSize(10, 10);
super.setBackground(Color.WHITE);
super.setFont(new java.awt.Font("Dialog", 1, 60));// 设置字体
}
}
public class MyGame extends JFrame implements ActionListener
{
private JFrame f = new JFrame("Game-Java 实现");
private JPanel jp = new JPanel(new GridLayout(5, 3, 10, 10));
private GameButton[] gb = new GameButton[9];
private int[][] relationShips = new int[9][];
private JButton JBSaveOperation = new JButton("保存操作记录");
private File fileSave = null; // 游戏记录文件
private StringBuffer tempSaveStrB = new StringBuffer(); // 暂时保存操作,最终会保存到fileSave中去
private JButton JBShowLast = new JButton("显示上一局");; // 显示上一局
private JButton JBRestart = new JButton("重新开始");; // 重新开始
private JLabel JLshowLastRecord = new JLabel("操作序列:"); // 显示操作过程
private Thread showLastThread = null; // 上一局游戏新线程
private JLabel JLshowRecordThread = new JLabel("操作序列:"); // 与线程同步显示
private BufferedReader in; //取记录的输入流
private String line; //从记录文件中读取的记录的用户游戏记录
MyGame()
{
f.setLocation(10, 100);
f.setSize(600, 400);
f.getContentPane().add(jp);
for (int i = 0; i < gb.length; i++)
{
gb[i] = new GameButton("-");
jp.add(gb[i]);
gb[i].addActionListener(this); // 添加按钮事件
}
gb[4].setText("+");
JBSaveOperation.addActionListener(this);
JBShowLast.addActionListener(this);
JBRestart.addActionListener(this);
jp.add(JBSaveOperation);
jp.add(JLshowLastRecord);
jp.add(JBShowLast);
jp.add(JBRestart);
jp.add(JLshowRecordThread);
f.setVisible(true);
relationShips[0] = new int[] { 0, 1, 3, 4 };
relationShips[1] = new int[] { 0, 1, 2 };
relationShips[2] = new int[] { 1, 2, 4, 5 };
relationShips[3] = new int[] { 0, 3, 6 };
relationShips[4] = new int[] { 1, 3, 4, 5, 7 };
relationShips[5] = new int[] { 2, 5, 8 };
relationShips[6] = new int[] { 3, 4, 6, 7 };
relationShips[7] = new int[] { 6, 7, 8 };
relationShips[8] = new int[] { 4, 5, 7, 8 };
fileSave = new File("game.txt");
if (!fileSave.exists())
{
try
{
fileSave.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
MyGame g = new MyGame();
}
public void begin()
{
for (int i = 0; i < gb.length; i++)
{
gb[i].setText("-");
}
gb[4].setText("+");
tempSaveStrB.delete(0, tempSaveStrB.length());
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource().equals(JBSaveOperation))// 如果点击的是“保存操作”按钮
{
if (writeFile())
{
JOptionPane.showMessageDialog(null, "写文件成功!");
} else
JOptionPane.showMessageDialog(null, "写文件失败!");
}
if (e.getSource().equals(JBRestart))// 如果点击的是“重新开始”按钮
{
begin();
JLshowLastRecord.setText("操作序列:");
}
if (e.getSource().equals(JBShowLast))// 如果点击的是“显示上一局”按钮
{
try
{
in=new BufferedReader(new FileReader("game.txt"));
} catch (FileNotFoundException e2)
{
e2.printStackTrace();
}
try
{
line=in.readLine();
} catch (IOException e2)
{
e2.printStackTrace();
}
if (line != null)
{
begin();
// 显示上一局游戏记录时先撤销方格按钮的响应事件
for (int i = 0; i < gb.length; i++)
{
gb[i].removeActionListener(this);
}
showLastThread = new Thread("showLastThread")
{
public void run()
{
JLshowLastRecord.setText("上一局的操作顺序为:" + line
+ " 每隔2秒显示一个步骤");
JLshowRecordThread.setText("当前执行到:");
String[] tokens = line.split(",");
int s = 0;
for (int i = 0; i < tokens.length; i++)
{
s = Integer.parseInt(tokens[i]);
if (i == tokens.length - 1)
JLshowRecordThread.setText(JLshowRecordThread.getText() + s);
else
JLshowRecordThread.setText(JLshowRecordThread.getText() + s + ">>");
try
{
Thread.sleep(1000); // 设置停顿1秒
ButtonChange(s);// 进行方格翻转
Thread.sleep(1000);// 设置停顿1秒
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
}
}
};
showLastThread.start(); // 启动显示上局游戏结果线程
}
else
{JOptionPane.showMessageDialog(null, "操作记录为空!");}
}
for (int i = 0; i < 9; i++)
{
if (e.getSource().equals(gb[i])) // 如果点中第i个
{
if (gb[i].getText().equals("-"))
{
JOptionPane.showMessageDialog(null, "你应该点“+”的");
return;
}
ButtonChange(i);
tempSaveStrB.append(i + ",");
JLshowLastRecord.setText("操作序列:" + tempSaveStrB.toString());
if (isWin())
{
JOptionPane.showMessageDialog(null, "你赢了!");
over();
if (writeFile())
{
JOptionPane.showMessageDialog(null, "写文件成功!");
} else
JOptionPane.showMessageDialog(null, "写文件失败!");
}
if (isFail())
{
JOptionPane.showMessageDialog(null, "你输了!");
over();
}
}
}
}
private boolean writeFile()
{
BufferedWriter writer;
try
{ // 记录游戏结果 写进游戏记录文档
writer = new BufferedWriter(new FileWriter("game.txt"));
writer.write(tempSaveStrB.toString());
writer.newLine();
writer.close();
} catch (IOException ex)
{
ex.printStackTrace();
return false;
}
return true;
}
private boolean isFail()
{
int count = 0;
for (int i = 0; i < gb.length; i++)
{
if (gb[i].getText().equals("-"))
count++;
}
if (9 == count)
return true;
else
return false;
}
private void over()
{
for(int i=0;i<gb.length;i++)
{
gb[i].setEnabled(false);
}
}
private boolean isWin() // 遍历所有Button
{
int count = 0;
for (int i = 0; i < gb.length; i++)
{
if (gb[i].getText().equals("+"))
count++;
}
if (8 == count && gb[4].getText().equals("-"))
return true;
else
return false;
}
private void ButtonChange(int i)
{
for (int j = 0; j < relationShips[i].length; j++)
{
if (gb[relationShips[i][j]].getText().equals("+"))
{
gb[relationShips[i][j]].setText("-");
}
else
{
gb[relationShips[i][j]].setText("+");
}
}
}
}