Adding the output of Stack.pop() - java

import java.util.Random;
import java.util.Stack;
public class Blackjack {
public static void main(String[] args) {
int cardValue; /* card value is from 2 to 11 */
Stack Player1 = new Stack();
Stack Addition = new Stack();
Random r = new Random();
int i = 2 + r.nextInt(11);
System.out.println("Welcome to Mitchell's blackjack program!");
for (int a = 1; a <= 2; a++) { /* Start's the game by assigning 2 cards each, to the players */
Player1.push(i);
}
while (!Player1.empty()) {
System.out.print("You get a " + Player1.pop());
System.out.print("and");
int sum = 0;
for (int n = 0; n < Player1.size(); n++) {
sum = sum + Player1.pop();
System.out.print("Your total is " + sum);
}
}
}
}
So I just started learning java and I'm trying to accomplish this BlackJack project But, when I try to compile using javac the output was bad operand types for binary operator '+' for the 'sum = sum + Player1.pop();'
The solution i used in the above coding was from here

Player1.pop() returns an Object because you used Stack without providing a type. and you cannot do int + Object. If you need to store ints in the Stack, just use generics and do
Stack<Integer> Player1 = new Stac<Integer>k();
Stack<Integer> Addition = new Stack<Integer>();
And your
System.out.print("Your total is " + sum);
should be outside the for otherwise you will get a temporary sum

Change Stack to Stack<Integer>.
By default, you get a stack of (unknown) Objects, and you can't add an Object to an int.

Stack takes a generic argument that determines the type of Object that the Stack will store. This in turn defines the type of Object that pop() returns. In your case you could use a numeric type e.g.
Stack Player1 = new Stack<Integer>();
Providing no type argument will result in Object being returned and int + Object is not defined, hence your error.

Others have explained this using Java generics, the new Stack() approach, which tells the compiler to only let you put Integers into the Stack, and automatically takes Integers out.
Before generics, you'd just cast whatever it was you brought out of the Stack to an Integer. As people have said, the problem is that your code doesn't know what it's getting back from the stack, so it assumes Object, and doesn't know how to add those. Casting would look like:
sum = sum + (Integer)Player1.pop();

Although using Stack will solve this problem. But I guess there are issues the way you have used loop.
Your while loop will execute only once, as you for loop will empty that stack. Not sure if that's what you want to do.

Related

How do I pass these integers to the method below it?

I'm confusing myself here. My goal was to make a simple program that took the number of values the user wants to average, store them in an array (while adding them together) and finally giving the average of these numbers.
My thing is, I am trying to understand the concept of multiple classes and methods as I am new so I tried using another class just do do all the work, while the Main class would just create the object from the other class, and then run their methods. Maybe I am asking something impossible. Take a look at my code.
This is my Main class:
public class Main
{
public static void main(String[] args)
{
System.out.println("Please enter numbers to average together");
OtherClass averages = new OtherClass();
averages.collectNumbers();
averages.AverageNumbers();
}
}
Now I am not sure if anything goes in those parameters, or if I can even use "averages.AverageNumbers();" without creating another object with "OtherClass" called something else? I am pretty sure it's legal though.
Here is my other class for this project entitled "OtherClass"
import java.util.Scanner;
public class OtherClass // using this to name obj
{
public void collectNumbers() //name of our method that does things
{
Scanner sc = new Scanner(System.in);
System.out.println("how many integers would you like to average? ");
int givenNum = sc.nextInt();
System.out.println("Alright, I will average " + givenNum + " values. \nPress enter after each:");
int[] numCollect = new int[givenNum];
int sum = 0;
for (int i = 0; i < numCollect.length; i++)
{
numCollect[i] = sc.nextInt();
sum = sum + numCollect[i];
}
System.out.println(sum);
}
public int AverageNumbers(int givenNum, int sum)
{
int average = sum / givenNum;
System.out.println(average);
return average;
}
}
So when I run this now with the the method AverageNumbers, it does not work. I am suspecting that maybe I am passing in the integers wrong? I have been toying with it for about an hour now, so I am asking for help. How do I make this work?
This will work if you declare sum and givenNum as fields of your OtherClass, instead of as local variables. So, before the collectNumbers method, write
private int sum;
private int givenNum;
and remove the declarations of these two variables inside collectNumbers. So, for example, instead of
int givenNum = sc.getInt();
you'll just have
givenNum = sc.getInt();
because the variable already exists. Also change the declaration of the averageNumbers method to
public int averageNumbers()
because you no longer need to pass those two values in to this method.
This is the archetypical example of using the objects of a class to carry a small amount of data around, instead of just using a class as a way to group methods together. The two methods of this class work with sum and givenNum, so it makes sense to store these in each object of this class.
Lastly, in your averageNumbers method, you have an integer division, which will automatically round down. You probably want a floating point division instead, so you could write
double average = (double) sum / givenNum;
which converts sum to a double-precision floating point number before the division, and therefore does the division in floating point, instead of just using integers. Of course, if you make this change, you'll need to change the return type of this method to double too.

