package nl.elridge.sudoku.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Observable;
/**
* This class represents a Sudoku game. It contains the solution, the user
* input, the selected number and methods to check the validation of the user
* input.
*
* @author Eric Beijer
*/
public class Game extends Observable {
private int[][] solution; // Generated solution.
private int[][] game; // Generated game with user input.
private boolean[][] check; // Holder for checking validity of game.
private int selectedNumber; // Selected number by user.
private boolean help; // Help turned on or off.
/**
* Constructor
*/
public Game() {
newGame();
check = new boolean[9][9];
help = true;
}
/**
* Generates a new Sudoku game.<br />
* All observers will be notified, update action: new game.
*/
public void newGame() {
solution = generateSolution(new int[9][9], 0);
game = generateGame(copy(solution));
setChanged();
notifyObservers(UpdateAction.NEW_GAME);
}
/**
* Checks user input agains the solution and puts it into a check matrix.<br />
* All observers will be notified, update action: check.
*/
public void checkGame() {
selectedNumber = 0;
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++)
check[y][x] = game[y][x] == solution[y][x];
}
setChanged();
notifyObservers(UpdateAction.CHECK);
}
/**
* Sets help turned on or off.<br />
* All observers will be notified, update action: help.
*
* @param help True for help on, false for help off.
*/
public void setHelp(boolean help) {
this.help = help;
setChanged();
notifyObservers(UpdateAction.HELP);
}
/**
* Sets selected number to user input.<br />
* All observers will be notified, update action: selected number.
*
* @param selectedNumber Number selected by user.
*/
public void setSelectedNumber(int selectedNumber) {
this.selectedNumber = selectedNumber;
setChanged();
notifyObservers(UpdateAction.SELECTED_NUMBER);
}
/**
* Returns number selected user.
*
* @return Number selected by user.
*/
public int getSelectedNumber() {
return selectedNumber;
}
/**
* Returns whether help is turned on or off.
*
* @return True if help is turned on, false if help is turned off.
*/
public boolean isHelp() {
return help;
}
/**
* Returns whether selected number is candidate at given position.
*
* @param x X position in game.
* @param y Y position in game.
* @return True if selected number on given position is candidate,
* false otherwise.
*/
public boolean isSelectedNumberCandidate(int x, int y) {
return game[y][x] == 0 && isPossibleX(game, y, selectedNumber)
&& isPossibleY(game, x, selectedNumber) && isPossibleBlock(game, x, y, selectedNumber);
}
/**
* Sets given number on given position in the game.
*
* @param x The x position in the game.
* @param y The y position in the game.
* @param number The number to be set.
*/
public void setNumber(int x, int y, int number) {
game[y][x] = number;
}
/**
* Returns number of given position.
*
* @param x X position in game.
* @param y Y position in game.
* @return Number of given position.
*/
public int getNumber(int x, int y) {
return game[y][x];
}
/**
* Returns whether user input is valid of given position.
*
* @param x X position in game.
* @param y Y position in game.
* @return True if user input of given position is valid, false
* otherwise.
*/
public boolean isCheckValid(int x, int y) {
return check[y][x];
}
/**
* Returns whether given number is candidate on x axis for given game.
*
* @param game Game to check.
* @param y Position of x axis to check.
* @param number Number to check.
* @return True if number is candidate on x axis, false otherwise.
*/
private boolean isPossibleX(int[][] game, int y, int number) {
for (int x = 0; x < 9; x++) {
if (game[y][x] == number)
return false;
}
return true;
}
/**
* Returns whether given number is candidate on y axis for given game.
*
* @param game Game to check.
* @param x Position of y axis to check.
* @param number Number to check.
* @return True if number is candidate on y axis, false otherwise.
*/
private boolean isPossibleY(int[][] game, int x, int number) {
for (int y = 0; y < 9; y++) {
if (game[y][x] == number)
return false;
}
return true;
}
/**
* Returns whether given number is candidate in block for given game.
*
* @param game Game to check.
* @param x Position of number on x axis in game to check.
* @param y Position of number on y axis in game to check.
* @param number Number to check.
* @return True if number is candidate in block, false otherwise.
*/
private boolean isPossibleBlock(int[][] game, int x, int y, int number) {
int x1 = x < 3 ? 0 : x < 6 ? 3 : 6;
int y1 = y < 3 ? 0 : y < 6 ? 3 : 6;
for (int yy = y1; yy < y1 + 3; yy++) {
for (int xx = x1; xx < x1 + 3; xx++) {
if (game[yy][xx] == number)
return false;
}
}
return true;
}
/**
* Returns next posible number from list for given position or -1 when list
* is empty.
*
* @param game Game to check.
* @param x X position in game.
* @param y Y position in game.
* @param numbers List of remaining numbers.
* @return Next possible number for position in game or -1 when
* list is empty.
*/
private int getNextPossibleNumber(int[][] game, int x, int y, List<Integer> numbers) {
while (numbers.size() > 0) {
int number = numbers.remove(0);
if (isPossibleX(game, y, number) && isPossibleY(game, x, number) && isPossibleBlock(game, x, y, number))
return number;
}
return -1;
}
/**
* Generates Sudoku game solution.
*
* @param game Game to fill, user should pass 'new int[9][9]'.
* @param index Current index, user should pass 0.
* @return Sudoku game solution.
*/
private int[][] generateSolution(int[][] game, int index) {
if (index > 80)
return game;
int x = index % 9;
int y = index / 9;
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++) numbers.add(i);
Collections.shuffle(numbers);
while (numbers.size() > 0) {
int number = getNextPossibleNumber(game, x, y, numbers);
if (number == -1)
return null;
game[y][x] = number;
int[][] tmpGame = generateSolution(game, index + 1);
if (tmpGame != null)
return tmpGame;
game[y][x] = 0;
}
return null;
}
/**
* Generates Sudoku game from solution.
*
* @param game Game to be generated, user should pass a solution.
* @return Generated Sudoku game.
*/
private int[][] generateGame(int[][] game) {
List<Integer> positions =
用java编写的数独游戏
需积分: 15 72 浏览量
2013-10-03
12:57:23
上传
评论 1
收藏 32KB RAR 举报
yanyunb
- 粉丝: 1
- 资源: 5
最新资源
- 63bdcaf5-6734-4718-a93b-13d8f4.html
- ebb9d6214df146e2a3c4136a8e33d88b_fe6ce2e6232417d8b5b2b33b5d02c36.apk
- three.js旋转立方体
- 基于Vue的服装大脑项目数据大屏设计源码
- 今天什么节日?恶搞小软件
- Python + MongoDB开发的百度云爬虫.zip
- GB-T 28827.1-2022 信息技术服务 运行维护 第1部分:通用要求国家标准
- 负反馈放大电路的一个例子
- DMN2041L-7-F-VB一款N-Channel沟道SOT23的MOSFET晶体管参数介绍与应用说明
- 辅助抢红包APP无需root
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