Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

E-Bookshop-master / uploads / file / Think-Java-How-to-Think-Like-a-Computer-Scientist_(1)

.pdf
Скачиваний:
35
Добавлен:
28.06.2021
Размер:
2.86 Mб
Скачать

120

Chapter 9. Mutable objects

BigInteger small = BigInteger.valueOf(17); BigInteger big = BigInteger.valueOf(1700000000); BigInteger total = small.add(big);

Try out some of the other methods, like multiply and pow.

7.Convert factorial so that it performs its calculation using BigIntegers and returns a BigInteger as a result. You can leave the parameter alone|it will still be an integer.

8.Try printing the table again with your modi ed factorial method. Is it correct up to 30? How high can you make it go? I calculated the factorial of all the numbers from 0 to 999, but my machine is pretty slow, so it took a while. The last number, 999!, has 2565 digits.

Exercise 9.5. Many encryption techniques depend on the ability to raise large integers to an integer power. Here is a method that implements a (reasonably) fast technique for integer exponentiation:

public static int pow(int x, int n) { if (n==0) return 1;

//find x to the n/2 recursively int t = pow(x, n/2);

//if n is even, the result is t squared

//if n is odd, the result is t squared times x

if (n%2 == 0) { return t*t;

}else { return t*t*x;

}

}

The problem with this method is that it only works if the result is smaller than 2 billion. Rewrite it so that the result is a BigInteger. The parameters should still be integers, though.

You can use the BigInteger methods add and multiply, but don't use pow, which would spoil the fun.

9.14. Exercises

121

Exercise 9.6. If you are interested in graphics, now is a good time to read Appendix A and do the exercises there.

122

Chapter 9. Mutable objects

Chapter 10

GridWorld: Part 2

Part 2 of the GridWorld case study uses some features we haven't seen yet, so you will get a preview now and more details later. As a reminder, you can nd the documentation for the GridWorld classes at http: //www.greenteapress.com/thinkapjava/javadoc/gridworld/.

When you install GridWorld, you should have a folder named projects/boxBug, which contains BoxBug.java, BoxBugRunner.java and BoxBug.gif.

Copy

these les into your working folder and import them into

your

development environment.

There are instructions here that

might

help: http://www.collegeboard.com/prod_downloads/student/

testing/ap/compsci_a/ap07_gridworld_installation_guide.pdf.

Here is the code from BoxBugRunner.java:

import info.gridworld.actor.ActorWorld; import info.gridworld.grid.Location;

import java.awt.Color;

public class BoxBugRunner {

public static void main(String[] args) { ActorWorld world = new ActorWorld(); BoxBug alice = new BoxBug(6);

124

Chapter 10. GridWorld: Part 2

alice.setColor(Color.ORANGE); BoxBug bob = new BoxBug(3);

world.add(new Location(7, 8), alice); world.add(new Location(5, 5), bob); world.show();

}

}

Everything here should be familiar, with the possible exception of Location, which is part of GridWorld, and similar to java.awt.Point.

BoxBug.java contains the class de nition for BoxBug.

public class BoxBug extends Bug { private int steps;

private int sideLength;

public BoxBug(int length) { steps = 0;

sideLength = length;

}

}

The rst line says that this class extends Bug, which means that a BoxBug is a kind of Bug.

The next two lines are instance variables. Every Bug has variables named sideLength, which determines the size of the box it draws, and steps, which keeps track of how many steps the Bug has taken.

The next line de nes a constructor, which is a special method that initializes the instance variables. When you create a Bug by invoking new, Java invokes this constructor.

The parameter of the constructor is the side length.

Bug behavior is controlled by the act method. Here is the act method for

BoxBug:

public void act() {

if (steps < sideLength && canMove()) { move();

10.1. Termites

125

steps++;

}

else { turn(); turn(); steps = 0;

}

}

If the BoxBug can move, and has not taken the required number of steps, it moves and increments steps.

If it hits a wall or completes one side of the box, it turns 90 degrees to the right and resets steps to 0.

Run the program and see what it does. Did you get the behavior you expected?

Exercise 10.1. Now you know enough to do the exercises in the Student Manual, Part 2. Go do them, and then come back for more fun.

10.1Termites

I wrote a class called Termite that extends Bug and adds the ability to interact with owers.

To run it, download these les and import them into your development environment:

http://thinkapjava.com/code/Termite.java

http://thinkapjava.com/code/Termite.gif

http://thinkapjava.com/code/TermiteRunner.java

