package com.jw.boggle;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
public class Board {
private final int[] board;
private final int size;
private Board(int[] board, int size) {
this.board = board;
this.size = size;
}
public int[] getBoard() {
return board;
}
public int getSize() {
return size;
}
public static Board newBoard(final int size)
{
int[] board = new Random().ints(size*size, 'a', 'z'+1).toArray();
return new Board(board,size);
}
public static Board loadBoard(final String fileName) throws IOException
{
final Path path = Paths.get(fileName);
final List<String> allLines = Files.readAllLines(path);
if(allLines.size() != 2)
{
throw new IllegalArgumentException("Incorrect format");
}
final int size = Integer.parseInt(allLines.get(0));
final int[] data = allLines.get(1).chars().toArray();;
return new Board(data, size);
}
public static void writeBoard(final Board board, final String fileName) throws IOException
{
Path path = Paths.get(fileName);
try(final BufferedWriter writer = Files.newBufferedWriter(path))
{
writer.write(board.getSize() + "\n");
IntStream.of(board.getBoard()).forEach(x ->
{
try {
writer.write((char)x);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
public static void printBoard(final Board board)
{
int count = 0;
for(int i : board.getBoard())
{
System.out.print((char) i + " ");
if(++count % board.getSize() == 0)
{
System.out.println();
}
}
}
public int[] newAdjacencyList()
{
final int totalSize = size*size;
final int[] list2 = new int[totalSize * 8]; //8 is the max amount of neighbors
Arrays.parallelSetAll(list2, x -> -1);
final int[] upperRow = {-(size+1), -size, -(size-1)};
final int[] sameRow = {-1, +1};
final int[] lowerRow = {size-1, size, size+1 };
final IntPredicate basePredicate = x -> x >= 0 && x < totalSize;
for(int i = 0; i < totalSize; ++i)
{
final int cur = i;
final int currentRowIndex = (cur / size) + 1; //plus 1 to make it start indexing at 1
//all exclusive indices
final int upperRowIndex = (currentRowIndex - 1) * size;
final int sameRowIndex = currentRowIndex * size;
final int lowerRowIndex = (currentRowIndex + 1) * size;
int innerIndex = 0;
final int bigIndex = i * 8;
innerIndex = findMatches(cur, upperRow, basePredicate.and(x-> x < upperRowIndex), bigIndex, innerIndex, list2);
innerIndex = findMatches(cur, sameRow, basePredicate.and(x-> x >= upperRowIndex && x < sameRowIndex), bigIndex, innerIndex, list2);
findMatches(cur, lowerRow, basePredicate.and(x-> x >= sameRowIndex && x < lowerRowIndex), bigIndex, innerIndex, list2);
}
return list2;
}
public static void printAdjacencyList(int[] list)
{
int count = 0;
for(int i: list)
{
if(i != -1)
{
System.out.print(i + " ");
}
if(++count % 8 == 0) System.out.println();
}
}
private static int findMatches(final int base, final int[] offsets, IntPredicate boundsCheck, final int bigIndex, int innerIndex, final int[] list)
{
for(int off : offsets)
{
final int result = base + off;
if(boundsCheck.test(result))
{
list[bigIndex + innerIndex++] = result;
}
}
return innerIndex;
}
}