import java.lang.*; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.util.*; final class NumberplaceTextField extends TextField implements FocusListener { NumberplaceMatrix _npmListener; int _xGrid, _yGrid; NumberplaceTextField(NumberplaceMatrix npmListener, int xGrid, int yGrid, int iNumber) { super(iNumber == 0 ? "" : String.valueOf(iNumber)); _npmListener = npmListener; _xGrid = xGrid; _yGrid = yGrid; addFocusListener(this); } final public void focusGained(FocusEvent fe) { } final public void focusLost(FocusEvent fe) { _npmListener.closeField(this); } final public int y() { return _yGrid; } final public int x() { return _xGrid; } } final class NumberplaceMatrix extends Panel implements MouseListener, ComponentListener { int _iGrid; int _aiNumbers[][], _xMatrix, _yMatrix; FontMetrics _fm; NumberplaceFrame _npfListener; NumberplaceMatrix(NumberplaceFrame npfListener, int aiNumbers[][], int xMatrix, int yMatrix) { _npfListener = npfListener; _xMatrix = xMatrix; _yMatrix = yMatrix; _aiNumbers = aiNumbers; _iGrid = aiNumbers.length; addMouseListener(this); addComponentListener(this); } final public void mouseClicked(MouseEvent me) { } final public void mouseEntered(MouseEvent me) { } final public void mouseExited(MouseEvent me) { } final public void mousePressed(MouseEvent me) { Dimension dimWindow = getSize(); openField(me.getX() * _iGrid / dimWindow.width, me.getY() * _iGrid / dimWindow.height); } final public void openField(int xGrid, int yGrid) { Dimension dimWindow = getSize(); int cxWindow = dimWindow.width, cyWindow = dimWindow.height; NumberplaceTextField nptf = new NumberplaceTextField(this, xGrid, yGrid, _aiNumbers[yGrid][xGrid]); int xOrigin = xGrid * cxWindow / _iGrid, yOrigin = yGrid * cyWindow / _iGrid; nptf.setBounds(xOrigin, yOrigin, (xGrid + 1) * cxWindow / _iGrid - xOrigin, (yGrid + 1) * cyWindow / _iGrid - yOrigin); add(nptf); nptf.setVisible(true); nptf.requestFocus(); } final public void mouseMoved(MouseEvent me) { } final public void mouseDragged(MouseEvent me) { } final public void mouseReleased(MouseEvent me) { } final public void closeField(NumberplaceTextField nptf) { String str = nptf.getText(); int xGrid = nptf.x(), yGrid = nptf.y(); remove(nptf); if (str.length() == 0) { _aiNumbers[yGrid][xGrid] = 0; } else { try { int iNumber = Integer.parseInt(str); if (iNumber > 0 && iNumber <= _iGrid * _iGrid) { _aiNumbers[yGrid][xGrid] = iNumber; } } catch (Exception e) { } } } final public void nextField(NumberplaceTextField nptf) { int xGrid = nptf.x(), yGrid = nptf.y(); closeField(nptf); if ((xGrid = xGrid + 1) == _iGrid) { xGrid = 0; if ((yGrid = yGrid + 1) == _iGrid) { _npfListener.nextField(_xMatrix, _yMatrix); return; } } openField(xGrid, yGrid); } final public void paint(Graphics g) { Dimension dimWindow = getSize(); int cxWindow = dimWindow.width, cyWindow = dimWindow.height; int yOffset2 = 0xffff; for (int iLine = 0; iLine <= _iGrid; iLine++) { int iCoord = iLine * (cxWindow - 1) / _iGrid; g.drawLine(iCoord, 0, iCoord, cyWindow - 1); iCoord = iLine * (cyWindow - 1) / _iGrid; g.drawLine(0, iCoord, cxWindow - 1, iCoord); } for (int yGrid = 0; yGrid < _iGrid; yGrid++) { for (int xGrid = 0; xGrid < _iGrid; xGrid++) { int iNumber; if ((iNumber = _aiNumbers[yGrid][xGrid]) != 0) { if (_fm == null) { _fm = getFontMetrics(getFont()); } if (yOffset2 == 0xffff) { yOffset2 = _fm.getMaxAscent() - _fm.getMaxDescent(); } String str = String.valueOf(iNumber); int xOrigin = ((xGrid * 2 + 1) * cxWindow / _iGrid - _fm.stringWidth(str)) / 2, yOrigin = ((yGrid * 2 + 1) * cyWindow / _iGrid + yOffset2) / 2; g.drawString(str, xOrigin, yOrigin); } } } } final public void refresh(int xGrid, int yGrid, boolean fWait) { Dimension dimWindow = getSize(); int cxWindow = dimWindow.width, cyWindow = dimWindow.height; int xOrigin = xGrid * cxWindow / _iGrid, yOrigin = yGrid * cyWindow / _iGrid; repaint(xOrigin, yOrigin, (xGrid + 1) * cxWindow / _iGrid - xOrigin, (yGrid + 1) * cyWindow / _iGrid - yOrigin); if (fWait) { try { Thread.sleep(50); } catch (Exception e) { } } } public void componentResized(ComponentEvent ce) { Component anptf[] = getComponents(); for (int iIndex = 0; iIndex < anptf.length; iIndex++) { NumberplaceTextField nptf = (NumberplaceTextField)anptf[iIndex]; int xGrid = nptf.x(), yGrid = nptf.y(); Dimension dimWindow = getSize(); int cxWindow = dimWindow.width, cyWindow = dimWindow.height; int xOrigin = xGrid * cxWindow / _iGrid, yOrigin = yGrid * cyWindow / _iGrid; nptf.setBounds(xOrigin, yOrigin, (xGrid + 1) * cxWindow / _iGrid - xOrigin, (yGrid + 1) * cyWindow / _iGrid - yOrigin); } } public void componentMoved(ComponentEvent ce) { } public void componentShown(ComponentEvent ce) { } public void componentHidden(ComponentEvent ce) { } } final class NumberplaceFrame extends Frame implements Runnable, ActionListener, WindowListener, ItemListener { int _iGrid; Numberplace _np; int _iAllPossible, _aiNumbers[][][][], _aiSavedNumbers[][][][], _afPossible[][][][]; NumberplaceMatrix _anpmWindows[][]; int _iUnknown; boolean _fDiagonal = false, _fWait = false; Thread _thread = null; final static String _strGo = "Go", _strClear = "Clear", _strTest = "Test", _strSave = "Save", _strLoad = "Load", _strDiagonal = "Diagonal", _strWait = "Wait"; final static private int _aiTest[][][][] = { { { { 5, 8, 12, 0, 15 }, { 7, 0, 0, 23, 0 }, { 21, 0, 9, 0, 0 }, { 0, 6, 0, 0, 20 }, { 10, 0, 0, 18, 13 } }, { { 6, 10, 0, 0, 20 }, { 0, 0, 4, 15, 2 }, { 16, 17, 1, 0, 0 }, { 7, 0, 0, 0, 9 }, { 0, 0, 3, 25, 0 } }, { { 0, 21, 0, 14, 0 }, { 3, 5, 9, 12, 13 }, { 0, 0, 2, 0, 0 }, { 23, 1, 11, 25, 15 }, { 0, 17, 0, 20, 0 } }, { { 3, 0, 0, 2, 19 }, { 25, 21, 1, 0, 0 }, { 0, 0, 24, 13, 4 }, { 22, 0, 0, 0, 18 }, { 0, 11, 7, 0, 0 } }, { { 13, 0, 25, 1, 18 }, { 0, 20, 0, 0, 17 }, { 0, 0, 3, 0, 22 }, { 10, 0, 0, 5, 0 }, { 4, 8, 0, 0, 24 } }, }, { { { 4, 0, 25, 7, 0 }, { 3, 0, 11, 0, 0 }, { 0, 20, 1, 0, 5 }, { 0, 24, 0, 0, 22 }, { 23, 12, 0, 16, 0 } }, { { 0, 20, 15, 0, 0 }, { 23, 2, 0, 0, 24 }, { 12, 0, 0, 13, 0 }, { 0, 0, 8, 0, 0 }, { 0, 14, 0, 0, 22 } }, { { 18, 23, 10, 16, 12 }, { 0, 0, 13, 0, 0 }, { 0, 3, 22, 21, 0 }, { 1, 0, 0, 0, 11 }, { 0, 0, 15, 17, 0 } }, { { 0, 0, 6, 19, 0 }, { 7, 0, 0, 25, 8 }, { 0, 24, 0, 0, 2 }, { 0, 0, 18, 0, 0 }, { 13, 0, 0, 20, 0 } }, { { 0, 17, 2, 0, 9 }, { 0, 0, 22, 0, 20 }, { 16, 0, 11, 6, 0 }, { 23, 0, 0, 12, 0 }, { 0, 25, 0, 18, 4 } }, }, { { { 0, 15, 0, 1, 0 }, { 9, 10, 0, 19, 23 }, { 0, 11, 3, 12, 0 }, { 14, 7, 0, 24, 21 }, { 0, 25, 0, 5, 0 } }, { { 17, 0, 0, 10, 0 }, { 24, 0, 16, 0, 1 }, { 22, 0, 13, 0, 25 }, { 8, 0, 20, 0, 0 }, { 4, 0, 0, 14, 0 } }, { { 0, 11, 0, 24, 0 }, { 21, 0, 0, 0, 2 }, { 0, 0, 7, 0, 0 }, { 17, 0, 0, 0, 3 }, { 0, 22, 0, 8, 0 } }, { { 0, 7, 0, 0, 14 }, { 0, 0, 3, 0, 15 }, { 24, 0, 20, 0, 16 }, { 1, 0, 5, 0, 13 }, { 0, 18, 0, 0, 12 } }, { { 0, 2, 0, 16, 0 }, { 5, 6, 0, 22, 25 }, { 0, 21, 15, 23, 0 }, { 9, 18, 0, 4, 12 }, { 0, 11, 0, 17, 0 } }, }, { { { 8, 23, 0, 21, 0 }, { 0, 3, 0, 0, 12 }, { 0, 14, 16, 0, 10 }, { 20, 0, 17, 0, 0 }, { 11, 0, 18, 25, 0 } }, { { 0, 16, 0, 0, 19 }, { 0, 0, 24, 0, 0 }, { 1, 0, 0, 3, 0 }, { 2, 8, 0, 0, 13 }, { 0, 4, 14, 0, 0 } }, { { 0, 14, 5, 0, 0 }, { 22, 0, 0, 0, 16 }, { 0, 4, 12, 19, 0 }, { 0, 0, 18, 0, 0 }, { 8, 24, 23, 1, 6 } }, { { 10, 0, 0, 11, 0 }, { 0, 0, 2, 0, 0 }, { 0, 13, 0, 0, 25 }, { 15, 0, 0, 24, 21 }, { 0, 0, 12, 7, 0 } }, { { 0, 3, 0, 2, 1 }, { 25, 0, 0, 19, 0 }, { 22, 0, 9, 20, 0 }, { 0, 0, 12, 0, 6 }, { 0, 10, 16, 0, 5 } }, }, { { { 15, 0, 0, 4, 7 }, { 0, 21, 0, 0, 2 }, { 12, 0, 24, 0, 0 }, { 25, 0, 0, 11, 0 }, { 1, 18, 19, 0, 17 } }, { { 0, 0, 9, 20, 0 }, { 25, 0, 0, 0, 12 }, { 3, 15, 11, 0, 0 }, { 0, 0, 10, 17, 4 }, { 14, 22, 0, 0, 5 } }, { { 0, 25, 0, 5, 0 }, { 4, 6, 14, 7, 17 }, { 0, 0, 21, 0, 0 }, { 15, 13, 8, 2, 23 }, { 0, 10, 0, 9, 0 } }, { { 0, 10, 17, 0, 0 }, { 20, 0, 0, 0, 22 }, { 0, 0, 19, 1, 23 }, { 12, 6, 9, 0, 0 }, { 8, 0, 0, 16, 11 } }, { { 14, 12, 0, 0, 8 }, { 19, 0, 0, 15, 0 }, { 0, 0, 17, 0, 10 }, { 0, 22, 0, 0, 16 }, { 7, 0, 4, 21, 13 } } } }; NumberplaceFrame(Numberplace np, int iGrid) { super((new StringBuffer("Numberplace - ")) .append(iGrid).append('x').append(iGrid).append('x') .append(iGrid).append('x').append(iGrid).toString()); // set variables _iGrid = iGrid; _np = np; _iAllPossible = ((1 << (iGrid * iGrid + 1)) - 1) & ~1; _aiNumbers = new int[iGrid][iGrid][iGrid][iGrid]; _aiSavedNumbers = new int[iGrid][iGrid][iGrid][iGrid]; resetAll(); saveNumbers(); _afPossible = new int[iGrid][iGrid][iGrid][iGrid]; _anpmWindows = new NumberplaceMatrix[iGrid][iGrid]; // set layout setLayout(new BorderLayout()); Color color = new Color(0xc0, 0xd4, 0xd0); setBackground(color); Panel panel = new Panel(); panel.setBackground(color); panel.setLayout(new GridLayout(2, 4)); addButton(panel, _strGo); addButton(panel, _strClear); addButton(panel, _strSave); addButton(panel, _strLoad); addButton(panel, _strTest); Checkbox cb = new Checkbox(_strDiagonal, false); panel.add(cb); cb.addItemListener(this); cb = new Checkbox(_strWait, false); panel.add(cb); cb.addItemListener(this); add("North", panel); panel = new Panel(); panel.setLayout(new GridLayout(iGrid, iGrid, 2, 2)); GridLayout grid = new GridLayout(iGrid, iGrid); for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { panel.add(_anpmWindows[yMatrix][xMatrix] = new NumberplaceMatrix(this, _aiNumbers[yMatrix][xMatrix], xMatrix, yMatrix)); } } add("Center", panel); addWindowListener(this); validateTree(); pack(); setVisible(true); } final public Dimension getPreferredSize() { int iSize = Math.min(Math.max(_iGrid * _iGrid * 30, 200), 600); return new Dimension(iSize, iSize + 40); } final void addButton(Panel panel, String strButton) { Button button; panel.add(button = new Button(strButton)); button.addActionListener(this); } final public void windowClosing(WindowEvent we) { terminate(); } final public void windowOpened(WindowEvent we) { } final public void windowClosed(WindowEvent we) { } final public void windowIconified(WindowEvent we) { } final public void windowDeiconified(WindowEvent we) { } final public void windowActivated(WindowEvent we) { } final public void windowDeactivated(WindowEvent we) { } final public void itemStateChanged(ItemEvent ie) { boolean fNew = (ie.getStateChange() == ItemEvent.SELECTED); if (ie.getItem().equals(_strDiagonal)) { _fDiagonal = fNew; } else { _fWait = fNew; } } final public void terminate() { if (_thread != null && _thread.isAlive()) { _thread.stop(); } _thread = null; _np.removeFrame(this); dispose(); } final static int countbits(int i) { // count the number of bits in a 32-bit integer i -= (i >>> 1) & 0x55555555; int i2 = i & 0x33333333; i = ((i ^ i2) >>> 2) + i2; i = (i + (i >>> 4)) & 0x0f0f0f0f; i += i >>> 8; return (i + (i >>> 16)) & 0xff; } final static boolean zeroOrOneBit(int i) { return (i & (i - 1)) == 0; } final boolean clearFlags(int yMatrix, int xMatrix, int y, int x, int iMask) { int iGrid = _iGrid; for (int xMatrix2 = 0; xMatrix2 < iGrid; xMatrix2++) { for (int x2 = 0; x2 < iGrid; x2++) { if (xMatrix2 == xMatrix && x2 == x) continue; int iFlag = _afPossible[yMatrix][xMatrix2][y][x2], iNewFlag = iFlag & iMask; if (iFlag != iNewFlag) { _afPossible[yMatrix][xMatrix2][y][x2] = iNewFlag; if (zeroOrOneBit(iNewFlag)) { if (iNewFlag == 0) { return false; } else if (!zeroOrOneBit(iFlag)) { int iNumber = countbits(iNewFlag - 1); _aiNumbers[yMatrix][xMatrix2][y][x2] = iNumber; _anpmWindows[yMatrix][xMatrix2].refresh(x2, y, _fWait); _iUnknown--; if (!clearFlags(yMatrix, xMatrix2, y, x2, ~iNewFlag)) { return false; } } } } } } for (int yMatrix2 = 0; yMatrix2 < iGrid; yMatrix2++) { for (int y2 = 0; y2 < iGrid; y2++) { if (yMatrix2 == yMatrix && y2 == y) continue; int iFlag = _afPossible[yMatrix2][xMatrix][y2][x], iNewFlag = iFlag & iMask; if (iFlag != iNewFlag) { _afPossible[yMatrix2][xMatrix][y2][x] = iNewFlag; if (zeroOrOneBit(iNewFlag)) { if (iNewFlag == 0) { return false; } else if (!zeroOrOneBit(iFlag)) { int iNumber = countbits(iNewFlag - 1); _aiNumbers[yMatrix2][xMatrix][y2][x] = iNumber; _anpmWindows[yMatrix2][xMatrix].refresh(x, y2, _fWait); _iUnknown--; if (!clearFlags(yMatrix2, xMatrix, y2, x, ~iNewFlag)) { return false; } } } } } } for (int y2 = 0; y2 < iGrid; y2++) { for (int x2 = 0; x2 < iGrid; x2++) { if (x2 == x && y2 == y) continue; int iFlag = _afPossible[yMatrix][xMatrix][y2][x2], iNewFlag = iFlag & iMask; if (iFlag != iNewFlag) { _afPossible[yMatrix][xMatrix][y2][x2] = iNewFlag; if (zeroOrOneBit(iNewFlag)) { if (iNewFlag == 0) { return false; } else if (!zeroOrOneBit(iFlag)) { int iNumber = countbits(iNewFlag - 1); _aiNumbers[yMatrix][xMatrix][y2][x2] = iNumber; _anpmWindows[yMatrix][xMatrix].refresh(x2, y2, _fWait); _iUnknown--; if (!clearFlags(yMatrix, xMatrix, y2, x2, ~iNewFlag)) { return false; } } } } } } if (_fDiagonal) { int iDiagonal = 0; if (xMatrix == yMatrix && x == y) { iDiagonal = 1; } if (xMatrix == iGrid - 1 - yMatrix && x == iGrid - 1 - y) { iDiagonal |= 2; } for (int iCheck = 1; iCheck <= 2; iCheck++) { if ((iDiagonal & iCheck) != 0) { for (int iIndex = 0; iIndex < iGrid * iGrid; iIndex++) { int xMatrix2 = iIndex / iGrid, x2 = iIndex % iGrid, yMatrix2, y2; if (iCheck == 1) { yMatrix2 = xMatrix2; y2 = x2; } else { yMatrix2 = iGrid - 1 - xMatrix2; y2 = iGrid - 1 - x2; } if (xMatrix2 == xMatrix && x2 == x && yMatrix2 == yMatrix && y2 == y) { continue; } int iFlag = _afPossible[yMatrix2][xMatrix2][y2][x2], iNewFlag = iFlag & iMask; if (iFlag != iNewFlag) { _afPossible[yMatrix2][xMatrix2][y2][x2] = iNewFlag; if (zeroOrOneBit(iNewFlag)) { if (iNewFlag == 0) { return false; } else if (!zeroOrOneBit(iFlag)) { int iNumber = countbits(iNewFlag - 1); _aiNumbers[yMatrix2][xMatrix2][y2][x2] = iNumber; _anpmWindows[yMatrix2][xMatrix2].refresh(x2, y2, _fWait); _iUnknown--; if (!clearFlags(yMatrix2, xMatrix2, y2, x2, ~iNewFlag)) { return false; } } } } } } } } return true; } final boolean clearAllFlags() { int iGrid = _iGrid; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { int iFlag = _afPossible[yMatrix][xMatrix][y][x]; if (zeroOrOneBit(iFlag)) { if (!clearFlags(yMatrix, xMatrix, y, x, ~iFlag)) { return false; } } } } } } return true; } final boolean checkAllFlags() { int iGrid = _iGrid; int aiNumberBits[] = new int[iGrid * iGrid + 1]; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int y = 0; y < iGrid; y++) { for (int iIndex = 0; iIndex < aiNumberBits.length; iIndex++) { aiNumberBits[iIndex] = 0; } int iIndex = 0; for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int x = 0; x < iGrid; x++) { int iFlag = _afPossible[yMatrix][xMatrix][y][x]; for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { if ((iFlag & (1 << iNumber)) != 0) { aiNumberBits[iNumber] |= (1 << iIndex); } } iIndex++; } } for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { iIndex = aiNumberBits[iNumber]; if (zeroOrOneBit(iIndex)) { if (iIndex == 0) { return false; } iIndex = countbits(iIndex - 1); int xMatrix = iIndex / iGrid, x = iIndex % iGrid; if (_aiNumbers[yMatrix][xMatrix][y][x] != iNumber) { _aiNumbers[yMatrix][xMatrix][y][x] = iNumber; _anpmWindows[yMatrix][xMatrix].refresh(x, y, _fWait); _iUnknown--; int iFlag = 1 << iNumber; _afPossible[yMatrix][xMatrix][y][x] = iFlag; if (!clearFlags(yMatrix, xMatrix, y, x, ~iFlag)) { return false; } } } } } } for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int x = 0; x < iGrid; x++) { for (int iIndex = 0; iIndex < aiNumberBits.length; iIndex++) { aiNumberBits[iIndex] = 0; } int iIndex = 0; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int y = 0; y < iGrid; y++) { int iFlag = _afPossible[yMatrix][xMatrix][y][x]; for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { if ((iFlag & (1 << iNumber)) != 0) { aiNumberBits[iNumber] |= (1 << iIndex); } } iIndex++; } } for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { iIndex = aiNumberBits[iNumber]; if (zeroOrOneBit(iIndex)) { if (iIndex == 0) { return false; } iIndex = countbits(iIndex - 1); int yMatrix = iIndex / iGrid, y = iIndex % iGrid; if (_aiNumbers[yMatrix][xMatrix][y][x] != iNumber) { _aiNumbers[yMatrix][xMatrix][y][x] = iNumber; _anpmWindows[yMatrix][xMatrix].refresh(x, y, _fWait); _iUnknown--; int iFlag = 1 << iNumber; _afPossible[yMatrix][xMatrix][y][x] = iFlag; if (!clearFlags(yMatrix, xMatrix, y, x, ~iFlag)) { return false; } } } } } } for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int iIndex = 0; iIndex < aiNumberBits.length; iIndex++) { aiNumberBits[iIndex] = 0; } int iIndex = 0; for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { int iFlag = _afPossible[yMatrix][xMatrix][y][x]; for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { if ((iFlag & (1 << iNumber)) != 0) { aiNumberBits[iNumber] |= (1 << iIndex); } } iIndex++; } } for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { iIndex = aiNumberBits[iNumber]; if (zeroOrOneBit(iIndex)) { if (iIndex == 0) { return false; } iIndex = countbits(iIndex - 1); int y = iIndex / iGrid, x = iIndex % iGrid; if (_aiNumbers[yMatrix][xMatrix][y][x] != iNumber) { _aiNumbers[yMatrix][xMatrix][y][x] = iNumber; _anpmWindows[yMatrix][xMatrix].refresh(x, y, _fWait); _iUnknown--; int iFlag = 1 << iNumber; _afPossible[yMatrix][xMatrix][y][x] = iFlag; if (!clearFlags(yMatrix, xMatrix, y, x, ~iFlag)) { return false; } } } } } } if (_fDiagonal) { for (int iDiagonal = 0; iDiagonal <= 1; iDiagonal++) { for (int iIndex = 0; iIndex < aiNumberBits.length; iIndex++) { aiNumberBits[iIndex] = 0; } for (int iIndex = 0; iIndex < iGrid * iGrid; iIndex++) { int xMatrix = iIndex / iGrid, xIndex = iIndex % iGrid; int iFlag = _afPossible[iDiagonal == 0 ? xMatrix : (iGrid - 1 - xMatrix)] [xMatrix] [iDiagonal == 0 ? xIndex : (iGrid - 1 - xIndex)] [xIndex]; for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { if ((iFlag & (1 << iNumber)) != 0) { aiNumberBits[iNumber] |= (1 << iIndex); } } } for (int iNumber = 1; iNumber <= iGrid * iGrid; iNumber++) { int iIndex = aiNumberBits[iNumber]; if (zeroOrOneBit(iIndex)) { if (iIndex == 0) { return false; } iIndex = countbits(iIndex - 1); int xMatrix = iIndex / iGrid, xIndex = iIndex % iGrid, yMatrix, yIndex; if (iDiagonal == 0) { yMatrix = xMatrix; yIndex = xIndex; } else { yMatrix = iGrid - 1 - xMatrix; yIndex = iGrid - 1 - xIndex; } if (_aiNumbers[yMatrix][xMatrix][yIndex][xIndex] != iNumber) { _aiNumbers[yMatrix][xMatrix][yIndex][xIndex] = iNumber; _anpmWindows[yMatrix][xMatrix].refresh(xIndex, yIndex, _fWait); _iUnknown--; int iFlag = 1 << iNumber; _afPossible[yMatrix][xMatrix][yIndex][xIndex] = iFlag; if (!clearFlags(yMatrix, xMatrix, yIndex, xIndex, ~iFlag)) { return false; } } } } } } return true; } final private void repaintAll() { int iGrid = _iGrid; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { _anpmWindows[yMatrix][xMatrix].repaint(); } } } final private void resetAll() { int iGrid = _iGrid; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { _aiNumbers[yMatrix][xMatrix][y][x] = 0; } } } } } final private void saveNumbers() { int iGrid = _iGrid; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { _aiSavedNumbers[yMatrix][xMatrix][y][x] = _aiNumbers[yMatrix][xMatrix][y][x]; } } } } } final private void loadNumbers() { int iGrid = _iGrid; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { _aiNumbers[yMatrix][xMatrix][y][x] = _aiSavedNumbers[yMatrix][xMatrix][y][x]; } } } } } final public void run() { int iGrid = _iGrid; _iUnknown = 0; for (int yMatrix = 0; yMatrix < iGrid; yMatrix++) { for (int xMatrix = 0; xMatrix < iGrid; xMatrix++) { for (int y = 0; y < iGrid; y++) { for (int x = 0; x < iGrid; x++) { int iNumber = _aiNumbers[yMatrix][xMatrix][y][x]; if (iNumber != 0) { _afPossible[yMatrix][xMatrix][y][x] = 1 << iNumber; } else { _afPossible[yMatrix][xMatrix][y][x] = _iAllPossible; _iUnknown++; } } } } } int iUnknownPrev; do { iUnknownPrev = _iUnknown; if (!clearAllFlags() || !checkAllFlags()) { break; } } while (_iUnknown > 0 && iUnknownPrev != _iUnknown); _thread = null; } final public void nextField(int xMatrix, int yMatrix) { if ((xMatrix = xMatrix + 1) == _iGrid) { xMatrix = 0; if ((yMatrix = yMatrix + 1) == _iGrid) { yMatrix = 0; } } _anpmWindows[yMatrix][xMatrix].openField(0, 0); } final public void actionPerformed(ActionEvent ae) { String str = ae.getActionCommand(); if (_thread != null) { return; } if (str.equals(_strGo)) { (_thread = new Thread(this)).start(); } else if (str.equals(_strClear)) { resetAll(); repaintAll(); } else if (str.equals(_strSave)) { saveNumbers(); repaintAll(); } else if (str.equals(_strLoad)) { loadNumbers(); repaintAll(); } else if (str.equals(_strTest) && _iGrid == 5) { for (int yMatrix = 0; yMatrix < 5; yMatrix++) { for (int xMatrix = 0; xMatrix < 5; xMatrix++) { for (int y = 0; y < 5; y++) { for (int x = 0; x < 5; x++) { _aiNumbers[yMatrix][xMatrix][y][x] = _aiTest[yMatrix][xMatrix][y][x]; } } } } repaintAll(); } } } final public class Numberplace extends Applet implements ActionListener { Vector _vecFrames = new Vector(); Choice _choice; final public void init() { setLayout(new GridLayout(1, 3)); setBackground(new Color(0xc0, 0xd4, 0xd0)); add(new Label("Dimension:", Label.RIGHT)); Choice choice; _choice = choice = new Choice(); choice.addItem("2"); choice.addItem("3"); choice.addItem("4"); choice.addItem("5"); choice.select(1); add(choice); Button button; add(button = new Button("Open")); button.addActionListener(this); } final public void removeFrame(NumberplaceFrame frame) { _vecFrames.removeElement(frame); } final public void stop() { while (!_vecFrames.isEmpty()) { ((NumberplaceFrame)_vecFrames.firstElement()).terminate(); } } final public void actionPerformed(ActionEvent ae) { try { int iGrid = Integer.parseInt(_choice.getSelectedItem()); _vecFrames.addElement(new NumberplaceFrame(this, iGrid)); } catch (Exception e) { } } }