Because Termite extends Bug, all Bug methods also work on Termites. But Termites have additional methods that Bugs don't have.

/**

* Returns true if the termite has a flower. */

public boolean hasFlower();

126

Chapter 10. GridWorld: Part 2

/**

* Returns true if the termite is facing a flower. */

public boolean seeFlower();

/**

* Creates a flower unless the termite already has one. */

public void createFlower();

/**

*Drops the flower in the termites current location.

*Note: only one Actor can occupy a grid cell, so the effect of

*dropping a flower is delayed until the termite moves.

*/

public void dropFlower();

/**

* Throws the flower into the location the termite is facing.

*

*/

public void throwFlower();

/**

*Picks up the flower the termite is facing, if there is one,

*and if the termite doesn't already have a flower.

*/

public void pickUpFlower();

For some methods Bug provides one de nition and Termite provides another. In that case, the Termite method overrides the Bug method.

For example, Bug.canMove returns true if there is a ower in the next location, so Bugs can trample Flowers. Termite.canMove returns false if there is any object in the next location, so Termite behavior is di erent.

As another example, Termites have a version of turn that takes an integer number of degrees as a parameter. Finally, Termites have randomTurn, which

10.1. Termites

127

turns left or right 45 degrees at random.

Here is the code from TermiteRunner.java:

public class TermiteRunner

{

public static void main(String[] args)

{

ActorWorld world = new ActorWorld(); makeFlowers(world, 20);

Termite alice = new Termite(); world.add(alice);

Termite bob = new Termite(); bob.setColor(Color.blue); world.add(bob);

world.show();

}

public static void makeFlowers(ActorWorld world, int n) { for (int i=0; i<n; i++) {

world.add(new EternalFlower());

}

}

}

Everything here should be familiar. TermiteRunner creates an ActorWorld with 20 EternalFlowers and two Termites.

An EternalFlower is a Flower that overrides act so the owers don't get darker.

class EternalFlower extends Flower { public void act() {}

}

If you run TermiteRunner.java you should see two termites moving at random among the owers.

128

Chapter 10. GridWorld: Part 2

MyTermite.java demonstrates the methods that interact with owers. Here is the class de nition:

public class MyTermite extends Termite {

public void act() {

if (getGrid() == null) return;

if (seeFlower()) { pickUpFlower();

}

if (hasFlower()) { dropFlower();

}

if (canMove()) { move();

}

randomTurn();

}

}

MyTermite extends Termite and overrides act. If MyTermite sees a ower, it picks it up. If it has a ower, it drops it.

Exercise 10.2. The purpose of this exercise is to explore the behavior of Termites that interact with owers.

Modify TermiteRunner.java to create MyTermites instead of Termites. Then run it again. MyTermites should move around at random, moving theowers around. The total number of owers should stay the same (including the ones MyTermites are holding).

In Termites, Turtles and Tra c Jams, Mitchell Resnick describes a simple model of termite behavior:

If you see a ower, pick it up. Unless you already have a ower; in that case, drop the one you have.

Move forward, if you can.

10.2. Langton's Termite

129

Turn left or right at random.

Modify MyTermite.java to implement this model. What e ect do you think this change will have on the behavior of MyTermites?

Try it out. Again, the total number of owers does not change, but over time the owers accumulate in a small number of piles, often just one.

This behavior is an an emergent property, which you can read about at http: // en. wikipedia. org/ wiki/ Emergence . MyTermites follow simple rules using only small-scale information, but the result is large-scale organization.

Experiment with di erent rules and see what e ect they have on the system. Small changes can have unpredicable results!

10.2Langton's Termite

Langton's Ant is a simple model of ant behavior that displays surprisingly complex behavior. The Ant lives on a grid like GridWorld where each cell is either white or black. The Ant moves according to these rules:

If the Ant is on a white cell, it turns to the right, makes the cell black, and moves forward.

If the Ant is on a black cell, it turns to the left, makes the cell white, and moves forward.

Because the rules are simple, you might expect the Ant to do something simple like make a square or repeat a simple pattern. But starting on a grid with all white cells, the Ant makes more than 10,000 steps in a seemingly random pattern before it settles into a repeating loop of 104 steps.

You can read more about Langton's Ant at http://en.wikipedia.org/ wiki/Langton_ant.

It is not easy to implement Langton's Ant in GridWorld because we can't set the color of the cells. As an alternative, we can use Flowers to mark

Соседние файлы в папке file