8-1 三子棋
编写程序,实现简单的三子棋游戏。在三子棋中,双方在3×3的棋盘中轮流下棋,一方用*示,另一方用O表示。如果一方的3个棋子占据了同一行,同一列或者对角线,则该方获胜。如果棋盘已被棋子占满,但没有一方获胜则出现平局。在程序中,一方为用户,用户在界面上输入每次下棋的位置;另一方下棋的位置为随机自动生成。示例界面如图所示。
提示:(1) 采用Scanner类或者JOptionPane类中提供的方法输入,输出采用System.out中的方法或JOptionPane类提供的方法。
(2) 字符串处理可以使用String或StringBuffer类。
这里因为最大只有九步,所以可以用一个三维数组来储存所有的步数,方便撤销
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Game extends JFrame{
private JButton sendBtn;
private JButton backBtn;
private JTextField inputField;
char[][][] map = new char[10][][];
int step = 0;
public Game(){
Random rd = new Random();
sendBtn = new JButton("确定");
sendBtn.setBorderPainted(true);
backBtn = new JButton("撤销");
backBtn.setBorderPainted(true);
inputField = new JTextField(10);
map[0] = new char[][] { {'0', '1', '2'}, {'3', '4', '5'}, {'6', '7', '8'} };
JPanel boardPanel = new JPanel();
JPanel inputPanel = new JPanel();
inputPanel.add(inputField);
inputPanel.add(sendBtn);
inputPanel.add(backBtn);
inputPanel.setBackground(new Color(10,10,10));
String s = "";
s+="<html> -------------- <br>";
s+="| " + map[step][0][0] + " | " + map[step][0][1] + " | " + map[step][0][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][1][0] + " | " + map[step][1][1] + " | " + map[step][1][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][2][0] + " | " + map[step][2][1] + " | " + map[step][2][2] + " |" + "<br>";
s+=" -------------- <br>";
JLabel label = new JLabel(s);
boardPanel.add(label);
sendBtn.addActionListener(new ActionListener() {
//判断对局情况
public int judge(){
//colum
for(int i=0;i<=2;i++){
if(map[step][i][0] == '*' && map[step][i][1] == '*' && map[step][i][2] == '*'){
return 1;
}
if(map[step][i][0] == 'O' && map[step][i][1] == 'O' && map[step][i][2] == 'O'){
return -1;
}
if(map[step][0][i] == '*' && map[step][1][i] == '*' && map[step][2][i] == '*'){
return 1;
}
if(map[step][0][i] == 'O' && map[step][1][i] == 'O' && map[step][2][i] == 'O'){
return -1;
}
}
if(map[step][0][0] == map[step][1][1] && map[step][2][2] == map[step][1][1] && map[step][1][1] == '*'){
return 1;
}
if(map[step][0][0] == map[step][1][1] && map[step][2][2] == map[step][1][1] && map[step][1][1] == 'O'){
return -1;
}
if(map[step][0][2] == map[step][1][1] && map[step][2][0] == map[step][1][1] && map[step][1][1] == '*'){
return 1;
}
if(map[step][0][2] == map[step][1][1] && map[step][2][0] == map[step][1][1] && map[step][1][1] == 'O'){
return -1;
}
return 0;
}
//获取新游戏面板
public String update(){
String s = "";
s+="<html> -------------- <br>" ;
s+="| " + map[step][0][0] + " | " + map[step][0][1] + " | " + map[step][0][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][1][0] + " | " + map[step][1][1] + " | " + map[step][1][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][2][0] + " | " + map[step][2][1] + " | " + map[step][2][2] + " |" + "<br>";
s+=" -------------- <br>";
return s;
}
@Override
public void actionPerformed(ActionEvent e) {
//输入坐标
int position;
int x;
int y;
try{
position = Integer.parseInt(inputField.getText());
x = position/3;
y = position%3;
}catch(Exception err){
JOptionPane.showMessageDialog(null, "请输入数字");
return ;
}
//检查合法
if(position >= 9 || position < 0){
JOptionPane.showMessageDialog(null, "别乱输入数字");
inputField.setText("");
return ;
}
if(map[step][x][y] == '*' || map[step][x][y] == 'O' ){
JOptionPane.showMessageDialog(null, "这里已经下过了嗷");
inputField.setText("");
return ;
}
//更新游戏数据
step++;
map[step] = new char[3][];
for(int i=0;i<=2;i++){
map[step][i] = Arrays.copyOf(map[step-1][i],map[step-1][i].length);
}
map[step][x][y] = '*';
int robt = rd.nextInt(9);
while(map[step][robt/3][robt%3] == '*' || map[step][robt/3][robt%3] == 'O'){
robt++;
robt%=9;
if(step == 5){
break;
}
}
if(step != 5){
map[step][robt/3][robt%3] = 'O';
}
//更新游戏面板
inputField.setText("");
boardPanel.removeAll();
JLabel label = new JLabel(update()) ;
boardPanel.add(label);
boardPanel.updateUI();
//判断对局情况
if(judge() == 1){
JOptionPane.showMessageDialog(null, "大聪明,你赢了");
return ;
}
if(judge() == -1){
JOptionPane.showMessageDialog(null, "机器人都打不过?");
return ;
}
if(step == 5){
JOptionPane.showMessageDialog(null, "平局");
}
}
});
backBtn.addActionListener(new ActionListener() {
//获取新游戏面板
public String update(){
String s = "";
s+="<html> -------------- <br>" ;
s+="| " + map[step][0][0] + " | " + map[step][0][1] + " | " + map[step][0][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][1][0] + " | " + map[step][1][1] + " | " + map[step][1][2] + " |" + "<br>";
s+=" -------------- <br>";
s+="| " + map[step][2][0] + " | " + map[step][2][1] + " | " + map[step][2][2] + " |" + "<br>";
s+=" -------------- <br>";
return s;
}
@Override
public void actionPerformed(ActionEvent e) {
if(step == 0){
JOptionPane.showMessageDialog(null, "还点??");
return;
}
--step;
boardPanel.removeAll();
JLabel label = new JLabel(update());
boardPanel.add(label);
boardPanel.updateUI();
}
});
this.add(inputPanel,BorderLayout.SOUTH);
this.add(boardPanel,BorderLayout.NORTH);
this.setTitle("三子棋");
this.setSize(280,220);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
public class Main{
public static void main(String[] args){
new Game();
}
}
8-3 绘制随机图形
定义4个类,MyShape、MyLine、MyRectangle和MyOval,其中MyShape是其他三个类的父类。MyShape为抽象类,包括图形位置的四个坐标;一个无参的构造方法,将所有的坐标设置为0;一个带参的构造函数,将所有的坐标设置为相应值;每个坐标的设置和读取方法;abstract void draw(Graphics g)方法。MyLine类负责画直线,实现父类的draw方法;MyRectangle负责画矩形,实现父类的draw方法;MyOval负责画椭圆,实现父类的draw方法。编写一个应用程序,使用上面定义的类,随机选取位置和形状,绘制20个图形。示例输出如图所示。
提示:可以使用ArrayList来保存要绘制的多个图形。
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
abstract class MyShape{
int x = 0;
int y = 0;
int z = 0;
int k = 0;
public MyShape(){
;
}
public abstract void draw(Graphics g);
}
class MyLine extends MyShape{
Random rd = new Random();
@Override
public void draw(Graphics g){
g.drawLine(x,y,z,k);
}
public MyLine(){
int _x = rd.nextInt(200);
int _y = rd.nextInt(200);
int _z = rd.nextInt(200);
int _k = rd.nextInt(200);
x = _x;
y = _y;
z = _z;
k = _k;
}
}
class MyRectangle extends MyShape{
Random rd = new Random();
@Override
public void draw(Graphics g){
g.drawRect(x,y,z,k);
}
public MyRectangle(){
int _x = rd.nextInt(200);
int _y = rd.nextInt(200);
int _z = rd.nextInt(200);
int _k = rd.nextInt(200);
x = _x;
y = _y;
z = _z;
k = _k;
}
}
class MyOval extends MyShape{
Random rd = new Random();
@Override
public void draw(Graphics g){
g.drawOval(x,y,z,k);
}
public MyOval(){
int _x = rd.nextInt(200);
int _y = rd.nextInt(200);
int _z = rd.nextInt(200);
int _k = rd.nextInt(200);
x = _x;
y = _y;
z = _z;
k = _k;
}
}
class DrawComponent extends JComponent
{
@Override
public void paintComponent(Graphics g)
{
for(int i=0;i<20;i++) {
if(i<6) {
MyOval mo = new MyOval();
mo.draw(g);
}
else if(i<12) {
MyRectangle mr = new MyRectangle();
mr.draw(g);
}
else {
MyLine ml = new MyLine();
ml.draw(g);
}
}
}
}
class Game extends JFrame{
Random rd = new Random();
public Game(){
this.add(new DrawComponent());
this.setSize(600,600);
this.setTitle("Graphics");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
public class Main1{
public static void main(String [] args){
new Game();
}
}
8-4 猜数游戏
编写一个猜数程序,该程序随机在1到1000的范围中选择一个供用户猜测的整数。界面上提供一个文本框来接收用户输入的猜测的数,如果用户猜得太大,则背景变为红色,如果猜得太小,背景变为蓝色。用户猜对后,文本框变为不可编辑,同时提示用户猜对了。界面上提供一个按钮,使用户可以重新开始这个游戏。在界面上还需显示用户猜测的次数。示例输出如图所示。
实验步骤:
(1) 定义继承自JFrame的类,在该类中添加界面各部分;
(2) 定义事件监听器类完成事件处理;
(3) 定义一个包含main方法的测试类,在该类中创建框架类对象,并显示。
实验提示:
(1) 使用面板进行页面布局;
(2) 可以使用内部类定义事件监听器类;
(3) 按钮点击通过处理ActionEvent事件来完成响应。
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Game extends JFrame{
private JButton sendBtn;
private JButton restartBtn;
private JButton quitBtn;
private JTextField inputField;
int num;
public Game(){
Random rd = new Random();
this.num = rd.nextInt(1000);
//options
JPanel optionPanel = new JPanel();
sendBtn = new JButton("send");
restartBtn = new JButton("restart");
quitBtn = new JButton("quit");
optionPanel.add(sendBtn);
optionPanel.add(restartBtn);
optionPanel.add(quitBtn);
//enter
JPanel inputPanel = new JPanel();
inputField = new JTextField(10);
JLabel label = new JLabel("please enter a num :");
inputPanel.add(label);
inputPanel.add(inputField);
//sendBtn
sendBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//enter num
int get;
try{
get = Integer.parseInt(inputField.getText());
}catch(Exception err){
JOptionPane.showMessageDialog(null, "please enter Number");
return ;
}
if(get > num){
JOptionPane.showMessageDialog(null, "bigger");
return ;
}
if(get < num){
JOptionPane.showMessageDialog(null, "smaller");
return ;
}
if(get == num){
JOptionPane.showMessageDialog(null, "correct");
return ;
}
}
});
restartBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
num = rd.nextInt(1000);
JOptionPane.showMessageDialog(null, "done!");
}
});
quitBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//system
this.add(optionPanel,BorderLayout.SOUTH);
this.add(inputPanel,BorderLayout.CENTER);
this.setTitle("guess");
this.setSize(280,220);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
public class Main2{
public static void main(String [] args){
new Game();
}
}