How to access a method with parameters? - java

I am creating a Dice Game as a project in IntelliJ with Java and right now I have a method in the Game class, where I want to reset the Dice Cup in the beginning of the game. Therefore, I have created a method called resetDiceCup() and a method called startGame().
Right now, I am getting the error "Identifier expected" in startGame() and I think it has something to do with the parameters I use in resetDiceCup().
Is there any way to fix this?
public class Game{
public void startGame() {
resetDiceCup( int doublets, int numOfDoublets);
System.out.println("Willkommen zu diesem Würfelspiel. Los geht´s!");
String[] playerNames = Print.multipleAnswers("Please insert the name of a player.");
player = new Player[playerNames.length];
for (int i = 0; i < playerNames.length; i++)
{
player[i] = new Player(playerNames[i]);
}
}
//to "refresh" the DiceCup before every new game
public void resetDiceCup(int doublets, int numOfDoublets) {
int[] result = new int[numOfDices]; //amout of dices in the game as chosen by players
sum = 0;
doublets = 0;
numOfDoublets = 0;
sumWithDoublets = 0;
}
}

Related

How do I have two methods in separate classes wait before continuing execution?

I have two classes, BlackJack and BlackJackPane, BlackJack has a method called dealCards() which gives a class called Player a Card by looping from the first Player to the last Player twice like in a real game of blackjack where each player is dealt one card at a time.
The BlackJackPane is a JFrame that contains JButtons and JLabels. The JButton deal when clicked has a .actionCommand("deal") and an ActionListener with a Lambda expression that calls the instance variable blackjack in BlackJackPane to deal cards, blackjack.dealCards(). The ActionListener also determines what kind of card from a regular 52 card deck the Player was dealt to display the proper Card the Player has.
I would PREFER to have the dealCards() method in BlackJack wait after passing a Card to a Player for a JLabel to be created and displayed in the JFrame, however, I do not know how to make this work across classes. I am open to other creative options or tips on how to improve my code.
I am trying to keep the classes encapsulated and I/O confined in BlackJackPane.
This is my class BlackJack
public class BlackJack
{
private final Deck deck;
private final ArrayList<Player> player;
private final int numOfPlayers;
public BlackJack(int players)
{
this.numOfPlayers = players + 1; // +1 for dealer, dealer is always first in arrayList
this.deck = new Deck(Deck.TYPE[0]);
this.player = new ArrayList();
for (int i = 0; i < players + 1; i++)
{
this.player.add(new Player((i == 0))); //i == 0 is to say true to Player constructor that it is the dealer or cpu
}
}
public void DealCards()
{
deck.shuffle();
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < player.size(); j++)
{
player.get(j).getHand().add(deck.getCard(0));
deck.remove(0);
}
}
}
}
This is the BlackJackPane
public class BlackJackPane extends JFrame
{
private BlackJack blackjack;
private JLabel pokerTable;
private JButton hit, stay, split, deal, hiddenCard;
public BlackJackPane(BlackJack blackjack) throws IOException
{
this.blackjack = blackjack;
display();
}
private void display() throws IOException
{
deal.addActionListener((event) ->
{
if (event.getActionCommand().equals("deal"))
{
blackjack.DealCards();
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < blackjack.getNumOfPlayers(); j++)
{
if (blackjack.getPlayer(j).isCpu() && i != 1) //One card dealer has is face down
{
} else
{
if (blackjack.getPlayer(j).getHand().get(i).getFace() == 0) // face = 2
{
if (blackjack.getPlayer(j).getHand().get(i).getSuit() == 0) //clubs
{
//Code to make and display the JLabel within the JFrame
} else if (blackjack.getPlayer(j).getHand().get(i).getSuit() == 1) //diamonds
{
} else if (blackjack.getPlayer(j).getHand().get(i).getSuit() == 2) //hearts
{
} else //spades
{
}
} else if() //and so on for 52 cards
}
}
}
}
});
}
}
You could redefine your dealCards method to take some callback to be invoked after each card is dealt.
public void dealCards(BiConsumer<Player, Card> onDealtCallback) {
for (Player player : players) {
Card dealt = this.getNextCardToDeal();
onDealtCallback.accept(player, dealt);
}
}
And then invoke it with something like:
public void callIt() {
this.blackJack.dealCards(this::drawLabel);
}
public void drawLabel(Player player, Card card) {
// TODO
}
I can't say this is the most object-oriented approach, and it doesn't give a nice separation of state and UI. But it should do what you're trying to do.
(Note: this isn't the place for code review, so I'm resisting the urge to offer further suggestions on 'how to improve your code'.)

