Setting up my Hangman methods and calling them in my main method - java

Having difficulty calling the methods in my Game class to my main method for my hangman game.
We're supposed to spin a wheel to get a jackpot amount for 100,250 or 500 bucks then play the game as you'd expect... But methods are a necessity. Im nowhere near done I just want to be able to call my methods at this point to see how its working.
Here's my code:
import java.util.Scanner;
import java.util.Random;
public class GameDemo {
public static void main(String[] args) {
String[] songs = {"asdnj", "satisfaction", "mr jones",
"uptown funk"}; //note this is a very short list as an example
Random rand = new Random();
int i = rand.nextInt(songs.length);
String secretword = songs[i];
System.out.print("Welcome to The Guessing Game. The topic is song titles. \nYou have 6 guesses. Your puzzle has the following letters: ");
System.out.print("After spinning the wheel, you got " + spinWheel());
//continue the code here.
}
}
class Game {
Random rand = new Random();
String[] songs = {"asdnj", "satisfaction", "mr jones",
"uptown funk"};
int i = rand.nextInt(songs.length);
private String secretword = songs[i];
private char [] charSongs = secretword.toCharArray();
private char [] guessed = new char [charSongs.length];
private int guesses;
private int misses;
private char letter;
private char [] jackpotAmount = {100,250,500};
public Game (){}
public int spinWheel(int[] jackpotAmount){
int rand = new Random().nextInt(jackpotAmount.length);
return jackpotAmount[rand];
}
public char guessLetter(char charSongs [], char letter){
int timesFound = 0;
for (int i = 0; i < charSongs.length; i++){
if (charSongs[i] == letter){
timesFound++;
guessed[i] = letter;
}
}
return letter;
}
}
And the return error is
GameDemo.java:11: error: cannot find symbol System.out.print("After
spinning the wheel, you got " + spinWheel()); ^

To call methods from another class you need to make the method public. Once that is done, make them static if you will call the same method many times and you want it do the same function each time (the parameters can still be different).
To call the method do the following (this is a general form for most classes and methods, you should be able to use this to call all your methods):
yourClassWithMethod.methodName();

There are several issues in your spinWheelmethod call:
You haven't instantiated any any Game object to call this method. Either you have to make it static or just instantiate a Game and call it from that objet. I personally prefer the second (non-static) option because, especially because a static method cannot access directly non-static method or variables (... you need an instance or to make them static).
In main, you can do this (non-static solution):
Game game = new Game();
System.out.print("After spinning the wheel, you got " + game.spinWheel());
spinWheel requires an argument of type int[]. It seems that it is not useful since there is an instance variable jackpotAmount that seems to have been created on that purpose. jackpotAmount (see also second point) should be static in you example.
spinWheel becomes :
//you can have "public static int spinWheel(){"
//if you chose the static solution
//Note that jackpotAmount should also be static in that case
public int spinWheel(){
int rand = new Random().nextInt(jackpotAmount.length);
return jackpotAmount[rand];
}
Note that jackpotAmount should better be an int[]than a char[]

Related

Java - Inheritance regarding constructors

So, I'm trying to practice my java skills by applying it to some math homework and making a frequency distribution chart using inheritance. In my head, I envision it as a frequency distribution (parent class = FreqDist) that can have multiple "MyStatClasses" (in the form of the MyStatClass array). Each FreqDist has variables that span across all MyStatClasses which is why I put them in the parent class. However, when I call the MyStatClass constructor, my program gets a StackOverflowError. I think this is because the super(s, i) line calls back to the FreqDist constructor and starts over, causing an infinite loop. Assuming this is the case, how would I fix this?
Ideally, I'd like to access my MyStatClass array and grab values that only apply to that MyStatClass, but I cannot get it to work.
public class FreqDist {
private MyStatClass[] freqClasses;
private double[] dblValuesArray;
private int intNumberOfClasses;
private double dblMax;
private double dblMin;
private int intClassWidth;
public FreqDist(String strValues, int intNumOfClasses) {
System.out.println("This is the beginning of the FreqDist constructor...");
dblValuesArray = getDoubleValues(strValues);
intNumberOfClasses = intNumOfClasses;
dblMin = dblValuesArray[0];
dblMax = dblValuesArray[dblValuesArray.length - 1];
intClassWidth = (int)Math.ceil((dblMax - dblMin) / intNumberOfClasses);
freqClasses = new MyStatClass[intNumberOfClasses];
for (int x = 0; x < freqClasses.length; x++) {
freqClasses[x] = new MyStatClass(strValues, intNumOfClasses);
}
}
public double[] getDoubleValues(String strValues) {
String[] strValuesArray = strValues.trim().split(" ");
dblValuesArray = new double[strValuesArray.length];
for (int x = 0; x < strValuesArray.length; x++) {
dblValuesArray[x] = Double.parseDouble(strValuesArray[x]);
}
Arrays.sort(dblValuesArray);
return dblValuesArray;
}
public int getNumberOfClasses() {
return intNumberOfClasses;
}
public double getMin() {
return dblMin;
}
public double getMax() {
return dblMax;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("What are the values? ");
String values = scan.nextLine();
System.out.print("How many classes? ");
int classes = scan.nextInt();
FreqDist fd = new FreqDist(values, classes);
}
}
public class MyStatClass extends FreqDist {
public MyStatClass(String s, int i) {
super(s, i);
}
}
Ok so this is mostly an issue with a flaw in your design.
From what I understand FreqDist is a class that should contain an array of MyStatClass. You want them to have the same properties so you make MyStatClass extend FreqDist. However when you call FreqDist it MyStatClass which Calls a new MyStatClass over and over and over.
One way to solve this is to create a new class that has the shared properties you want FreqDist and MyStatClass to have, and have those two classes inherit from said class. Then create separate constructors for FreqDist and MyStatClass.
A parent type should never refer to its own subtypes, as yours does. Her the parent initializes subtype instances, which require that each initialize the parent type, which initializes subtype instances, which initialize their parent type, which initializes... KABLOOEY!

How to pass information through a method and returning a value

I'm new to Java, and need help. I have been asked to write a program that rolls dice and determines the chance of the player to get two "1s" on the top face of the dice. I have different functions such as role(), getTopFace() etc. I want to be get what the number on the dice is using these functions, but don't know how to call them in my main function. Here's my code:
import javax.swing.JOptionPane;
import java.util.Random;
public class SnakeEyes {
private final int sides;
private int topFace;
public static void main(String[]args)
{
String numberSides;
int n;
numberSides=JOptionPane.showInputDialog("Please enter the number of sides on the dice:");
n = Integer.parseInt ( numberSides);
int[]die=new int[n];
for (int index=0; index<n;index++)
{
die[index]=index+1;
}
//Here is where I want to get information from my functions and calculate the ods of getting two 1's.
}
public void Die(int n)
{
if(n>0)
{
int sides=n;
topFace=(int)(Math.random()*sides)+1;
}
else{
JOptionPane.showMessageDialog(null, " Die : precondition voliated");
}
}
public int getTopFace(int topFace)
{
return topFace;
}
public int role(int[] die)
{
topFace=(int)(Math.random()*sides)+1;
return topFace;
}
}
Make an object of your class SnakeEyes in your main method, and call the required functions using that object.
Example:
SnakeEyes diceObj = new SnakeEyes();
int topFace = diceObj.role(n,....);
If you want to call this functions from main this functions must be "static", because main its a static function and static function can only call other static functions.
But... this is a very ugly design for a java program, before jumping to write java code you need to understand at least a little about object orientation. For example, why you can't call a non-static function from a static function?, the answer of this question requires knowledge about object orientation and its a knowledge you need if you want to write serious java code.

improve calling next method in JAVA

I'm looking for a better way to organize my class.
Right now my code looks like this:
mainMethod:
-number1 input
-call method1 with number1 als value
method1:
-do "stuff" with input
-call method2 with new "stuff" as value
method2:
-do stuff
-call method3
etc...
So i start with user input in my main method and my whole class works like domino, the first method needs to be called to run the next method.
I would rather have method1 return a value and save it in some global variable in my class which can be used by method2 and so on.
Here is my Code with exactly this problem: (it calculates sqrt)
package wurzel;
import java.util.Scanner;
import wurzel.Fraction;
public class wurzel {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Eingabe:");
int in = s.nextInt();
s.close();
bisection(in);
}
private static int bisection(int N){
int counter = 0;
for(int i = 0; i < N;i++){
if((counter*counter) > N){
counter--;
break;
}
else if(counter*counter == N){
break;
}
else counter++;
}
calculateSequence(counter,N);
return counter;
}
static int[] calculateSequence(int vKomma, int look){
int m = 0;
int d = 1;
int a = vKomma;
int[] intarr = new int[4];
intarr[0] = vKomma;
for(int i = 1; i <= intarr.length; i++){
if(i == intarr.length )
break;
else{
m = (d*a) - m;
d = (look - (m*m)) / d;
a = (vKomma + m) / d;
intarr[i] = a;
}
}
calculateApproximation(intarr);
return intarr;
}
static double calculateApproximation(int[] sequence ){
Fraction result = new Fraction((sequence.length)-1);
for(int dcounter = sequence.length; dcounter > 0; dcounter--){
result = result.reciprocal().add(sequence[dcounter-1]);
}
System.out.println("Approximation als double: " +result.doubleValue());
System.out.println("Approximation als Bruch: " +result);
return result.doubleValue();
}
}
You should also seperate code into different classes. E.g. have a generic MathHelper class which has these methods in it.
This helps keep code seperate and easy to read.
You mentioned that you wanted to store some data in a global variable for the class as a whole. The way to do this is by making the class use instance methods rather than class methods. With class methods, you have to use class variables. But, when you use instance methods, you can define instance variables which can be accessed by any method within the class.
To do this, change all your methods (apart from main()) by removing the keyword static from each method. Then, define the instance variable that is global for the class. e.g. if your global variable is of type int then it would be:
private int myInstanceVariable;
This instance variable, or global variable, can be accessed by a getter and setter.
It is quite normal methods to call each other and to form long chains of calls.
So I would not worry about that. Actually in real world, in enterprise code,
you have call stack going through tens of calls. So I think global variables would
be worse practice compared to what you did.

