问题
We are working on a Treasure Hunt game in class as a project. Below is the code that we have so far. I need to randomize where the Treasure Buttons are. My question is: Do I need to create an array that will hold EmptyButton and TreasureButton and then call Random on it or is there a way to create a random layout within the TreasureButton class?
Here is our code so far
public class TreasureGame
{
// has-a number of tries
private int numberOfTriesLeft = 50;
//has-a number of hidden treasure
private int numberStillHidden = 20;
// Purpose: Subtract 1 try for every attempt taken by the player
public void reduceTriesLeft()
{
numberOfTriesLeft -= 1;
}
public void reduceNumberStillHidden()
{
numberStillHidden -=1;
}
public int getNumberStillHidden()
{
return numberStillHidden;
}
public int getNumberOfTriesLeft()
{
return numberOfTriesLeft;
}
}
import java.awt.*;
import javax.swing.*;
import java.util.Random;
public class TreasureGameView extends JFrame
{
// has-a TreasureGame
private TreasureGame treasureGame;
//has-a triesLeftField
private JTextField triesLeftField;
//has-a treasures left field
private JTextField treasuresLeftField;
private JTextField lastMoveField;
public TreasureGameView(TreasureGame newTreasureGame)
{
treasureGame = newTreasureGame;
setTitle("Treasure Hunt");
setSize(800, 500);
setLayout(new BorderLayout());
JPanel gridPanel = new JPanel();
gridPanel.setLayout(new GridLayout(10, 10));
add(gridPanel, BorderLayout.CENTER);
for(int counter=0; counter<treasureGame.getNumberStillHidden(); counter++)
{
gridPanel.add(new TreasureButton(treasureGame, this));
}
for(int counter=0; counter<(10*10)-treasureGame.getNumberStillHidden(); counter++)
{
gridPanel.add(new EmptyButton(treasureGame, this));
}
JPanel triesLeftPanel = new JPanel();
JLabel triesLeftLabel = new JLabel("Tries left:");
triesLeftPanel.add(triesLeftLabel);
triesLeftField = new JTextField("" + treasureGame.getNumberOfTriesLeft());
triesLeftPanel.add(triesLeftField);
JLabel treasuresLeftLabel = new JLabel("Treasures left:");
triesLeftPanel.add(treasuresLeftLabel);
treasuresLeftField = new JTextField("" + treasureGame.getNumberStillHidden());
triesLeftPanel.add(treasuresLeftField);
add(triesLeftPanel, BorderLayout.WEST);
JPanel lastMovePanel = new JPanel();
JLabel lastMoveLabel = new JLabel("Your last move was: ");
lastMovePanel.add(lastMoveLabel);
lastMoveField = new JTextField("" );
lastMovePanel.add(lastMoveField);
add(lastMovePanel, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
//Purpose; Update Value of triesLeftField
public void updateUI()
{
triesLeftField.setText("" + treasureGame.getNumberOfTriesLeft());
treasuresLeftField.setText("" + treasureGame.getNumberStillHidden());
}
}
import javax.swing.*;
public class EmptyButton extends JButton
{
//has-a TreasureGame
private TreasureGame game;
//has-a TreasureGameView
private TreasureGameView gameView;
public EmptyButton(TreasureGame game, TreasureGameView gameView)
{
super();
this.game = game;
this.gameView = gameView;
//setText("?");
addActionListener(new EmptyButtonListener(this, game, gameView));
}
}
public class TreasureButton extends EmptyButton
{
public TreasureButton(TreasureGame game, TreasureGameView gameView)
{
super(game, gameView);
//setText("T");
addActionListener(new TreasureButtonListener(this, game, gameView));
}
}
import java.awt.event.*;
public class EmptyButtonListener implements ActionListener
{
private EmptyButton button;
//has-a TreasureGame
private TreasureGame game;
//has-a TreasureGameView
private TreasureGameView gameView;
public EmptyButtonListener(EmptyButton button, TreasureGame game, TreasureGameView gameView)
{
this.game = game;
this.button = button;
this.gameView = gameView;
}
public void actionPerformed(ActionEvent e)
{
//button.setText("X");
button.setEnabled(false);
game.reduceTriesLeft();
gameView.updateUI();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TreasureButtonListener implements ActionListener
{
// Has-a TreasureButton
private TreasureButton button;
private TreasureGame game;
private TreasureGameView gameView;
public TreasureButtonListener(TreasureButton button, TreasureGame game, TreasureGameView gameView)
{
this.button = button;
this.game = game;
this.gameView = gameView;
}
public void actionPerformed(ActionEvent e)
{
button.setText("$");
game.reduceNumberStillHidden();
gameView.updateUI();
}
}
回答1:
You have to think in terms of MVC.
First create a model for your treasure. This could be an array of class Field. .
A field would represent weather it has a treasure and a state (eg. revealed)
Populate the array with the fields from which 20 are representing an treasure.
Shuffle the array.
Your view will then iterate over the array and represents the model in a user friendly way. For ease you can pass the field instance to your button to manipulate the field state in your actionlistener.
回答2:
The answer is mostly opinion based. Better to maintain a List<Buttons> buttons
and store both empty
and TreasureButton
inside it. Whenever you need to randomize it, use Collections.shuffle(buttons)
to shuffle. As the action remains same you don't need to create button every time. Just shuffle it and display in grid by iteration that list.
来源:https://stackoverflow.com/questions/64952221/creating-a-grid-layout-that-holds-100-buttons-with-80-empty-buttons-and-20-rando