import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.ArrayList;
/**
* NumbrixEngine loads a test file that describes a Numbrix game in
* progress and verifies that the loaded data represents a valid state
* for a Numrbix game and reports of the game is complete.
*
* @author Austin Anderson
*
*/
public class NumbrixEngine {
public static int[] gameBoardSize = new int[2];
public static int[][] CurrentBoard;
public ArrayList<Integer> numbers = new ArrayList<Integer>();
private int[] count;
public boolean endGame = false;
/**
* Main method I created to read in and run test files.
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
NumbrixEngine e = new NumbrixEngine();
e.loadGame("/home/anderaus/Desktop/test/valid_complete_1.txt");
e.displayBoard();
}
public void makeInGameMenu() {
System.out.println("[1] Start new game.");
System.out.println("[2] Restart current game.");
System.out.println("[3] Save game.");
System.out.println("[4] Load saved game.");
System.out.println("[5] Exit game.");
Scanner scan = new Scanner(System.in);
int choice = 0;
try {
choice = scan.nextInt();
}
catch (InputMismatchException ime) {
}
catch (NoSuchElementException nsee){
}
scan.nextLine();
switch(choice) {
case 1:
// NumbrixEngine();
case 2:
// Restart();
case 3:
// Save();
case 4:
// Exit();
default :
makeInGameMenu();
}
}
/**
* Initializes the current board array.
*/
public NumbrixEngine() {
}
/**
* Reads in a file and calls loadGame and throws exceptions if
* necessary.
*
* @param filename
* @throws InvalidGameStateException
*/
public NumbrixEngine(String filename)
throws InvalidGameStateException {
try {
loadGame("/home/anderaus/Desktop/test/valid_complete_1.txt");
} catch (FileNotFoundException e) {
System.out.println("File Not Found.");
e.printStackTrace();
} catch (ParseException e) {
System.out.println("File will not read properly.");
e.printStackTrace();
} catch (InvalidGameStateException e) {
System.out.println("Invaid game state.");
e.printStackTrace();
}
if (isValid() == false) {
throw new InvalidGameStateException("message");
}
parseComments();
validBoardSize();
validRange();
unique();
}
/**
*
* @return
*/
private boolean parseComments() {
return true;
}
/**
* Returns true if the board size is one or higher for rows and
* columns.
*
* @return true if board size is valid, false if invalid
*/
private boolean validBoardSize() {
if ((gameBoardSize[0] > 0) && (gameBoardSize[1] > 0)) {
return true;
}
return false;
}
/**
* Returns true if numbers are in a valid range.
*
* @return true if range is valid, false if invalid
*/
private boolean validRange() {
int maxNumber = numbers.size() - 2;
for (int i = 2; i < numbers.size(); i++) {
if (i < maxNumber) {
return true;
}
}
return false;
}
/**
* Returns true if each number is only seen once.
*
* @return true if everyone number is unique, false if at least one
* number is used more than once
*/
private boolean unique() {
count = new int[gameBoardSize[0] * gameBoardSize[1]];
for (int i = 2; i < numbers.size(); i++) {
count[numbers.get(i)]++;
}
for (int j = 1; j < count.length; j++) {
if (count[j] != 1) {
return false;
}
}
return true;
}
/**
* Returns the integer neighbor based on the number in currentBoard
* and which direction is being checked.
*
* @param r
* @param c
* @param x
* @param y
*
* @return int neighbor
*/
private int checkNeighbor(int r, int c, int x, int y) {
int neighbor = CurrentBoard[r + x][c + y];
return neighbor;
}
/**
* Checks if each number is touched on the north, south, east or
* west side by a number that is one greater than itself.
*
* @return returns true if each number is touched by a number one
* greater, false if otherwise
* @throws InvalidGameStateException
*/
private boolean isValid() throws InvalidGameStateException {
boolean valid = true;
int row = gameBoardSize[0];
int col = gameBoardSize[1];
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; r++) {
if (CurrentBoard[r][c] != 0
|| CurrentBoard[r][c] != (row * col)) {
if (r > 0) {
if (CurrentBoard[r][c] != checkNeighbor(r, c,
1, 0) + 1) {
valid = false;
}
if (CurrentBoard[r][c] != checkNeighbor(r, c,
-1, 0) + 1) {
valid = false;
} else {
valid = true;
}
if (r < row) {
if (CurrentBoard[r][c] != checkNeighbor(r,
c, 1, 0) + 1) {
valid = false;
} else {
valid = true;
}
}
if (c > 0) {
if (CurrentBoard[r][c] != checkNeighbor(r,
c, 0, -1) + 1) {
valid = false;
}
if (CurrentBoard[r][c] != checkNeighbor(r,
c, 0, -1) + 1) {
valid = false;
} else {
valid = true;
}
if (c < col) {
if (CurrentBoard[r][c] != checkNeighbor(
r, c, 0, -1) + 1) {
valid = false;
} else {
valid = true;
}
}
}
}
}
}
}
return valid;
}
/**
* Returns true if the game is valid and if 0 is never seen.
*
* @return true if game is complete, false if otherwise.
*/
public boolean isComplete() {
if (count[0] == 0) {
return true;
}
return false;
}
/**
* Reads in a file and creates a gameboard based on the data in the
* file. Throws exceptions where necessary.
*
* @param fileName
* @throws ParseException
* @throws InvalidGameStateException
* @throws FileNotFoundException
*/
public void loadGame(String fileName) throws ParseException,
InvalidGameStateException, FileNotFoundException {
String comment;
Scanner scan = new Scanner(new File(fileName));
while (scan.hasNextLine()) {
comment = scan.nextLine();
if (comment.length() != 0) {
if (!(comment.charAt(0) == '#')) {
int comment_position = comment.indexOf('#');
if (comment_position != -1) {
comment = comment
.substring(0, comment_position);
}
Scanner sc1 = new Scanner(comment);
while (sc1.hasNext()) {
try {
numbers.add(sc1.nextInt());
} catch (InputMismatchException a) {
throw new ParseException(
"input type invalid", 0);
}
}
}
}
}
try {
gameBoardSize[0] = numbers.get(0);
gameBoardSize[1] = numbers.get(1);
if (numbers.get(0) == 0 && numbers.get(1) == 0) {
throw new ParseException("Board size is invalid", 0);
}
if (numbers.get(0) == 0 || numbers.get(1) == 0) {
throw new InvalidGameStateException(
"Board size is invalid");
}
} catch (IndexOutOfBoundsException i) {
throw new ParseException("Board size is invalid", 0);
}
if ((numbers.size() - 2) > (gameBoardSize[0] * gameBoardSize[1])
|| (numbers.size() - 2) < (gameBoardSize[0] * gameBoardSize[1])) {
throw new ParseException("Too much data", 0);
}
CurrentBoard = new int[gameBoardSize[0]][gameBoardSize[1]];
int a = 2;
for (int i = 0; i < CurrentBoard.length; i++) {
for (int j = 0; j < CurrentBoard[i].length; j++) {
CurrentBoard[i][j] = numbers.get(a);
a++;
}
}
}
private static String makeBoard(int maxDigit) {
String temp = "";
String mid = "";
String line = "-";
String split = "+";
for (int i = 0; i < maxDigit; i++) {
mid += line;
}
temp += "" + split;
for (int j = 0; j < gameBoardSize[0]; j++) {
if (j < gameBoardSize[0] - 1) {
temp += mid;
temp += split;
} else {
temp += mid;
}
}
temp += split;
return temp;
}
public void displayBoard() {
String totalSize = "" + gameBoardSize[0] * gameBoardSize[1];
String display = "";
int maxDigit = totalSize.length();
display += makeBoard(maxDigit) + "\n";
for (int r = 0; r < CurrentBoard.length; r++) {
if (r > 0) {
display += "\n" + makeBoard(maxDigit) + "\n";
}
// System.out.print(r);
for (int c = 0; c < CurrentBoard[r].length; c++) {
String total = "" + CurrentBoard[r][c];
// System.out.print(total);
// display += " ";
int totalCount = total.length();
if (total.contentEquals("0") || total.isEmpty()) {
display += "|"
+ makeSpace(totalCount, maxDigit, " ")
+ "-";
} else {
// System.out.println(total);
display += "|"
+ makeSpace(totalCount, maxDigit, " ")
+ total;
}
}
display += "|";
}
display += "\n" + makeBoard(maxDigit) + "\n";
System.out.print(display);
}
private String makeSpace(int totalCount, int maxDigit, String spacer) {
String temp = "";
int space = maxDigit - totalCount;
for (int i = 0; i < space; i++) {
temp += "" + spacer;
}
return temp;
}
}