java blackjack pair hand

So basically I'm trying to test to see if my hand of 5 cards has a pair in it (two cards have the same value (1-9)) and I'm getting an unknown error and this is my code
Error:
java.lang.AssertionError at org.junit.Assert.fail(Assert.java:86)...
Code:
public static boolean hasPair(Card[] cards) {
Deck theDeck = new Deck();
cards = theDeck.deal(5);
int k=0;
for (int atPos = 0; atPos<5; atPos++){
for (int atPos2 = atPos+1; atPos2<5; atPos2++){
if(cards[atPos].getValue() == cards[atPos2].getValue()){
k++;
}
}
}
if (k==2){
return true;
}
else {
return false;
}
JUnit that is failing
#Test
public void testExampleTest_SinglePairTest() {
Card[] testHand = new Card[5];
testHand[0] = new Card(1,1);
testHand[1] = new Card(2,1);
testHand[2] = new Card(2,1);
testHand[3] = new Card(4,1);
testHand[4] = new Card(5,1);
assertTrue(HandEvaluatorBBXP.hasPair(testHand));
It seems like there's no point in passing in Card[] cards as an argument to the hasPair method because you immediately set the variable to whatever deck.deal() returns. So the incoming value is never used.
This could well be the reason your test is failing, because your test data what the hasPair method is actually using to evaluate the test with.

How to retrieve value changes made from a For Loop within it's own method in Android Studio?

I have a for loop within my main activity that is used to randomly shuffle/reassign the values within an array at the beginning of every time the application is opened.
I was told that for loops in Android Studio could only exist within a method (after getting errors when it was placed without one), but by doing so the random shuffling of the array is not carried over to the rest of the click events that are outside of the method and it just continues to output the same originally assigned values of in the array.
int[] money = {1,10,5,2,20,500,50,100,1000000,5000,1000,50000,100000,500000,250000,10000};
int swap1;
int swap2;
int temp;
Random random = new Random();
void what(){
for (int j=0;j<16;j+=1)
{
swap1 = random.nextInt(16);
swap2 = random.nextInt(16);
temp = money[swap1];
money[swap1] = money[swap2];
money[swap2] = temp;
}
}
The click events that are using the values from this array are like this one:
one.setOnClickListener(new View.OnClickListener() {
public void onClick(View b) {
one.setVisibility(View.INVISIBLE);
counter++;
money[0] = 0;
Context one = getApplicationContext();
CharSequence message1 = "$1";
int duration = Toast.LENGTH_LONG; //this could also be a number
final Toast one1 = Toast.makeText(one, message1, duration);
one1.show();
for (int x = 0; x < 16; x++) {
sum += money[x];
}
banker = sum / 16;
Context oney = getApplicationContext();
CharSequence message1y = "The Banker offers you $" + banker + " for your case.";
int durationy = Toast.LENGTH_LONG; //this could also be a number
final Toast one1y = Toast.makeText(oney, message1y, durationy);
one1y.show();
}
});
The aim was that if I were to click this button this time the money output was something like $500, and the next time I opened the application it would randomly shuffle and I might get a new value like $1.
You might want to check out Collections.shuffle() instead of implementing it (don't reinvent the wheel etc).
Sounds like what you want to do is call the shuffle method from inside onCreate() and onResume()
You should do the shuffle inside of the "onCreate" method.
public void onCreate(Bundle savedInstanceState){
...
int[] money = {1,10,5,2,20,500,50,100,1000000,5000,1000,50000,100000,500000,250000,10000};
int swap1;
int swap2;
int temp;
Random random = new Random();
void what(){
for (int j=0;j<16;j+=1)
{
swap1 = random.nextInt(16);
swap2 = random.nextInt(16);
temp = money[swap1];
money[swap1] = money[swap2];
money[swap2] = temp;
}
}
}

Access already running objects - Java

import java.awt.*;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
public class vasilisTable extends JFrame {
Object[] split_data_l;
Object[][] split_data;
Object [][] split_data_clone;
Object [][] split_data_reverse;
Object [][] split_data_reverse_num;
String[] temp;
private JTable table;
private JPanel bottom_panel;
private JLabel average;
private JLabel max_dr;
public vasilisTable(String name, String data, int choice)
{
super(name);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //the DISPOSE_ON_CLOSE means that when we press the x button is will close only the table window and not the whole programm
//this.getAccessibleContext().setAccessibleName(name);
//System.out.println(this.getAccessibleContext().getAccessibleName());
setSize(800,600);
String[] columnNames = {"Date", "Open","High","Low","Close",
"Volume", "Adjusted" };//defines the column names
//------ Start of making the arrays that will be used as data for the table creation
split_data_l = data.split( "\n" );
int lngth = split_data_l.length;
split_data = new Object[lngth-1][7];
split_data_clone = new Object[lngth-1][7];
split_data_reverse= new Object[lngth-1][7];
split_data_reverse_num= new Object[lngth-1][7];
double sum = 0;
for(int k=1; k<split_data_l.length; k++) //initializing the three arrays with the data we got from the URLReader
{
temp = split_data_l[k].toString().split(",");
for (int l=0; l<temp.length; l++)
{
split_data[k-1][l] = temp[l];
split_data_clone[k-1][l] = temp[l];
split_data_reverse[k-1][l] = temp[l];
split_data_reverse_num[k-1][l] = temp[l];
}
}
for(int k=split_data_l.length-2; k>=1; k--) // making of the clone array that contains all the last column with colours
{
Double temp = Double.parseDouble(split_data[k][6].toString());
Double temp1 = Double.parseDouble(split_data[k-1][6].toString());
double check =temp-temp1;
if (check>0)
{
String color_temp = "<html><span style = 'color:red'>" + split_data_clone[k-1][6] +"</span></html>" ;
split_data_clone[k-1][6] = color_temp;
}
else
{
String color_temp = "<html><span style = 'color:green'>" +split_data_clone[k-1][6]+"</span></html>" ;
split_data_clone[k-1][6] = color_temp;
}
}
int l = split_data_clone.length;
int m = l-1;
for (int i=0; i<l; i++) //making of the reversed array
{
for (int j = 0; j<=6; j++)
{
split_data_reverse[i][j]=split_data_clone[m][j];
}
m--;
}
m = l-1;
for (int i=0; i<l; i++) //making of the reversed array
{
for (int j = 0; j<=6; j++)
{
split_data_reverse_num[i][j]=split_data[m][j];
}
m--;
}
//------ End of making the arrays that will be used as data for the table creation
//------ Start of calculating the average
for (int i=0; i<lngth-1; i++)
{
Double temp = Double.parseDouble(split_data[i][6].toString());
sum = sum+temp;
//System.out.println("turn "+i+" = "+split_data[i][6]);
}
float avg = (float) (sum/(lngth-1));
avg = Round((float) avg,2);
String avg_str;
avg_str = "<html>Average: <b>"+avg+"</b></html>";
//"<html><b>Average: </b></html>"
//------ End of calculating the average
//------ Start of Calculating the Maximal Drawdown
double high=0;
double low=100000000;
double drawdown=0;
double max_drawdown=0;
int last_high=0;
int last_low=0;
for (int i=0; i<lngth-1; i++)
{
Double temp = Double.parseDouble(split_data_reverse_num[i][6].toString());
//Double temp1 = Double.parseDouble(split_data[i+1][6].toString());
if (temp>high)
{
high = temp;
last_high = i;
//System.out.println("max high = "+temp);
}
else
{
low = temp;
last_low = i;
//System.out.println("max low = "+temp);
}
if (last_low>last_high)
{
drawdown = high-low;
//System.out.println("drawdown = "+drawdown);
}
if (drawdown>max_drawdown)
{
max_drawdown = drawdown;
}
}
//System.out.println("max dr = "+max_drawdown);
String max_dr_str = "<html>Maximal Drawdown: <b>"+max_drawdown+"</b></html>";
//------ End of Calculating the Maximal Drawdown
average = new JLabel(avg_str);
max_dr = new JLabel(max_dr_str);
bottom_panel = new JPanel();
String space = " ";
JLabel space_lbl = new JLabel(space);
bottom_panel.add(average);
bottom_panel.add(space_lbl);
bottom_panel.add(max_dr);
//-------- Start of table creation ---------
if(choice==1)
{
table = new JTable(split_data_clone, columnNames);//creates an instance of the table with chronological order
}else
{
table = new JTable(split_data_reverse, columnNames);//creates an instance of the table with reverse chronological order
}
TableColumn column = null;
for (int i = 0; i < 7; i++) {
column = table.getColumnModel().getColumn(i);
if (i == 0) {
column.setPreferredWidth(100); //third column is bigger
} else if (i == 5) {
column.setPreferredWidth(85); //third column is bigger
}
else if (i == 6) {
column.setPreferredWidth(70); //third column is bigger
}
else {
column.setPreferredWidth(50);
}
}
table.setShowGrid(true);
table.setGridColor(Color.black);
//-------- End of table creation ---------
JPanel table_panel = new JPanel (new BorderLayout());
JScrollPane table_container = new JScrollPane(table); // create a container where we will put the table
//table.setFillsViewportHeight(true); // if the information are not enough it still fill the rest of the screen with cells
table_panel.add(table_container, BorderLayout.CENTER);
table_panel.add(bottom_panel, BorderLayout.SOUTH);
//table_panel.add();
setContentPane (table_panel);
pack(); // here i pack the final result to decrease its dimensions
}
public float Round(float Rval, int Rpl) // this functions rounds the number to 2 decimal points
{
float p = (float)Math.pow(10,Rpl);
Rval = Rval * p;
float tmp = Math.round(Rval);
return (float)tmp/p;
}
}
I am making an application which creates various instances of a class. These instances are actually some windows. After having create multiple of these windows, how can I access one of them and bring it in front? I know the .tofront() method, but how can I specify the window that I want to bring in front?
Above is the code that creates every window. My main problem is that after I have create e.g 5 windows, how can I access one of them?
ps
code that creates each window:
if (sData != null) {
//System.out.println("Success, waiting response");
vasilisTable ftable = new vasilisTable(name, sData, choice);
hashMap.put(name, ftable);
ftable.setVisible(true);
//choice=2;
}
My main problem is that after I have create e.g 5 windows, how can I access one of them?
You have to keep a reference to the relevant objects in variables or an array or a collection or something. The "bring it to the front" function needs to:
figure out what domain object needs to be brought to the front,
lookup its corresponding JFrame, and
call toFront() on it.
Java provides no built-in mechanisms for finding previously created instances of objects.
When you create your various instances of the above JFrame, you can keep track of the created instances, may be store them within a HashMap, then you can pick the right JFrame instance basing on its designated name and bring it to the front. Have a look at the below code for more illustration:
HashMap<String, VasilisTable> hashMap = new HashMap<String, VasilisTable>();
JFrame firstWindow = new VasilisTable("firstWindow",data, choice);
hashMap.put("firstWindow", firstWindow);
JFrame secondWindow = new VasilisTable("secondWindow",data, choice);
hashMap.put("secondWindow", secondWindow);
JFrame thirdWindow = new VasilisTable("thirdWindow",data, choice);
hashMap.put("thirdWindow", thirdWindow);
// To bring a certain window to the front
JFrame window = hashMap.get("firstWindow");
window.setVisible(true);
window.toFront();
Are these JFrame or JWindow objects? If they are you can call -
jframe.setVisible(true);
jframe.toFront();
This is something interesting I found at the API doc.
Places this Window at the top of the stacking order and shows it in
front of any other Windows in this VM. No action will take place if
this Window is not visible. Some platforms do not allow Windows which
own other Windows to appear on top of those owned Windows. Some
platforms may not permit this VM to place its Windows above windows of
native applications, or Windows of other VMs. This permission may
depend on whether a Window in this VM is already focused. Every
attempt will be made to move this Window as high as possible in the
stacking order; however, developers should not assume that this method
will move this Window above all other windows in every situation.
I would recommend you to check out these answers as well.
Java Swing: JWindow appears behind all other process windows, and will not disappear
Java: How can I bring a JFrame to the front?

Inner Classes in Java

I am making a keyboard-like buttons for my Hangman game (SEE PICTURE HERE), my problem is about the inner classes. I've read this LINK about inner classes and it says that you can only access the outside variables with FINAL type. But if I declared the variable as such, I cannot change the value of it anymore... So my problem is that I need to change the value inside the inner class. My code is as follows:
public class MainGame extends JDialog {
private String player;
private char [] wordChar;
private JButton[] buttons;
private int level;
private int score;
private int livesLeft;
private int missedGuess;
void newGame() {
level = 0;
score = 0;
livesLeft = 10;
missedGuess = 0;
//label1:
// while (livesLeft!= 0) {
//get random WORD from LIST
Word hiddenWord = new Word();
//put random word in Array
wordChar = new char[hiddenWord.getHiddenWord().length()];
wordChar = hiddenWord.getHiddenWord().toCharArray();
buttons = new JButton[wordChar.length];
for (int i = 0; i < wordChar.length; i++){
JButton guessWord = new JButton(" ");
guessWord.setFont(new Font("Microsoft Sans Serif", 1, 18));
guessWord.setEnabled(false);
jPanel3.setLayout(new GridLayout(1, wordChar.length));
jPanel3.add(guessWord);
buttons[i] = guessWord;
}
checkLetter();
}
void checkLetter() {
int checker = 0;
while(checker != wordChar.length){
jPanel1.setLayout(new GridLayout(3, 9, 3, 5));
for (char buttonChar = 'a'; buttonChar <= 'z'; buttonChar++) {
String buttonText = String.valueOf(buttonChar);
final JButton letterButton = new JButton(buttonText);
letterButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
for (int j = 0; j < wordChar.length; j++){
String text = String.valueOf(wordChar[j]);
if(actionCommand.equals(text)){
buttons[j].setText(text);
checker++; //THIS CODE IS NOT POSSIBLE!!!!
}
}
}
});
jPanel1.add(letterButton);
}
checker++;
}
}
NOTE: The code above is not complete.
The int checker is used to count how many correct letters are already guessed so that if it is equal to the length of the word, I can now proceed to the next level
How can I re-do my code?
You can declare checker as a field of outer class, and access it with some method, something like increaseChecker().
UPDATE: Something like this:
1) Create checker field in outer class:
public class OuterClassName {
private int checker;
protected void increaseChecker() {
checker++;
}
void checkLetter() {
// ...
}
}
2) Use increaseChecker() method call instead of checker++
You can't access local variables in an anonymous inner class, and that's for a good reason. The actionPerformed() method isn't guaranteed to be called inside the checkLetter() function. It will be called later, possibly (and most probably) after the function exits so its local variables will be destroyed by that time. Therefore, the newly created anonymous class implicitly gets a copy of that variable. But it wouldn't make any sense to increase the copy, that's why only final local variables can be accessed from methods of an anonymous class.
The simplest workaround is just to make checker a field of the outer class. But that wouldn't make any sense if it's accessed only within the checkLetter() function unless it is necessary for it to retain its value between checkLetter() calls. In order to find out the true answer, you need to think why you are trying to increase checker inside actionPerformed()? When should it happen and what are you trying to achieve by doing it?
Why not keep the anonymous inner class but have it call a method of the class. This way final isn't an issue.
letterButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
letterButtonActionPerformed(e); // create this method
}
});
//.....
// new method
private void letterButtonActionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
for (int j = 0; j < wordChar.length; j++){
String text = String.valueOf(wordChar[j]);
if(actionCommand.equals(text)){
buttons[j].setText(text);
checker++; //THIS CODE IS NOT POSSIBLE!!!!
}
}
}

Categories

Resources