To implement pile of cards and manage players

includes a pile of cards in a player’s hand and two actions: TAKE and DISCARD. TAKE puts a card on the top of a player’s pile of cards when that player receives a card from a dealer. DISCARD removes a card from the top of a player’s pile of cards when a player plays it against another player in the game. Each player receives 16 cards from the dealer at the
beginning of a game........
I tried my code like this which gives me nothing
public class play {
int noOfCards = 16;
static void TAKE(Stack st, int a) {
st.push(new Integer(a));
}
static void DISCARD(Stack st) {
Integer a = (Integer) st.pop();
}
public static void main(String args[]) {
for(int i=0; i<=16; i++) {
Stack st = new Stack();
st.take();
st.discard();
}
}
}
I am new to this concepts ....give me a path to solve this question
I'm sorry but I didn't fully understand the whole process you're trying to do. But I still gave it a shot.
public class Play
{
private static int noOfCards = 16;
private static Stack<Integer> player1 = new Stack<Integer>();
private static Stack<Integer> player2 = new Stack<Integer>();
static void takeCard(Stack<Integer> st,int cardValue){
st.push(cardValue);
}
static int discardCard(Stack<Integer> st){
return st.pop();
}
static int getRandomValue(int min, int max){
Random r = new Random();
return r.nextInt((max - min) + 1) + min;
}
//Filled card pile with random values from 1-13
public static void main(String[] args)
{
for(int i = 0 ; i < noOfCards; i++){
takeCard(player1,getRandomValue(1,13));
takeCard(player2,getRandomValue(1,13));
}
//player 1 takes a card!
//Size of player1's pile before and after taking card
System.out.println("Before:" + player1.size());
takeCard(player1, getRandomValue(1, 13));
System.out.println("After" + player1.size());
//player 2 discards a card and outputs the card's value
System.out.println("Player 2 discards: " + discardCard(player2));
}
}
Not sure what you want it to do. Are you just trying to implement TAKE and DISCARD? Despite not knowing exactly what you're trying to do, there are lots of issues with your code.
One immediate issue is the fact that your Stack initialization is inside your for loop meaning that every time you execute that loop, you create a brand new Stack, which will be empty. So, essentially, your main method does this:
Create a new Stack (it's empty)
Add a card to the stack
Remove a card from the stack
Repeat steps 1-3 16 times
Another issue is that Java is case sensitive so calling st.take() doesn't match up with TAKE().
Yet another issue is that st.take() is like saying "Call the 'take()' method on my instance of Stack". Stack doesn't define a method called take() - it has methods like push() and pop() (look here: http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html). Your take and discard methods are on the class Play, so you'd want to invoke them like this:
Play.TAKE(st, 3);
Play.DISCARD(st);
Another issue: when you try to invoke keep or discard, you don't send any parameters, but you've defined these methods to take parameters. See above.
Is discard supposed to return the value of the card being discarded? You retrieve that value and store it into the local variable "a" and then you don't do anything with it. If you're not going to return it, you don't need to create "a". If you are going to return it, your return type shouldn't be void.

Trying to Make an Average Finder, Not Using ReadLine(), using Only Console

New to Java, basically started yesterday.
Okay, so here's the thing.
I'm trying to make an 'averager', if you wanna call it that, that accepts a random amount of numbers. I shouldn't have to define it in the program, it has to be arbitrary. I have to make it work on Console.
But I can't use Console.ReadLine() or Scanner or any of that. I have to input the data through the Console itself. So, when I call it, I'd type into the Console:
java AveragerConsole 1 4 82.4
which calls the program and gives the three arguments: 1, 4 and 82.4
I think that the problem I'm having is, I can't seem to tell it this:
If the next field in the array is empty, calculate the average (check Line 14 in code)
My code's below:
public class AveragerConsole
{
public static void main(String args[])
{
boolean stop = false;
int n = 0;
double x;
double total = 0;
while (stop == false)
{
if (args[n] == "") //Line 14
{
double average = total / (n-1);
System.out.println("Average is equal to: "+average);
stop = true;
}
else
{
x = Double.parseDouble(args[n]);
total = total + x;
n = n + 1;
}
}
}
}
The following error appears:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at AveragerConsole.main(AveragerConsole.java:14)
for(String number : args) {
// do something with one argument, your else branch mostly
}
Also, you don't need n, you already have the number of arguments, it's the args length.
This is the simplest way to do it.
For String value comparisons, you must use the equals() method.
if ("".equals(args[n]))
And next, the max valid index in an array is always array.length - 1. If you try to access the array.length index, it'll give you ArrayIndexOutOfBoundsException.
You've got this probably because your if did not evaluate properly, as you used == for String value comparison.
On a side note, I really doubt if this if condition of yours is ever gonna be evaluated, unless you manually enter a blank string after inputting all the numbers.
Change the condition in your while to this and your program seems to be working all fine for n numbers. (#SilviuBurcea's solution seems to be the best since you don't need to keep track of the n yourself)
while (n < args.length)
You gave 3 inputs and array start couting from 0. The array args as per your input is as follows.
args[0] = 1
args[1] = 4
args[2] = 82.4
and
args[3] = // Index out of bound
Better implementation would be like follows
double sum = 0.0;
// No fault tolerant checking implemented
for(String value: args)
sum += Double.parseDouble(value);
double average = sum/args.length;

ArrayList of integer arrays

I'm trying to write a simple game where an enemy chases the player on a grid. I'm using the simple algorithm for pathfinding from the Wikipedia page on pathfinding. This involves creating two lists with each list item containing 3 integers. Here's test code I'm trying out to build and display such a list.
When I run the following code, it prints out the same numbers for each array in the ArrayList. Why does it do this?
public class ListTest {
public static void main(String[] args) {
ArrayList<Integer[]> list = new ArrayList<Integer[]>();
Integer[] point = new Integer[3];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//Added this line to confirm that Integer[] point is actually
//being filled with 3 random ints.
System.out.println(point[0] + "," + point[1] + "," + point[2]);
}
System.out.println();
//My current understanding is that this section should step through
//ArrayList list and retrieve each Integer[] point added above. It runs, but only
//the values of the last Integer[] point from above are displayed 10 times.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
}
First of all, several of the other answers are misleading and/or incorrect. Note that an array is an object. So you can use them as elements in a list, no matter whether the arrays themselves contain primitive types or object references.
Next, declaring a variable as List<int[]> list is preferred over declaring it as ArrayList<int[]>. This allows you to easily change the List to a LinkedList or some other implementation without breaking the rest of your code because it is guaranteed to use only methods available in the List interface. For more information, you should research "programming to the interface."
Now to answer your real question, which was only added as a comment. Let's look at a few lines of your code:
Integer[] point = new Integer[3];
This line creates an array of Integers, obviously.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 3; j++) {
point[j] = (int)(Math.random() * 10);
}
//Doesn't this line add filled Integer[] point to the
//end of ArrayList list?
list.add(point);
//...
}
Here you assign values to the elements of the array and then add a reference to the array to your List. Each time the loop iterates, you assign new values to the same array and add another reference to the same array to the List. This means that the List has 10 references to the same array which has been repeatedly written over.
Iterator it = list.iterator();
while (it.hasNext()) {
point = (Integer[])it.next();
for (int i = 0; i < 3; i++) {
System.out.print(point[i] + ",");
}
System.out.println();
}
}
Now this loop prints out the same array 10 times. The values in the array are the last ones set at the end of the previous loop.
To fix the problem, you simply need to be sure to create 10 different arrays.
One last issue: If you declare it as Iterator<Integer[]> it (or Iterator<int[]> it), you do not need to cast the return value of it.next(). In fact this is preferred because it is type-safe.
Finally, I want to ask what the ints in each array represent? You might want to revisit your program design and create a class that holds these three ints, either as an array or as three member variables.
I would highly recommend to enclose the integer array of 3 numbers into a meaningful class, that would hold, display and control an array of 3 integers.
Then in your main, you can have an growing ArrayList of objects of that class.
You have an extra ) here:
element = (int[])it.next()); //with the extra parenthesis the code will not compile
should be:
element = (int[])it.next();
Besides the problem in the other answer, you cal it.next() two times, that cause the iterator move forward two times, obviously that's not what you want. The code like this:
element = (int[])it.next());
String el = (String)element;
But actually, I don't see you used el. Although it's legal, it seems meaningless.

