Numbers Game Source

(Last Update 12:35 on Thursday, 13 December 2001)

// Numbers Game applet
// Neil Rashbrook
// Last modified June 28 2001
import java.awt.*;
import java.awt.event.*;
public class numbers extends java.applet.Applet implements Runnable {
private int target, best, length;
private Checkbox a;
private Button q, r, s;
private TextArea o;
private Choice h, t, u, b, v[] = new Choice[6];
private Panel north, center, south;
private String all[], oldText;
public numbers() throws Exception {
setLayout(new BorderLayout());
north = new Panel();
center = new Panel();
south = new Panel();
super.add("North", north);
super.add("Center", center);
super.add("South", south);
north.add(q = new Button("Random"));
north.add((Component)(h = createChoice(1, 9, false)));
north.add((Component)(t = createChoice(0, 9, false)));
north.add((Component)(u = createChoice(0, 9, false)));
north.add(a = new Checkbox("All"));
north.add(s = new Button("Submit"));
north.add(r = new Button("Reset"));
GridBagLayout gbl;
center.setLayout(gbl = new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
center.add(o = new TextArea(10, 40));
o.setEditable(false);
o.disable();
gbc.fill = gbc.VERTICAL;
gbc.weighty = 1;
gbl.setConstraints(o, gbc);
south.add(b = createChoice(1, 0, false));
b.addItem("0/6");
b.addItem("1/5");
b.addItem("2/4");
b.addItem("3/3");
b.addItem("4/2");
b.addItem("Any");
b.select(5);
for (int i = 0; i < 6; i++) south.add((Component)(v[i] = createChoice(1, 9, true)));
random();
}
private static Class choice;
static {
try {
choice = Class.forName("choice");
} catch (Exception e) {
}
}
private static Choice createChoice(int low, int high, boolean ext) {
Choice c;
try {
c = (Choice)choice.newInstance();
} catch (Exception e) {
c = new Choice();
}
for (int i = low; i <= high; i++) c.addItem(new StringBuffer(1).append((char)(i + '0')).toString());
if (ext) {
c.addItem("10");
c.addItem("25");
c.addItem("50");
c.addItem("75");
c.addItem("100");
high += 5;
}
return c;
}
private void check(value[] values, int i, int j, int n, value e) {
if (all == null) {
int diff = n - target;
if (diff < 0) diff = -diff;
if (diff > best) return;
if (diff == best && values.length < length) return;
for (int k = 0; k < values.length; k++)
if (k != i && k != j && (e.after(values[k]) || values[k].scan(e))) return;
if (diff < best || values.length > length) o.setText(oldText);
best = diff;
length = values.length;
o.appendText("\n" + n + " = " + e);
} else if (n > 0 && n < 1000) {
String s = e.toString();
if (all[n] != null && all[n].length() <= s.length()) return;
for (int k = 0; k < values.length; k++)
if (k != i && k != j && (e.after(values[k]) || values[k].scan(e))) return;
if (all[n] == null) showStatus("" + ++length);
else o.setText("");
all[n] = s;
o.appendText("\n" + n + " = " + s);
} else if (all[0] == null || n <= best) {
String s = e.toString();
if (all[0] != null && n == best && all[0].length() <= s.length()) return;
if (all[0] != null) o.setText("");
all[0] = s;
best = n;
o.appendText("\n" + n + " = " + s);
}
}
private void resolve(value[] values, int order, int i, int j, value e) {
value[] newval = new value[values.length - 1];
if (i < j) {
System.arraycopy(values, 0, newval, 0, j);
System.arraycopy(values, j + 1, newval, j, newval.length - j);
newval[i] = e;
} else {
System.arraycopy(values, 0, newval, 0, i);
System.arraycopy(values, i + 1, newval, i, newval.length - i);
newval[j] = e;
}
solve(newval, order);
}
private void solve(value[] values, int order) {
order--;
for (int i = 0; i < values.length; i++) {
value ie = values[i];
int iv = ie.value;
for (int j = 0; j < values.length; j++) {
if (i == j) continue;
value je = values[j];
int jv = je.value;
if (iv < jv) continue;
if (ie.op != null && ie.after(je)) continue;
if (ie.scan(je)) continue;
int result;
value re;
if (je.op != value.TIMES && je.op != value.DIVIDE && jv > 1) {
if (ie.op != value.DIVIDE && (ie.op != value.TIMES || je.lower(ie.right))) {
result = iv * jv;
re = new value(order, result, ie, value.TIMES, je);
check(values, i, j, result, re);
if (result == target) return;
if (values.length > 2) resolve(values, order, i, j, re);
}
if (ie.op != value.DIVIDE || je.lower(ie.right)) {
if (iv % jv == 0 && (result = iv / jv) != jv) {
re = new value(order, result, ie, value.DIVIDE, je);
check(values, i, j, result, re);
if (result == target) return;
if (values.length > 2) resolve(values, order, i, j, re);
}
}
}
if (je.op != value.PLUS && je.op != value.MINUS) {
if (ie.op != value.MINUS && (ie.op != value.PLUS || je.lower(ie.right))) {
result = iv + jv;
re = new value(order, result, ie, value.PLUS, je);
check(values, i, j, result, re);
if (result == target) return;
if (values.length > 2) resolve(values, order, i, j, re);
}
if (ie.op != value.MINUS || je.lower(ie.right)) {
result = iv - jv;
if (result != 0 && result != jv) {
re = new value(order, result, ie, value.MINUS, je);
check(values, i, j, result, re);
if (result == target) return;
if (result > 1 && values.length > 2) resolve(values, order, i, j, re);
}
}
}
}
}
}
public void run() {
if (a.getState()) {
o.setText("");
all = new String[1000];
target = 0;
best = Integer.MAX_VALUE;
} else {
oldText = o.getText();
best = target = Integer.parseInt(h.getSelectedItem()) * 100 + Integer.parseInt(t.getSelectedItem()) * 10 + Integer.parseInt(u.getSelectedItem());
}
length = 0;
value[] values = new value[6];
for (int i = 0; i < 6; i++) {
int j = Integer.parseInt(v[i].getSelectedItem());
values[i] = new value(i, j);
if (all != null && all[j] == null) {
all[j] = v[i].getSelectedItem();
length++;
}
}
solve(values, 12);
if (all != null) {
o.setText("");
StringBuffer sb = new StringBuffer(32000);
for (int i = 1; i < 1000; i++) sb.append('\n').append(i).append(" = ").append(all[i]);
if (all[0] != null) sb.append('\n').append(best).append(" = ").append(all[0]);
o.setText(sb.toString());
all = null;
}
o.appendText("\n");
north.enable();
south.enable();
}
private boolean alldone() {
if (a.getState()) {
h.disable();
t.disable();
u.disable();
} else {
h.enable();
t.enable();
u.enable();
}
return true;
}
private boolean all() {
a.requestFocus();
a.setState(!a.getState());
return alldone();
}
private boolean reset() {
o.setText("");
focusForward(this, null);
return true;
}
private boolean submit() {
o.enable();
o.requestFocus();
north.disable();
south.disable();
(new Thread(this)).start();
return true;
}
private static java.util.Random random = new java.util.Random();
private boolean random() {
h.select((random.nextInt() & 07777777777) % 9);
t.select((random.nextInt() & 07777777777) % 10);
u.select((random.nextInt() & 07777777777) % 10);
//for (int i = 0; i < 6; i++) v[i].select((random.nextInt() & 07777777777) % 10);
int b = this.b.getSelectedIndex();
int temp[] = new int[6];
int used[] = new int[14];
for (int i = 0; i < 6; i++) {
do {
if (b == 5) temp[i] = (random.nextInt() & 07777777777) % 14;
else if (i < b) temp[i] = 10 + (random.nextInt() & 3);
else temp[i] = (random.nextInt() & 07777777777) % 10;
} while (used[temp[i]] > (temp[i] > 9 ? 0 : 1));
used[temp[i]]++;
}
for (int i = 0; i < 4; i++) {
if (temp[i] <= 9) {
for (int j = i + 1; j < 6; j++) {
if (temp[j] > 9) {
int k = temp[j];
temp[j] = temp[i];
temp[i] = k;
break;
}
}
}
}
for (int i = 0; i < 6; i++) v[i].select(temp[i]);
return true;
}
public boolean action(Event e, Object arg) {
if (e.target == q) return random();
if (e.target == r) return reset();
if (e.target == s) return submit();
if (e.target == a) return alldone();
return false;
}
private void focusForward(Container cont, Component comp) {
if (cont == null) cont = comp.getParent();
boolean found = comp == null;
Component ca[] = cont.getComponents();
for (int i = 0; i < ca.length; i++) {
Component temp = ca[i];
if (temp == comp) found = true;
else if (found && temp.isEnabled()) {
if (temp instanceof Container) focusForward((Container)temp, null);
else temp.requestFocus();
return;
}
}
if (cont != this) focusForward(null, cont);
else if (comp != null) focusForward(this, null);
}
private void focusBackward(Container cont, Component comp) {
if (cont == null) cont = comp.getParent();
boolean found = comp == null;
Component ca[] = cont.getComponents();
for (int i = ca.length; i-- > 0; ) {
Component temp = ca[i];
if (temp == comp) found = true;
else if (found && temp.isEnabled()) {
if (temp instanceof Container) focusBackward((Container)temp, null);
else temp.requestFocus();
return;
}
}
if (cont != this) focusBackward(null, cont);
else if (comp != null) focusBackward(this, null);
}
public boolean keyDown(Event e, int key) {
if (north.isEnabled()) {
if (e != null && e.target instanceof Choice && keyChoice((Choice)e.target, key)) return true;
switch (key) {
case 'a': case 'A': return all();
case '?': return random();
case 27: return reset();
case 13: case 10: return submit();
case 9:
if ((e.modifiers & ~e.SHIFT_MASK) == 0) {
Component source = (Component)e.target;
if (e.modifiers == 0) focusForward(null, source);
else focusBackward(null, source);
return true;
}
}
}
return false;
}
static boolean keyChoice(Choice c, int key) {
switch (c.countItems()) {
case 6:
switch (key) {
case 'A': case 'a':
c.select(5);
return true;
}
if (key < '0' || key > '4') return false;
c.select(key - '0');
break;
case 9:
if (key < '1' || key > '9') return false;
c.select(key - '1');
break;
case 10:
if (key < '0' || key > '9') return false;
c.select(key - '0');
break;
default:
switch (key) {
case '1':
switch (c.getSelectedIndex()) {
case 9: case 10: case 11: case 12: c.select(13); break;
case 13: c.select(0); break;
default: c.select(9); break;
}
break;
case '2':
switch (c.getSelectedIndex()) {
case 0: case 10: case 11: case 12: case 13: c.select(1); break;
default: c.select(10); break;
}
break;
case '5':
switch (c.getSelectedIndex()) {
case 4: case 5: case 6: case 7: case 8: case 9: case 10: c.select(11); break;
default: c.select(4); break;
}
break;
case '7':
switch (c.getSelectedIndex()) {
case 6: case 7: case 8: case 9: case 10: case 11: c.select(12); break;
default: c.select(6); break;
}
break;
case '3': case '4': case '6': case '8': case '9':
c.select(key - '1'); break;
default:
return false;
}
}
return true;
}
public void start() {
focusForward(this, null);
}
}
class choice extends Choice implements ItemListener {
PopupMenu menu = new PopupMenu();
CheckboxMenuItem items[] = new CheckboxMenuItem[14];
public void addNotify() {
super.addNotify();
super.getParent().add(menu);
super.enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK);
}
public void addItem(String text) {
int count = super.getItemCount();
CheckboxMenuItem item = new CheckboxMenuItem(text);
item.addItemListener(this);
items[count] = item;
if (count == 0) item.setState(true);
menu.add(item);
super.addItem(text);
}
public void select(int pos) {
if (super.getSelectedIndex() >= 0) items[super.getSelectedIndex()].setState(false);
items[pos].setState(true);
super.select(pos);
}
public void select(String text) {
if (super.getSelectedIndex() >= 0) items[super.getSelectedIndex()].setState(false);
super.select(text);
items[super.getSelectedIndex()].setState(true);
}
public void processKeyEvent(KeyEvent evt) {
if (evt.getID() == KeyEvent.KEY_TYPED) {
char key = evt.getKeyChar();
if (!numbers.keyChoice(this, key) && key != 9) super.getParent().getParent().keyDown(null, key);
}
super.processKeyEvent(evt);
}
public void processMouseEvent(MouseEvent evt) {
if (evt.isPopupTrigger()) {
super.requestFocus();
Rectangle r = super.getBounds();
menu.show(super.getParent(), r.x, r.y - super.getSelectedIndex() * (((Container)super.getParent().getParent().getComponent(0)).getComponent(0).getSize().height * 2 - 4 - r.height));
}
super.processMouseEvent(evt);
}
public void itemStateChanged(ItemEvent evt) {
select((String)evt.getItem());
}
}
class value {
static public String PLUS = " + ", MINUS = " - ", TIMES = " × ", DIVIDE = " ÷ ";
int terms, lowest, order, value;
String op;
value left, right;
value(int o, int i) {
terms = 6;
lowest = order = o;
value = i;
}
value(int o, int i, value l, String op, value r) {
terms = l.terms + r.terms;
lowest = l.lowest < r.lowest ? l.lowest + r.terms : r.lowest + l.terms;
order = o;
value = i;
left = l;
this.op = op;
right = r;
}
boolean lower(value e) {
if (value != e.value) return value < e.value;
return lowest < e.lowest;
}
boolean after(value e) {
return e != null && (order < e.order || after(e.left) || after(e.right));
}
boolean scan(value e) {
if (value == e.value && lowest < e.lowest) return true;
if (e.op != null && (scan(e.left) || scan(e.right))) return true;
if (op != null && (left.scan(e) || right.scan(e))) return true;
return false;
}
private boolean bracket(value e) {
if (op == PLUS || op == MINUS) return e.op == TIMES || e.op == DIVIDE;
if (op == TIMES || op == DIVIDE) return e.op == PLUS || e.op == MINUS;
throw new InternalError();
}
public String toString() {
if (op == null) return "" + value;
StringBuffer sb = new StringBuffer();
if (bracket(left)) sb.append('(').append(left).append(')');
else sb.append(left);
sb.append(op);
if (bracket(right)) sb.append('(').append(right).append(')');
else sb.append(right);
return sb.toString();
}
}

Frames Version
Customization Page
Back to Numbers Game Page


619617
38.107.191.97