import java.awt.*;
import java.applet.*;
import java.util.Date;
import java.util.Random;
public class MicrosoftColorSort extends Applet {
java.awt.Button sort;
java.awt.Button reset;
Ball[] balls;
int[] colors;
boolean[] isColorUsed;
int totalColors = 10;
int totalBalls = 600;
int xs[];
int ys[];
public void init() {
setBackground(Color.WHITE);
add(reset = new java.awt.Button("Reset"));
add(sort = new java.awt.Button("Sort"));
}
public boolean handleEvent(Event event) {
if (event.target == sort && event.id == Event.ACTION_EVENT) {
doSort(event);
return true;
}
if (event.target == reset && event.id == Event.ACTION_EVENT) {
doReset(event);
return true;
}
return super.handleEvent(event);
}
public void paint(Graphics g) {
drawString("Usage: Click Reset, then Sort", 10, 20);
}
private void doReset(Event event) {
int x = 10;
int y = 10;
int xOffset = 20;
int yOffset = 20;
colors = new int[totalColors];
isColorUsed = new boolean[totalColors];
this.getGraphics().clearRect(0, 30, this.getWidth(), this.getHeight());
for (int i = 0; i < totalColors; i++) {
colors[i] = i;
}
int theColor = 0;
balls = new Ball[totalBalls];
xs = new int[totalBalls];
ys = new int[totalBalls];
for (int i = 0; i < totalBalls; i++) {
x += xOffset;
if ((i % 25) == 0) {
y += yOffset;
x = 10;
}
theColor = new Random(new Date().getTime()).nextInt(1000000) % totalColors;
balls[i] = new Ball(theColor);
xs[i] = x;
ys[i] = y;
if (!isColorUsed[theColor]) {
isColorUsed[theColor] = true;
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
balls[i].draw(xs[i], ys[i], this.getGraphics());
}
}
private void drawString(String message, int x, int y) {
this.getGraphics().setColor(Color.black);
this.getGraphics().drawString(message, x, y);
}
private void drawBalls() {
this.getGraphics().clearRect(0, 30, 20 * 25, this.getHeight());
for (int i = 0; i<totalBalls; i++) {
balls[i].draw(xs[i], ys[i], this.getGraphics());
}
}
void doSort(Event event) {
int start = 0;
int yOffset = 40;
int x = 540;
drawString("Start indices", 540, yOffset);
Ball displayBall = null;
for (int i = 0; i < totalColors; i++) {
if (isColorUsed[i]) {
displayBall = new Ball(i);
displayBall.draw(x, (i + 2) * yOffset, this.getGraphics());
drawString(" - " + ((i == 0) ? 0: start), x + 22, ((i + 2) * yOffset) + 15 );
start = partition(balls, colors[i], start);
drawBalls();
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
}
public int partition(Ball[] balls, int sortingColor, int startIndex) {
int i = startIndex;
int j = balls.length - 1;
int ithColor = 0;
int jthColor = 0;
Ball tmpBall = null;
while (i <= j) {
ithColor = balls[i].getBallColor();
jthColor = balls[j].getBallColor();
if ((ithColor == sortingColor) && (jthColor == sortingColor)) {
i++;
} else if ((ithColor == sortingColor) && (jthColor != sortingColor)) {
i++;
} else if ((ithColor != sortingColor) && (jthColor != sortingColor)) {
j--;
} else if ((ithColor != sortingColor) && (jthColor == sortingColor)) {
tmpBall = balls[i];
balls[i] = balls[j];
balls[j] = tmpBall;
i++;
j--;
}
}
return i;
}
}
class Ball {
private Color ballColor;
private int colorIndex;
public Ball(int colorIndex) {
switch (colorIndex) {
case 0:
ballColor = Color.black;
break;
case 1:
ballColor = Color.blue;
break;
case 2:
ballColor = Color.cyan;
break;
case 3:
ballColor = Color.lightGray;
break;
case 4:
ballColor = Color.green;
break;
case 5:
ballColor = Color.magenta;
break;
case 6:
ballColor = Color.orange;
break;
case 7:
ballColor = Color.pink;
break;
case 8:
ballColor = Color.red;
break;
case 9:
ballColor = Color.yellow;
break;
}
this.colorIndex = colorIndex;
}
public int getBallColor() {
return colorIndex;
}
public void draw(int x, int y, Graphics g) {
g.setColor(ballColor);
g.fillOval(x, y, 20, 20);
g.setColor(Color.white);
g.drawString("" + colorIndex, x + 7, y + 14);
}
}