exponential growth in java, return type array of doubles

Im working on a CS assignment and Im having a little trouble understanding how to output an array of doubles that represent the amt of money in a bank account at increments of time given a user specified growth rate. I have a main method that asks the user for initialAmount of $, a growthRate and the number of time intervals (denoted iA, gR and nP for inital Amount, growth Rate and number of Periods). this method then calls another method which is of return type double[]. My issue is with the code inside my for-loop, it compiles fine but outputs gibberish. heres the code:
import java.util.Scanner;
public class Benford {
public static double[] generateBenfordNumbers (double iA, double gR, int nP) {
double[] bankStatement = new double[nP];
for (int i = 0; i<nP; i++) {
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
}
return bankStatement;
}
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
double iA;
double gR;
int nP;
System.out.print("What is the initial amount of money that you are starting with? : ");
iA = scan.nextDouble();
System.out.println();
System.out.print("What is the amount of growth per time period? : ");
gR = scan.nextDouble();
System.out.println();
System.out.print("How many time periods would you like to use? : ");
nP = scan.nextInt();
System.out.println();
generateBenfordNumbers(iA, gR, nP);
System.out.print(generateBenfordNumbers(iA, gR, nP));
}
}
In the line
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
i++ increments i a second time. You probably want:
bankStatement[i] = (iA*(Math.pow((1+(gR)), i + 1)));
or, if we clean it up,
bankStatement[i] = iA * Math.pow(1 + gR, i + 1);
i + 1 returns a value 1 greater than that of i, but does not actually increment the variable itself.
Also, do you really have to use Math.pow each time? Can't you just manually set the first element of your array to iA and subsequently use bankStatement[i-1] to compute bankStatement[i]? Doing something like this will probably improve your program.
i is incremented twice : at loop level and into the body
The gibberish output looks like this:
[D#1b67f74
which is s double array text representation. You could use:
System.out.print(Arrays.toString(generateBenfordNumbers(iA, gR, nP)));
You should not be incrementing i inside your call to Math.pow. This is because you already increment it in your for loop. The result is that elements of your array are getting skipped and not set. This is probably where the gibberish-ness is coming from.
You probably want to change:
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
To:
bankStatement[i] = iA*Math.pow(1+gR, i);
Also, as an aside, you generally shouldn't use so many parenthesis because it makes it hard to read. If you're not sure what the order of operations is, look it up.
What the others said, you're incrementing i twice so I'm not going to repeat that. I just want to add that brackets are good to organize formulas and to ensure correct execution order of calculations, but if you overuse them, they can obfuscate the intention of your program and they may make the problem you're looking for harder to spot. Compare
bankStatement[i] = iA * Math.pow(1.0 + gR, i+1);
with
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i))));
See what I mean?
EDIT - following ARS very valid remark about the initial value of i, I changed the cleaned up statement.

Categories