I know it can be done by making the integer into a 1x1 array, but I hope there
is a more straight-forward way to do it.
Thanks.
Jim
public int multiplyByFive(int value)
{
return value * 5;
}
...
i = multiplyByFive(i);
That's the best way. See some past threads for several detailed discussions
of ways to avoid the need for pass-by-reference. Essentially, it boils down
to three cases:
Problem: You need pass-by-reference because you're using the
return value for an error code.
Solution: Use exceptions, and you get your return value back.
Problem: Your method does in-place updates of large amounts of
related data items.
Solution: Encapsulate the data as a class, and pass that as the
parameter. You can update the object state in-place.
Problem: Your method needs to return two unrelated values.
Solution: Split up the method into two different methods.
Chris Smith
Jim Simpson wrote:
This could be done. It might be better to create a new object. That way the
tostring() method would be more useful when you want to look at the value.
Be careful. Java copies object reference by value. You cannot assign a
new object to a reference that is passed to a method.
class Int{
private Integer val;
public Int(int aVal){val=new Integer(aVal);}
public String toString(){return val.toString();}
public Int setVal(int aVal){val=new Integer(aVal); return this;}
public Integer getVal(){return val;}
public int getValue(){return val.intValue();}
public Int mult(int prod){return setVal(prod*getValue()); }
public Int mult(Int prod){return mult(prod.getValue());}
public Int getThis(){return this;}
public Object clone(){return new Int(getValue());}
}
public class Junk {
public static void main(String[] args) {
Int i=new Int(2);
forthPower(i);
System.out.println(i);
i.setVal(2);
cube(i);
System.out.println(i);
}
public static void forthPower(Int i){
i.mult(i).mult(i);
}
public static void cube(Int i){
Int j=(Int)i.clone();
i.mult(j).mult(j);
}
} // Junk
>
> Jim
John Creighton wrote:
> Jim Simpson wrote:
>
> > Is there a way to pass an integer as an argument to a method, change the value
> > of the integer in the method and return the integer to the calling routine with
> > the new value?
> >
> > I know it can be done by making the integer into a 1x1 array, but I hope there
> > is a more straight-forward way to do it.
>
> This could be done. It might be better to create a new object. That way the
> tostring() method would be more useful when you want to look at the value.
> Be careful. Java copies object reference by value. You cannot assign a
> new object to a reference that is passed to a method.
> <snip>
> public Int getThis(){return this;}
Don't ask why I put this hear. This does nothing.
> public Object clone(){return new Int(getValue());}
> }
> public class Junk {
>
> public static void main(String[] args) {
> Int i=new Int(2);
> forthPower(i);
> System.out.println(i);
> i.setVal(2);
> cube(i);
> System.out.println(i);
> }
> public static void forthPower(Int i){
> i.mult(i).mult(i);
> }
> public static void cube(Int i){
> Int j=(Int)i.clone();
> i.mult(j).mult(j);
> }
> } // Junk
>
> >
> > Jim
Output:
cd c:/MyFiles/cs1083/Junk/
javaw -classic Junk
16
8
Process Junk finished
P.S. It might not be a good idea to do what I did:
It is best to try to group related values into an object
instead of treating them as separate values.
Mutators and assessors should not be mixed up.
int amethod(int i) { return 2 * i;}
and call it
i = amethod(i);
Gilgames wrote:
Opps I thought he wanted to change the value without returning it (i.e. pass by
reference).
Silly me.
import java.util.*;
public class g {
public static void main(String[] arguments) {
final int C_I_R = 24;
rC twistie = new rC();
int cL = 20;
int rL = twistie.dC(cL, C_I_R);
System.out.println(rL);
}
}
class rC {
Random number = new Random();
int dC(int cL, int C_I_R)
{
int cd = number.nextInt(C_I_R) + 1;
cL = cL - 1;
return cd;
}
}
Thanks to all Jim.
> Sorry, I didn't make my question clear. The following snip should help. I
want
> "cL" to return to the calling routine with the new value of "19".
>
> import java.util.*;
> public class g {
> public static void main(String[] arguments) {
> final int C_I_R = 24;
> rC twistie = new rC();
> int cL = 20;
> int rL = twistie.dC(cL, C_I_R);
> System.out.println(rL);
> }
> }
>
> class rC {
> Random number = new Random();
> int dC(int cL, int C_I_R)
> {
> int cd = number.nextInt(C_I_R) + 1;
> cL = cL - 1;
> return cd;
> }
> }
I think everyone understood your question, but the answer to your question
is not how do you do what you want to do. The answer is to do a proper
design. There are several ways as Chris mentioned, but no one can suggest
which one without knowing more about what your problem looks like. What is
the purpose of this variable? It might be that you have it in the wrong
class, but we can't tell that without knowing what its meaning is. Your code
does not help since the variable is not even used.
One possibility is that cL really belongs to the rC class because it is part
of its state, but only you can tell us for sure.
--
Dale King
I really want to know if I seem to have a fundamental understanding of OOPS.
/*A simple card game for test and learning. In this example there are 2
players, named "Jim" and "Mary". Each player in turn draws a hand (3 cards each
in this example) from a deck of random numbers (52 cards in this example). Then
play begins with each player, in turn, drawing a single card to match with
those in his hand. If a match is found that card is negated. Each player then
draws another card. The player who first matches all cards in his hand wins.*/
import java.util.*;
public class Game
{
public static void main(String[] arguments)
{
final int CARDS_IN_DECK = 53;
final int CARDS_IN_SUIT = 13;
final int CARDS_IN_HAND = 3;
int[] cardsLeft = new int[1];
cardsLeft[0] = CARDS_IN_DECK - 1;
int scoredJimHand;
int scoredMaryHand;
//Create a new game called "monte".
Game monte = new Game();
//Later add a class Dealer to create the Deck and shuffle it, also a class
Players to handle various numbers of players and spit out the names as called
for.
//Create a new class Deck called "terpus"
Deck terpus = new Deck();
//Call Method "makeDeck" to return an array "Deck".
int[] Deck = terpus.makeDeck(CARDS_IN_DECK, CARDS_IN_SUIT);
//create a new class Hand named moe.
Hand moe = new Hand();
//call drawHand method to return Jim's hand.
int[] jimHand = new int[CARDS_IN_HAND];
jimHand = moe.drawHand(cardsLeft, CARDS_IN_HAND, Deck);
//call drawHand method to return Mary's hand.
int[] maryHand = new int[CARDS_IN_HAND];
maryHand = moe.drawHand(cardsLeft, CARDS_IN_HAND, Deck);
//Begin repeat until a winner is found or the Deck is exhausted.
do
{
scoredJimHand = 0;
scoredMaryHand = 0;
//call drawCard method to return a playing card for Jim.
DeckCard mimi = new DeckCard();
int jimCard = mimi.drawCard(cardsLeft, Deck);
//call drawCard method to return a playing card for Mary.
int maryCard = mimi.drawCard(cardsLeft, Deck);
//Create a Judge to negate hands and test for a winner (probably should be down
with 2 methods).
Judge dumDum = new Judge();
int univCard = jimCard;
int[] univHand = jimHand;
scoredJimHand = dumDum.scoreHand(univCard, univHand, CARDS_IN_HAND);
univCard = maryCard;
univHand = maryHand;
scoredMaryHand = dumDum.scoreHand(univCard, univHand, CARDS_IN_HAND);
}
while ((scoredJimHand > 0) && (scoredMaryHand > 0) && (cardsLeft[0] >= 2));
//Include a class to report the result of game.
if ((scoredJimHand == 0)&&(scoredMaryHand == 0))
{
System.out.println("Both Mary and Jim are winners. The game is a DRAW.");
}
else if (scoredJimHand == 0)
{
System.out.println("Jim is the winner.");
}
else if (scoredMaryHand == 0)
{
System.out.println("Mary is the winner.");
}
else if (cardsLeft[0] < 2)
{
System.out.println("The deck is empty. There is no winner.");
}
else
{
System.out.println("There is some problem");
}
}
}
//Makes a Deck of random-number cards.
class Deck
{
RandCard twistie = new RandCard();
int[] makeDeck(int CARDS_IN_DECK, int CARDS_IN_SUIT)
{
int dk[] = new int[CARDS_IN_DECK];
for (int i = 0; i < CARDS_IN_DECK; i++)
{
int rCard = twistie.drawCard(CARDS_IN_SUIT);
dk[i] = rCard;
}
return dk;
}
}
//Draws a single card from the top of the Deck.
class DeckCard
{
int drawCard(int[] cardsLeft, int[] Deck)
{
int dcd = Deck[cardsLeft[0]];
cardsLeft[0] = cardsLeft[0] - 1;
return dcd;
}
}
//Makes a Hand by drawing cards from the Deck.
class Hand
{
DeckCard mimi = new DeckCard();
int[] drawHand(int[] cardsLeft, int CARDS_IN_HAND, int[] Deck)
{
int[] hd = new int[CARDS_IN_HAND];
for (int i = 0; i < CARDS_IN_HAND; i++)
{
int Card = mimi.drawCard(cardsLeft, Deck);
hd[i] = Card;
}
return hd;
}
}
//Draws a single random-numbered card.
class RandCard
{
Random number = new Random();
int drawCard(int CARDS_IN_SUIT)
{
int cd = number.nextInt(CARDS_IN_SUIT) + 1;
return cd;
}
}
//Change this so that Judge calls 2 methods: Negate and TestForWinner.
class Judge
{
int scoreHand(int univCard, int[] univHand, int CARDS_IN_HAND)
{
for (int i = 0; i < CARDS_IN_HAND; i++)
{
if (univCard == univHand[i])
{
univHand[i] = 0;
break;
}
}
int sum = 0;
for (int i = 0; i < CARDS_IN_HAND; i++)
{
sum = sum + univHand[i];
}
return sum;
}
}
Thanks to all.
Jim
>Subject: Re: newbie
>From: "Dale King" Ki...@TCE.com
>Date: 7/12/01 1:16 AM Eastern Daylight Time
>Message-id: <3b4dc87b$3...@news.tce.com>
Two things here. First, if you're going to post large amounts of code,
please check that you understand your newsreader enough to make it preserve
formatting. Your code was not indented at all, all being flush against the
left margin. The first thing I had to do in order to look at it was go
through and restore the indentation... there's ten minutes down the drain.
Second, another way to answer Dale's question would have been to post a
description of what you are doing, just as Dale asked you to do.
> The variable of concern is "cardsLeft" and I
> have handled my problem by creating a 1x1 array.
It turns out that the variable is *definitely* in the wrong class. In fact,
it's a local variable. Local variables were never intended to hold state
that is important throughout the execution of the program. The problem,
though, and perhaps the reason you can't move it to the other classes in
your case, is that you are treating classes as functional entities. Each
class only has one method... the "thing" that it does. That's not how
classes work. Classes are data types, and you can generally do quite a few
things to them.
So let's take this in small steps. The first thing I would do is move the
drawCard class from DeckCard to Deck. The reason is that "draw a card" is
an operation you perform on a deck of cards, getting back an individual
card... *not* an opration performed on an individual card. (Once you know
the individual card you want, it's already drawn.) This turns out to be a
rather trivial change, because you haven't done any object oriented
programming... so the class doesn't really contain any state at all. Just
cut and paste the method body.
Now that the drawCard method is in the right place, it becomes very easy to
move cardsLeft to an instance field of Deck. That's where is belongs... the
number of cards left is, logically, a property of the deck of cards. Of
course, you need to know the number of cards left logically elsewhere in
your program, so you add a new operation to Deck to count the number of
cards left.
All this time, you've been passing around integers and integer arrays for
all of your data. You've missed the entire *point* of an object oriented
approach. Object oriented programming abstracts you away from the
representations of your data, so that you interact with concepts, such as
Deck or DeckCard. Hence, you should add instance variables to Deck and
DeckCard to represent your underlying data structures.
Your deck needs to be built. Right now, you have a makeDeck method in Deck
that does this. It makes sense to convert this to a constructor, since it's
involved in creating an instance of the class.
The result might look something like this (I'm leaving your other classes
alone... we are taking it in small steps. So this is still not an optimal
design):
//Represents a deck of cards.
class Deck
{
private DeckCard[] cards;
private int cardsLeft;
private RandCard twistie = new RandCard();
public Deck(int cardsInDeck, int cardsInSuit)
{
cards = new DeckCard[cardsInDeck];
for (int i = 0; i < cardsInDeck; i++)
{
int rCard = twistie.drawCard(cardsInSuit);
cards[i] = new DeckCard(rCard);
}
cardsLeft = cardsInDeck;
}
public DeckCard drawCard()
{
DeckCard card = cards[cardsLeft - 1];
cardsLeft = cardsLeft - 1;
return card;
}
public int getCardsLeft()
{
return cardsLeft;
}
}
//Represents a card in a deck.
class DeckCard
{
private int cardValue;
public DeckCard(int value)
{
cardValue = value;
}
public int getCardValue()
{
return cardValue;
}
}
I've made some other improvements as well, such as adding access qualifiers
and changing your names to fit Sun coding conventions, as well as modifying
your comments to refer to your classes as data abstractions, not processes.
Notice that you can now do something like this:
Deck myDeck = new Deck(52, 13);
Card card1 = myDeck.drawCard();
Card card2 = myDeck.drawCard();
if (myDeck.getCardsLeft() < 2)
{
...
}
and all the while, you don't need to worry about the data structures you are
really using to represent this data.
I'll leave the rest to you. Some of your goals should be to prevent the big
bulk of your code from occurring in one method (always a sign of poor OO
design), to make the Hand class and other classes also represent an
abstraction of data rather than just a method pertaining to that data, and
to otherwise make your code more readable, modular, and object oriented.
You ought to reconsider whether RandCard is really a class (data item) at
all, or if it should be turned into just another method used inside the Deck
class. I don't think it really represents any logical entities in the
game... more the process of getting a random card. Unless you've got a good
reason otherwise, that should then be a method (methods are processes,
classes are types of things).
> I really want to know if I seem to have a fundamental understanding of
OOPS.
>
That does indeed seem to be the point of confusion.
Chris Smith
int someMethod(int someInt)
{
someInt = 20; // (or whatever)
return someInt;
}
Is that what you are asking?
I'm very confused about classes. At a top level, just what is a class? How
should I go about it to analyze a problem to best determine what classes I
should have and what should be included under each?
Patricia gave some good ideas to help understand objects and methods but I'm
still at-sea on classes. Can you help?
Thanks also to Adam for his suggestion.
Jim
>Subject: Re: newbie
>From: "Chris Smith" cds...@twu.net
>Date: 7/14/01 10:57 AM Eastern Daylight Time
>Message-id: <9ipmpe$8il$0...@dosa.alt.net>
Jim Simpson wrote:
>
> Thanks Chris for taking the time to review my code and give me your
> ideas--sorry about the formating.
>
> I'm very confused about classes. At a top level, just what is a class? How
> should I go about it to analyze a problem to best determine what classes I
> should have and what should be included under each?
>
> Patricia gave some good ideas to help understand objects and methods but I'm
> still at-sea on classes. Can you help?
>
> Thanks also to Adam for his suggestion.
A class is a class of objects that all have the same "shape", the same
methods and attributes, though different values for those attributes.
For example, if you have a game with two players, there will be a class
Player with two objects, one for each.
Every object has to belong to a class, so even if you only need one
object of a given shape, you need a class for it. Even if you only have
one deck of cards, that deck should still be an instance of a class
Deck.
Patricia
Thanks for all your help.
Jim
>Subject: Re: newbie
>From: Patricia Shanahan pa...@acm.org
>Date: 7/16/01 9:05 AM Eastern Daylight Time
>Message-id: <3B52E778...@acm.org>
Jim
>Subject: Re: newbie
>From: Adam Sanders asan...@cs.olemiss.edu
>Date: 7/15/01 12:49 AM Eastern Daylight Time
>Message-id: <3B5120E2...@cs.olemiss.edu>
>Subject: Re: newbie
>From: Patricia Shanahan pa...@acm.org
>Date: 7/16/01 9:05 AM Eastern Daylight Time
>Message-id: <3B52E778...@acm.org>
Jim
>Subject: Re: newbie
>From: "Chris Smith" cds...@twu.net
>Date: 7/14/01 10:57 AM Eastern Daylight Time
>Message-id: <9ipmpe$8il$0...@dosa.alt.net>
Your confusion is probably my fault. At one point (when I defined the
class) I called it DeckCard. Later (in example usage code), I called it
Card. Those were supposed to be the same class. Card is the simpler
name... DeckCard is what it was in your original code... and I used each at
different times by mistake.
Chris Smith
The following left for reference...
> >//Represents a card in a deck.
> >class DeckCard
> >{
> > private int cardValue;
> >
> > public DeckCard(int value)
> > {
> > cardValue = value;
> > }
> >
> > public int getCardValue()
> > {
> > return cardValue;
> > }
> >}
> >
Jim>Subject: Re: newbie
>From: "Chris Smith" cds...@twu.net
>Date: 7/24/01 9:07 PM Eastern Daylight Time
>Message-id: <9jl65u$7ll$0...@pita.alt.net>
Well, instances of the Card class were intended to represent cards from
the deck. Since you use integers to represent cards, and I didn't want
to walk backward through your code to find out how you were encoding Card
properties in those integers, I just added cardValue (an int) as a
property of Card... not ideal, but it's a start, at least.
In reality, unless you're working with an abnormal type of deck, you'll
probably want to replace that with rank and suit properties.
Remember, what I gave you was a start, to get you going in the right
direction... it wasn't a fix for everything wrong with the code.
Chris Smith
OK Chris. I can carry on from here, I think. Thanks for all your time.
Jim