import java.util.ArrayList;
import java.util.Random;
import javax.swing.JOptionPane;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.awt.;
import java.awt.event.;
import java.util.Objects;
import javax.swing.*;
import java.awt.HeadlessException;
import javax.swing.border.Border;
public class Sudoku2D extends JFrame implements ActionListener {
Container container;
JPanel painel;
ActionEvent evento;
JMenuBar menu;
JMenu jogo, ajuda;
JMenuItem facil, medio, dificil, expert, resolver, limpar, sair, sobre;
Botao selecionado;
Botao bt;
boolean joga = true;
int preenchidos = 0;
static final String vazio = " ";
Random r = new Random();
Botao [][] botoes = new Botao [9][9];
String [][] array = new String [9][9];
ArrayList <String> jogos = new ArrayList <>();
public Sudoku2D() {
super("SUDOKU");
setLayout(new GridLayout(9, 9));
menu = new JMenuBar();
jogo = new JMenu("Jogo");
facil = new JMenuItem("Fácil");
facil.addActionListener(this);
jogo.add(facil);
jogo.addSeparator();
medio = new JMenuItem("Médio");
medio.addActionListener(this);
jogo.add(medio);
jogo.addSeparator();
dificil = new JMenuItem("Difícil");
dificil.addActionListener(this);
jogo.add(dificil);
jogo.addSeparator();
expert = new JMenuItem("Expert");
expert.addActionListener(this);
jogo.add(expert);
jogo.addSeparator();
resolver = new JMenuItem("Resolve Sudoku");
resolver.addActionListener(this);
jogo.add(resolver);
jogo.addSeparator();
limpar = new JMenuItem("Limpar");
limpar.addActionListener(this);
jogo.add(limpar);
jogo.addSeparator();
sair = new JMenuItem("Sair");
sair.addActionListener(this);
jogo.add(sair);
ajuda = new JMenu("Ajuda");
sobre = new JMenuItem("Sobre");
sobre.addActionListener(this);
ajuda.add(sobre);
menu.add(jogo);
menu.add(ajuda);
setJMenuBar(menu);
setVisible(true);
pack();
}
public void actionPerformed(ActionEvent evento) {
this.evento = evento;
if(evento.getSource() == facil) {
pegaJogo("facil.txt");
criaTabuleiro();
}
if(evento.getSource() == medio) {
pegaJogo("medio.txt");
criaTabuleiro();
}
if(evento.getSource() == dificil) {
pegaJogo("dificil.txt");
criaTabuleiro();
}
if(evento.getSource() == expert) {
pegaJogo("expert.txt");
criaTabuleiro();
}
if(evento.getSource() == resolver) {
resolveBT();
}
if(evento.getSource() == limpar) {
JOptionPane.showMessageDialog(null, "Opção indisponível...");
// limpa();
}
else if(evento.getSource() == sair) {
System.exit(0);
}
else if(evento.getSource() == sobre) {
JOptionPane.showMessageDialog(
null, "Autor: Ighor Santiago\n"
+ "\nSudoku, é um jogo baseado na colocação lógica de"
+ "\nnúmeros. O objetivo do jogo é a colocação de números de"
+ "\n1 a 9 em cada uma das células vazias numa grade de 9x9,"
+ "\nconstituída por 3x3 subgrades chamadas regiões."
+ "\nO quebra-cabeça contém algumas pistas iniciais, que são"
+ "\nnúmeros inseridos em algumas células, de maneira a permitir"
+ "\numa indução ou dedução dos números em células que estejam"
+ "\nvazias."
+ "\nCada linha, coluna e região só pode ter um número de cada"
+ "\num dos 1 a 9. Resolver o problema requer apenas raciocínio"
+ "\nlógico e algum tempo.");
}
}
public String [][] pegaJogo(String arquivo) {
try {
FileReader arq = new FileReader(arquivo);
BufferedReader lerArq = new BufferedReader(arq);
String linha = lerArq.readLine(); // lê a primeira linha
while (linha != null) {
jogos.add(linha);
linha = lerArq.readLine();
}
arq.close();
} catch (IOException e) {
System.err.printf("Erro na abertura do arquivo");
}
int posicao = r.nextInt(jogos.size());
String jogo = jogos.get(posicao);
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
int index = ((i * 9) + j);
String aux = String.valueOf(jogo.substring(index, (index + 1)));
if(aux.equals("0")) {
array[i][j] = vazio;
}
else {
array[i][j] = aux;
preenchidos++;
}
}
}
return array;
}
String[] imutaveis = new String[preenchidos];
private void criaTabuleiro() {
int i, j;
setSize(400, 400);
setLocationRelativeTo(null);
for(i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
botoes[i][j] = new Botao();
if(i < 3 || i > 5) {
if(j < 3 || j > 5) {
botoes[i][j].setBackground(Color.lightGray);
}
}
else if(i > 2 && i < 6) {
if(j > 2 && j < 6) {
botoes[i][j].setBackground(Color.lightGray);
}
}
else
botoes[i][j].setBackground(Color.white);
add(botoes[i][j]);
}
}
preencheTabuleiro();
initKeyListener();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void preencheTabuleiro() {
int x = 0, y = 0;
//preenche tabuleiro
for(int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
botoes[i][j].setText(array[i][j]);
botoes[i][j].setName("bt_" + x);
botoes[i][j].setToolTipText("bt_" + x);
botoes[i][j].setLinha(i);
botoes[i][j].setColuna(j);
botoes[i][j].setForeground(Color.blue);
//pega os números que começam no tabuleiro
if(!botoes[i][j].getText().equals(vazio)) {
botoes[i][j].setEditavel(false);
botoes[i][j].setForeground(Color.black);
}
x++;
}
}
}
public boolean testaNumero(KeyEvent e) {
int lin = selecionado.getLinha();
int col = selecionado.getColuna();
String numero = Objects.toString(e.getKeyChar());
joga = true;
if(joga) {
//checa linha
for (int i = 0; i < 9; i++) {
if(array[lin][i].equals(numero)) {
JOptionPane.showMessageDialog(null, "Essa linha já tem esse número...");
joga = false;
}
}
}
if(joga) {
//checa coluna
for (int j = 0; j < 9; j++) {
if (array[j][col].equals(numero)) {
JOptionPane.showMessageDialog(null, "Essa coluna já tem esse número...");
joga = false;
}
}
}
if(joga) {
//checa grade
int linhaCaixa = lin - (lin % 3);
int colunaCaixa = col - (col % 3);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (array[linhaCaixa + x][colunaCaixa + y].equals(numero)) {
JOptionPane.showMessageDialog(null, "Essa grade já tem esse número...");
joga = false;
}
}
}
}
return joga;
}
//verifica o clique do mouse e pega o valor digitado
private void initKeyListener() {
addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (selecionado != null) {
if(selecionado.getEditavel()) {
if(testaNumero(e)) {
selecionado.setText(Objects.toString(e.getKeyChar()));
}
}
else
JOptionPane.showMessageDialog(null, "Este número não pode ser alterado...");
}
}
});
}
class Botao extends JLabel {
int linha;
int coluna;
boolean editavel = true;
ArrayList <String> possibilidades = new ArrayList<>();
public Botao() {
super();
init();
}
public int getLinha() { return linha; }
public void setLinha(int l) { linha = l; }
public int getColuna() { return coluna; }
public void setColuna(int c) { coluna = c; }
public boolean getEditavel() { return editavel; }
public void setEditavel(boolean e) { editavel = e; }
public ArrayList getPossibilidades() { return possibilidades; }
public void setPossibilidades(String p) { possibilidades.add(p); }
public void zeraPossibilidades() { possibilidades.clear(); }
private void init() {
setBackground(Color.WHITE);
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setPreferredSize(new Dimension(30, 30));
setHorizontalAlignment(SwingConstants.CENTER);
setOpaque(true);
setText("");
setLinha(0);
setColuna(0);
possibilidades.clear();
Botao esteBotao = this;
addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
selecionaBotao(esteBotao);
}
});
}
}
void selecionaBotao(Botao botao) {
JLabel clique;
//se tem selecionado
if (selecionado != null) {
selecionado.setBorder(BorderFactory.createLineBorder(Color.black));
}
//seleciona o novo se não for nulo
if (botao != null) {
botao.setBorder(BorderFactory.createLineBorder(Color.red));
}
selecionado = botao;
}
public boolean checa(int lin, int col, int numero) {
//checa linha
for (int i = 0; i < 9; i++) {
if(botoes[lin][i].getText().equals(String.valueOf(numero))) {
return false;
}
}
//checa coluna
for (int j = 0; j < 9; j++) {
if (botoes[j][col].getText().equals(String.valueOf(numero))) {
return false;
}
}
//checa grade
int linhaCaixa = lin - (lin % 3);
int colunaCaixa = col - (col % 3);
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (botoes[linhaCaixa + x][colunaCaixa + y].getText().equals(String.valueOf(numero))) {
return false;
}
}
}
return true;
}
public void pegaPossibilidades() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
botoes[i][j].zeraPossibilidades();
if (botoes[i][j].getText().equals(vazio)) {
for (int k = 1; k <= 9; k++) {
if (checa(i, j, k)) {
botoes[i][j].setPossibilidades(String.valueOf(k));
}
}
}
}
}
}
public boolean resolveBT() {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
if(botoes[i][j].getText().equals(vazio)) {
for(int k = 1; k <= 9; k++) {
if(checa(i, j, k)) {
botoes[i][j].setText(String.valueOf(k));
if(resolveBT()) { return true; }
else botoes[i][j].setText(vazio);
}
}
return false;
}
}
}
return true;
}
/*
public void resolveSudoku() {
int zeros = 81, numero = 0;
int n = 0, lin = 0, col = 0;
String [][] copia = new String [9][9];
pegaPossibilidades();
//imprime números possíveis de cada espaço vazio
for(int g = 0; g < 9; g++) {
for(int h = 0; h < 9; h++) {
int index = ((g * 9) + h);
if(!botoes[g][h].possibilidades.isEmpty()) {
System.out.println(index + " - " + botoes[g][h].possibilidades);
}
}
}
//checa a quantidade de números que faltam
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
// copia[i][j] = botoes[i][j].getText();
if(!botoes[i][j].getText().equals(vazio)) {
zeros--;
}
}
}
int tentativas = 0;
while(tentativas < 50) {
//linha
for(int i = 0; i < 9; i++) {
//coluna
for(int j = 0; j < 9; j++) {
int possiveis = 0;
if(botoes[i][j].getText().equals(vazio)) {
//testa de 1 a 9
for(int k = 1; k <= 9; k++) {
if(checa(i, j, k)) {
numero = k;
possiveis++;
}
}
if(possiveis == 1) {
botoes[i][j].setText(String.valueOf(numero));
botoes[i][j].setForeground(Color.red);
botoes[i][j].setEditavel(false);
// copia[i][j] = String.valueOf(numero);
zeros–;
}
int linhaCaixa = i - (i % 3);
int colunaCaixa = j - (j % 3);
for(int k = 1; k <= 9; k++) {
int p = 0;
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
if (botoes[linhaCaixa + x][colunaCaixa + y].getText().equals(String.valueOf(vazio))) {
if (checa((linhaCaixa + x), (colunaCaixa + y), k)) {
lin = (linhaCaixa + x);
col = (colunaCaixa + y);
p++;
}
}
}
}
if(p == 1) {
botoes[lin][col].setText(String.valueOf(k));
botoes[lin][col].setForeground(Color.red);
botoes[lin][col].setEditavel(false);
}
}
}//if vazio
}//for j
}//for i
tentativas++;
}//while
if(!resolveBT()) { resolveBT(); }
}//resolve
*/
public void limpa() {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
botoes[i][j] = new Botao();
}
}
}
public static void main(String[] args) {
new Sudoku2D();
}
}
O jogo ficou assim…
Só não consegui gerar um novo jogo direto, tenho que fechar a janela e rodar o código de novo.
Se puderem me ajudar.
Fora isso, ta funcionando bem.
O método pra resolver o sudoku resolve todos os níveis bem rápido.