New object instance not being recognized- Java

I am having trouble getting a random generator instance from being recognized as an object and it won't allow for use within another .class file. The base code for the random integer generator is this:
package RandomInstanceGenerator;
import java.util.Random;
/** Generate 10 random integers in the range 0..99. */
public final class RandomInteger {
public static final void main(String... aArgs){
log("Generating 10 random integers in range 0..99.");
//note a single Random object is reused here
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
int randomInt = randomGenerator.nextInt(100);
log("Generated : " + randomInt);
}
log("Done.");
}
private static void log(String aMessage){
System.out.println(aMessage);
}
}
I am trying to have the code below run what is above as a new instance. I have tried several methods that were apparent to me from other learnings, but they have failed me and so I request the knowledge of others for help in understanding. I say that in understanding that i literally copied and pasted the base code from another source that has it run as it's own little .class. Here is the code that tries to create a new instance:
package RandomInstanceGenerator;
import java.util.Random;
class Inst {
public static void main (String args[]) {
RandomInteger rig=new RandomInteger();
rig.main(args);
}
}
I am certain both need editing, hope I can fix this out so it works for me.
List of attempted changes:
1) Tried importing RandomInteger.class. The error given back says it cannot find symbol "Random Integer".
I used the code import RandomInstanceGenerator.RandomInteger;.
2) Working on the next attempt later..
When Java executes a program it looks for a main function; in this case in your second class. That class then instantiates your first class (via new RandomInteger()). You then attempt to call into that first class's main method.
Note, though, that the method is labeled static. Static methods are executable only on the class, not on a specific instantiated object. If you were to use RandomInteger.main() you could expect a different result:
class Inst {
public static void main (String args[]) {
RandomInteger.main(args);
}
}
But note that this is equivalent to just running RandomInteger as it's own program. If, as you say, you want to run your program as a method on an object, this is what you want:
public final class RandomInteger {
private Random randomGenerator = new Random(); //A single object can reuse this component
//function prints out x random numbers between low and high
//Note that your function should do ONE thing, therefore do not make it also interpret
//your program arguments!
public void logXRandomNumbers(int x, int low, int high){
log("Generating " + x + " random integers in range " + low ".." + high);
int range = high - low;
//you really should do a sanity check here to ensure the range is valid.
//note a single Random object is reused here
for (int idx = 1; idx <= x; ++idx){
int nextResult = this.randomGenerator.nextInt(range) + low;
log("Generated : " + nextResult);
}
log("Done.");
}
//This function is probably overkill
private static void log(String aMessage){
System.out.println(aMessage);
}
}
Now all you have to do is call this from your main function:
public static void main (String args[]) {
RandomInteger generator = new RandomInteger();
generator.logXRandomNumbers(10, 0, 100);
}
As for your imports, both classes should have the same package. Lets say its Generator for simplicity:
package Generator;
Only your second class (the not very-well-named Inst) needs to import your generator/logging class:
import Generator.*;
or
import Generator.RandomInteger;
Be sure that both of these files are in the same directory named 'Generator' and that you are running javac from the directory above that.

