Last active
May 21, 2020 02:16
-
-
Save feehe21/e3bf415411db6c5d3d554b6fca4467d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Color; | |
import javax.swing.JFrame; | |
import javax.swing.JPanel; | |
import javax.swing.WindowConstants; | |
import java.awt.Dimension; | |
import java.awt.Graphics; | |
import java.awt.Graphics2D; | |
import java.awt.Point; | |
import java.awt.event.MouseListener; | |
import java.awt.event.MouseEvent; | |
import java.awt.event.KeyAdapter; | |
import java.awt.event.KeyEvent; | |
import java.util.*; | |
import java.io.*; | |
import java.awt.Font; | |
public class GUI { | |
private JFrame frame; | |
static SudokuBoard board; | |
static int move; | |
public GUI() { | |
int[] a = {5,3,0,0,7,0,0,0,0, | |
6,0,0,1,9,5,0,0,0, | |
0,9,8,0,0,0,0,6,0, | |
8,0,0,0,6,0,0,0,3, | |
4,0,0,8,0,3,0,0,1, | |
7,0,0,0,2,0,0,0,6, | |
0,6,0,0,0,0,2,8,0, | |
0,0,0,4,1,9,0,0,5, | |
0,0,0,0,8,0,0,7,9}; | |
board = new SudokuBoard(a); | |
move = 0; | |
frame = new JFrame("Bubbles Program"); | |
frame.setSize(800, 800); | |
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | |
frame.setPreferredSize(frame.getSize()); | |
frame.add(new InnerProgram(frame.getSize())); | |
frame.pack(); | |
frame.setVisible(true); | |
} | |
public static void main(String... argv) { | |
new GUI(); | |
} | |
public static class InnerProgram extends JPanel implements Runnable, MouseListener { | |
ArrayList<String> names = new ArrayList<String>(); | |
private Thread animator; | |
Dimension d; | |
String str = ""; | |
public InnerProgram (Dimension dimension) { | |
setSize(dimension); | |
setPreferredSize(dimension); | |
addMouseListener(this); | |
addKeyListener(new TAdapter()); | |
setFocusable(true); | |
d = getSize(); | |
//for animating the screen - you won't need to edit | |
if (animator == null) { | |
animator = new Thread(this); | |
animator.start(); | |
} | |
setDoubleBuffered(true); | |
} | |
@Override | |
public void paintComponent(Graphics g) { | |
Graphics2D g2 = (Graphics2D)g; | |
g2.setColor(Color.black); | |
g2.fillRect(0, 0,(int)d.getWidth() , (int)d.getHeight()); | |
Color w = new Color(255,255,255); | |
g2.setColor(w); | |
int fontSize = 10; | |
g2.setFont(new Font("TimesRoman", Font.PLAIN, fontSize)); | |
g2.drawString("String " + str,20,40); | |
g2.setFont(new Font("TimesRoman", Font.PLAIN, 20)); | |
g2.drawString("Value: " + move,100,40); | |
int s = 75; | |
Color gr = new Color(60,60,60); | |
g2.setColor(gr); | |
g2.fillRect(50 + (s*3), 50, s*3, s*3); | |
g2.fillRect(50, 50 + (s*3), s*3, s*3); | |
g2.fillRect(50 + (s*6), 50 + (s*3), s*3, s*3); | |
g2.fillRect(50 + (s*3), 50 + (s*6), s*3, s*3); | |
g2.setFont(new Font("TimesRoman", Font.PLAIN, 100)); | |
g2.setColor(w); | |
Color b = new Color(52, 177, 235); | |
int value; | |
for(int i = 0; i < 9; i++){ | |
for(int j = 0; j < 9; j++){ | |
g2.drawRect(50+(j*s), 50+(i*s), s, s); | |
value = board.board[i][j].value; | |
if(value != 0){ | |
if(value == move){ | |
g2.setColor(b); | |
} | |
g2.drawString("" + value, 50+(j*s)+10, 50+((i+1)*s)-5); | |
g2.setColor(w); | |
} | |
} | |
} | |
} | |
public int random (int a, int b){ | |
int max=a; | |
int min=b; | |
int random=(int)(Math.random() * (max - min) + min); | |
return random; | |
} | |
public void mousePressed(MouseEvent e) { | |
int x = e.getX(); | |
int y = e.getY(); | |
int bX = (x-50)/75; | |
int bY = (y-50)/75; | |
str = x + " " + y + " " + bX + " " + bY; | |
if(x > 50 && y > 50 && bX < 9 && bY < 9){ | |
if(board.board[bY][bX].given){ | |
move = board.board[bY][bX].value; | |
}else{ | |
board.move(bX,bY,move); | |
} | |
} | |
} | |
public void mouseReleased(MouseEvent e) { | |
} | |
public void mouseEntered(MouseEvent e) { | |
} | |
public void mouseExited(MouseEvent e) { | |
} | |
public void mouseClicked(MouseEvent e) { | |
} | |
private class TAdapter extends KeyAdapter { | |
public void keyReleased(KeyEvent e) { | |
int keyr = e.getKeyCode(); | |
} | |
public void keyPressed(KeyEvent e) { | |
int key = e.getKeyCode(); | |
// String c = KeyEvent.getKeyText(e.getKeyCode()); | |
// c = Character.toString((char) key); | |
if((char)key == '1' || (char)key == '2' || (char)key == '3' || (char)key == '4' || (char)key == '5' || (char)key == '6' || (char)key == '7' || (char)key == '8' || (char)key == '9'){ | |
move = key - ((int)'0'); | |
}else{ | |
board.backtracking(); | |
} | |
} | |
}//end of adapter | |
public void run() { | |
long beforeTime, timeDiff, sleep; | |
beforeTime = System.currentTimeMillis(); | |
int animationDelay = 37; | |
long time = System.currentTimeMillis(); | |
while (true) {// infinite loop | |
// spriteManager.update(); | |
repaint(); | |
try { | |
time += animationDelay; | |
Thread.sleep(Math.max(0, time - System.currentTimeMillis())); | |
} catch (InterruptedException e) { | |
System.out.println(e); | |
} // end catch | |
} // end while loop | |
}// end of run | |
}//end of class | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PathNode | |
{ | |
int x; | |
int y; | |
PathNode next; | |
PathNode(int xV, int yV){ | |
x = xV; | |
y = yV; | |
next = null; | |
} | |
public PathNode getNext() { | |
return next; | |
} | |
public void setNext(PathNode nextValue) { | |
next = nextValue; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Stack<V> { | |
int nItems; | |
PathNode head; | |
public Stack(){ | |
head = null; | |
nItems = 0; | |
} | |
public Stack(PathNode h){ | |
head = h; | |
nItems = 1; | |
} | |
public void push(int x, int y) {//add to front | |
PathNode new_node = new PathNode(x,y); | |
if(head!=null){ | |
PathNode pastHead = head; | |
new_node.next=pastHead; | |
head=new_node; | |
}else{ | |
head=new_node; | |
} | |
nItems++; | |
}// add to front | |
public PathNode pop() {//remove from front | |
PathNode hold = null; | |
if(head!=null){ | |
hold = head; | |
if(head.next!=null){ | |
head=head.next; | |
}else{ | |
head=null; | |
} | |
nItems--; | |
} | |
return hold; | |
}//remove from front | |
public PathNode get(int index) { | |
int count = 0; | |
boolean go = true; | |
if(head!=null){ | |
PathNode last = head; | |
for(int i =0; i<=index; i++){ | |
if(i==index){ | |
return last; | |
} | |
if(last.next==null){ | |
return null; | |
} | |
last=last.next; | |
} | |
} | |
return null; | |
} | |
public boolean isEmpty() { | |
return (size()==0); | |
} | |
public int size() { | |
if (head == null) { | |
return 0; | |
} | |
PathNode last = head; | |
int count = 1; | |
while (last.next != null) { | |
last = last.next; | |
count++; | |
} | |
return count; | |
} | |
public void print(){ | |
if(head!=null){ | |
PathNode last = head; | |
System.out.println("List: "); | |
while (last.next != null) { | |
System.out.print(last.x+"," + last.y + " "); | |
last = last.next; | |
} | |
System.out.println(last.x+"," + last.y); | |
}else{ | |
System.out.println("List empty"); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Classic 9x9 sudoku board | |
import java.util.*; | |
public class SudokuBoard | |
{ | |
Tile[][] board; | |
public SudokuBoard(int[] given) | |
{ | |
board = new Tile[9][9]; | |
if(given.length != 81){ | |
System.out.println("This is not a valid 9x9 board"); | |
return; | |
} | |
//sets board -> 0=empty spot | |
int arrayTracker = 0; | |
for(int y = 0; y < 9; y++){ | |
for(int x = 0; x < 9; x++){ | |
if(given[arrayTracker] == 0){ | |
board[y][x] = new Tile(0, false); | |
}else{ | |
board[y][x] = new Tile(given[arrayTracker], true); | |
} | |
arrayTracker++; | |
} | |
} | |
} | |
public boolean move(int x, int y, int value){ | |
if(board[y][x].given){ | |
return false; | |
} | |
if(board[y][x].value == value){ | |
board[y][x].value = 0; | |
return true; | |
} | |
board[y][x].value = value; | |
if(validPlacement(x,y)){ | |
return true; | |
} | |
return false; | |
} | |
public boolean isSolved(){//checks if board is completely done and has no errors | |
//checks rows | |
for(int y = 0; y < 9; y++){ | |
if(!solvedNine(board[y])){ | |
return false; | |
} | |
} | |
//checks columns | |
Tile[]hold = new Tile[9]; | |
for(int j = 0; j < 9; j++){//x value of column | |
for(int i = 0; i < 9; i++){//forms array of column | |
hold[i] = board[i][j]; | |
} | |
if(!solvedNine(hold)){ | |
return false; | |
} | |
} | |
//checks regions | |
int spot; | |
for(int y = 0; y < 3; y++){//through y of 9 sub-blocks | |
for(int x = 0; x < 3; x++){//through x of 9 sub-blocks | |
spot = 0; | |
for(int subY = 0; subY < 3; subY++){//through y within sub-block | |
for(int subX = 0; subX < 3; subX++){//through x within sub-block | |
hold[spot] = board[y*3+subY][x*3+subX]; | |
spot++; | |
} | |
} | |
if(!solvedNine(hold)){ | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
private boolean solvedNine(Tile[] a){//checks if the inputed 9 tiles could make a completely solved row | |
int numbers = 0b111111111; | |
for(int i = 0; i < a.length; i++){ | |
int checkVal = a[i].value; | |
if (checkVal == 0)//empty | |
return false; | |
int mask = (1 << (checkVal - 1)); | |
if ((numbers & mask) == 0)//duplicate | |
return false; | |
//remove number from list | |
numbers &= ~mask; | |
} | |
return true; | |
} | |
private boolean validPlacement(int x, int y){//checks if the tile added to (x,y) can be placed without error | |
//checks row | |
if(!validNine(board[y])){ | |
return false; | |
} | |
//checks column | |
Tile[]hold = new Tile[9]; | |
for(int i = 0; i < 9; i++){//forms array of column | |
hold[i] = board[i][x]; | |
} | |
if(!validNine(hold)){ | |
return false; | |
} | |
//checks block | |
int spot = 0; | |
for(int subY = 0; subY < 3; subY++){//through y within sub-block | |
for(int subX = 0; subX < 3; subX++){//through x within sub-block | |
hold[spot] = board[(y/3)*3+subY][(x/3)*3+subX]; | |
spot++; | |
} | |
} | |
if(!validNine(hold)){ | |
return false; | |
} | |
return true; | |
} | |
private boolean validNine(Tile[] a){//checks if there are no errors in row, but allows for empty spaces | |
int numbers = 0b111111111; | |
for(int i = 0; i < a.length; i++){ | |
int checkVal = a[i].value; | |
if (checkVal == 0)//empty | |
continue; | |
int mask = (1 << (checkVal - 1)); | |
if ((numbers & mask) == 0)//duplicate | |
return false; | |
//remove number from list | |
numbers &= ~mask; | |
} | |
return true; | |
} | |
private int[] firstEmpty(){//find value of the first empty space in board; returns array {x,y}; checks row-first | |
//make more efficient by a starting point - know there are no empties before the focus point | |
int[] arr = {-1,-1}; | |
for(int y = 0; y < 9; y++){ | |
for(int x = 0; x < 9; x++){ | |
if(board[y][x].value == 0){ | |
arr[0] = x; | |
arr[1] = y; | |
return arr; | |
} | |
} | |
} | |
return arr; | |
} | |
public void backtracking(){ | |
int[] arr = firstEmpty(); | |
int focusX = arr[0]; | |
int focusY = arr[1]; | |
int limit = 0; | |
boolean solved = false; | |
int firstEmptyX = focusX; | |
int firstEmptyY = focusY; | |
Stack path = new Stack();//stack of coordinates of completed moves | |
if(focusX == -1){ | |
System.out.println("No empties"); | |
return; | |
} | |
while(limit < 500 && !solved){ | |
if(board[focusY][focusX].value == 9){ | |
board[focusY][focusX].value = 0; | |
if(focusX == firstEmptyX && focusY == firstEmptyY){ | |
System.out.println("no solutions"); | |
limit = 500; | |
}else{ | |
PathNode previous = path.pop(); | |
if(previous != null){//backtracks to previous move | |
focusX = previous.x; | |
focusY = previous.y; | |
}else{ | |
System.out.println("hmm"); | |
} | |
} | |
}else{ | |
board[focusY][focusX].value++; | |
if(validPlacement(focusX, focusY)){ | |
path.push(focusX, focusY); | |
arr = firstEmpty(); | |
focusX = arr[0]; | |
focusY = arr[1]; | |
if(focusX == -1){//no more empty spots | |
System.out.println("leaving"); | |
solved = true; | |
} | |
} | |
} | |
} | |
System.out.println("out"); | |
//print board here? | |
if(isSolved()){ | |
System.out.println("solved"); | |
} | |
limit++; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Represents one spot in the sudoku board | |
public class Tile | |
{ | |
int x; | |
int y; | |
int value;//the value of the tile | |
boolean given;//whether the value is given as a clue or is guessed | |
public Tile(int num, boolean notAGuess) | |
{ | |
value = num; | |
given = notAGuess; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment