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();
- }
- }

38.107.191.97