Creating weapon classes and a Combat Class

I am creating a text based game and I am having some issues.. This is what I have so far. So far I have a Combat Class, and two Classes for two different Weapons. I am trying to assign hit points to the weapons themselves. But my biggest issue is in the Combat class. I am trying to create it to were there will be random weapon drops at random times and also random Weapons. So far in the Combat class I have this:
public class Combat {
final int chanceOfDrop = 3;
static Weapons[] wepArray = {new M4(), new M16()}
static boolean[] hasWeapon = {false, true};
public static int ranNumberGen(int chanceOfDrop) {
return (int) (Math.random()*1);
}
private void enemyDead() {
boolean canDrop = false;
if(ranNumberGen(chanceOfDrop)==0){
canDrop = true;
}
if(canDrop == true){
givePlayerWeapon(Weapon[Combat.ranNumberGen(Weapons.length)]);
}
private static void givePlayerWeapon(int w) {
hasWeapon[w] = true;
for w <(Weapons.length-1) {
if has weapon[w] {
System.out.println(wepArray[w].getWeaponName);
}
}
}
}
}
}
I have issues when I am creating the new M4(), and the new M16() it says Type mismatch: cannot convert form M4 to Weapons. I do have a class named Weapons, could that be the problem?
And here is my M4 Class, both M4 and M16 Classes are identical
public abstract class M4 {
private Integer weaponDamage = 5;
private Integer weaponAmmo = 25;
private String weaponName = "M4";
public M4(String name, int ammo, int damage) {
name = weaponName;
ammo = weaponAmmo;
damage = weaponDamage;
}
public String getWeaponName() {
return weaponName;
}
public Integer getAmmo() {
return weaponAmmo;
}
public Integer getDamage() {
return weaponDamage;
}
}
I don't think I have any issues here. Maybe my problem lies within this though. Although, I have a Weapons class, but nothing in it. Do I need that?
A few things to fix at first sight:
Create a generic Weapon class that defines some properties that apply to each weapon, like name, damage, ammo, scope multiplier, etc... Then create subclasses for Weapon, like M4 and M16, that specify the properties and eventually add weapon-specific properties.
Add brackets to this line:
System.out.println(wepArray[w].getWeaponName); // Change to getWeaponName()
Remove the abstract keyword from M4.
Fix the ranNumberGen method because it will always return 0 right now. Math.random() returns a float in the range [0,1[. This means that casting it to an int will always result in 0. Multiply it by n to have a random int in the range of [0, n[. You probably want this:
public static int ranNumberGen(int max) {
return (int) (Math.random() * max);
}
Change this line:
givePlayerWeapon(Weapon[Combat.ranNumberGen(Weapons.length)]);
to:
givePlayerWeapon(wepArray[Combat.ranNumberGen(wepArray.length)]);
The syntax of a for-loop is like this:
for (variable-initialization; condition; increment)
So in your case, you want:
for (int i = 0; i < hasWeapon.length; ++i)
{
if (hasWeapon[i]) System.out.println(wepArray[i].getWeaponName());
}
You might want to revisit your decision to use an inheritance-style heirarchy for game objects before it is too late.
In practice, I've found a component-entity model and/or prototype model to be much more effective. You could take a look at the code in my old Java roguelike game Tyrant for inspiration:
Weapon definitions: mikera/tyrant/Weapon.java (Github is down right now so can't find the exact link, but should be easy enough to Google)
The idea is that you make your objects by setting properties / composing compoenents in a Map-like game object rather than using static inheritance.
When you want to create a random weapon in this model, you can just get a list of all the possible weapon prototypes, and clone one of them at random to make a new weapon.
the mean of abstract in "public abstract class M4" is that you cannot make a new object with this class.
So you can put all commons fields of your weapons in the weapon class and make m4 and m16 extends the weapon and you code would compile.

Categories