Having difficulties printing out my board in my Snake Game - java

I am not an expert on java and have run into an issue on my Snake Game. I have created a class called GameManager:
public class GameManager {
private GameObject board[][];
private int xR;
private int yR;
public Snake snk;
private Food food;
public GameManager (String fileName) {
BufferedReader fileInput = null;
try {
fileInput = new BufferedReader(new FileReader(fileName));
Scanner fileScanner = new Scanner(fileInput);
int rows = fileScanner.nextInt();
int cols = fileScanner.nextInt();
board = new GameObject[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
board[row][col] = new Empty();
}
}
while(fileScanner.hasNext()) {
fileScanner.nextLine();
int xStart = fileScanner.nextInt();
int yStart = fileScanner.nextInt();
int xEnd = fileScanner.nextInt();
int yEnd = fileScanner.nextInt();
addWall(xStart, yStart, xEnd, yEnd);
}
addGameObject(snk);
addGameObject(food);
fileScanner.close();
} catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(fileInput != null) {fileInput.close();}
} catch(IOException e) {
e.printStackTrace();
}
}
}
public void newRandomXY() {
Random r = new Random(0);
this.xR = r.nextInt(board.length);
this.yR = r.nextInt(board.length);
}
public void addGameObject(GameObject s) {
newRandomXY();
while(board[xR][yR].isOccupied()) {
newRandomXY();
}
if(s instanceof Snake) {
s = new Snake(xR, yR);
board[xR][yR] = s;
} else if(s instanceof Food) {
s = new Food(xR, yR);
board[xR][yR] = s;
}
}
public void addWall(int xStart, int yStart, int xEnd, int yEnd) {
for(int x = xStart; x <= xEnd; x++) {
for(int y = yStart; y <= yEnd; y++) {
board[x][y] = new Wall();
}
}
}
#Override
public String toString() {
String ret = "";
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
ret += board[row][col].toString();
}
ret += "\n";
}
return ret;
}
}
Now the issue I'm having is that whenever I try to print a string version of this board on my cmd, the program just hangs and I have to hard close the cmd. I have been messing around with some of the code and I have been able to fix the program just crashing, but I haven't been able to figure why its all not printing out.
Here is my Snake Class (Note: I also have some other methods in this class that I am not using at the moment, so I don't think they are the issue):
public class Snake extends GameObject {
private Point head;
private Deque<Point> snakeBody;
private int lenght = 0;
private String direction = "UP";
public Snake(int x, int y) {
this.head = super.newCell(x, y);
this.snakeBody = new ArrayDeque<Point>();
this.snakeBody.push(head);
}
and my toString of Snake:
public String toString(Deque<Point> s) {
String str = "";
for(Point p : s) {
String snk = p.toString();
snk = "S";
str += snk;
}
return str;
}
Here's my Food Class:
public class Food extends GameObject {
private Point foodLoc;
public Food(int x, int y) {
this.foodLoc = new Point(x, y);
}
public Point getLocation() {
return foodLoc.getLocation();
}
public String toString() {
return "F";
}
}
and here is my GameObject Class:
import java.awt.Point;
public class GameObject {
public final int CELL_SIZE = 1;
public Point newCell(int x, int y) {
return new Point(x, y);
}
public boolean isOccupied() {
return true;
}
public boolean isOccupied(Point p, Point o) {
boolean flag = false;
if(p.getLocation().equals(o.getLocation())) {
flag = true;
} else {
flag = false;
}
return flag;
}
}
I have a good feeling that my toString method in Snake is completely wrong, but I don't necessarily understand how to fix it and why my other toString methods don't work. I have looked around the forums to see if I could find and answer, but I couldn't find anything for this.

The problem is that you're trying to print an array of type gameObject, but that object does not have a .toString operator, so it's always going to return null.
I'm guessing that you want to represent the cells as either empty or occupied, or perhaps even further by having food, but you'd need a .toString in that class to define what you want returned in whatever given scenario.

Related

New to Programming (Java) - dont know how to fix an error with a small Console Game simular to Snake

I just started to learn Java and am working on a small project which is supposed to create a gameField in a 2 dimensional String Array Field Borders are marked with a "#". In this Field I want to spawn a player who is marked as ">". This player can then turn left or right (∧ for looking up for example) and then has the option to move forward one space.
I currently have the gameField created and now want to spawn the player into that 2 dimensional String Array for which I have made a spawnPlayer method/function in the class Player. I now want to add / open that method/function in the main method. This is where I am getting the error messages and dont know what to do.
public class KonsolenWanderer {
public static void main(String[] args) {
Field field1 = new Field();
field1.createField();
Player player1 = new Player();
//Error is here!!!
player1.spawnPlayer();
}
}
public class Field {
private String [][] fieldSize = new String [10][10];
public void createField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
//Creating Field Border
if(i == 0 || i == 9 || j == 0 || j == 9) {
fieldSize[i][j] = "#";
}
else {
fieldSize[i][j] = " ";
}
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public String[][] getFieldSize() {
return fieldSize;
}
public void setFieldSize(String[][] fieldSize) {
this.fieldSize = fieldSize;
}
}
public class Player {
private static int xPosition;
private static int yPosition;
private String up = "∧";
private String down = "∨";
private String left = "<";
private String right = ">";
private String currentDirection;
Player() {
xPosition = 4;
yPosition = 4;
}
public void spawnPlayer(String[][]fieldSize) {
fieldSize[xPosition][yPosition] = ">";
}
public static void moveForward() {
}
public static void turnPlayerLeft() {
}
public static void turnPlayerRight() {
}
}
You need to set the position inside the field object or expose fieldSize from within Field class.
public class KonsolenWanderer {
public static void main(String[] args) {
Field field = new Field();
field.createField();
Player player1 = new Player();
//Error is here!!!
player1.spawnPlayer(new String[8][8], field);
field.showField();
}
}
class Field {
private String [][] fieldSize = new String [10][10];
public void createField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
//Creating Field Border
if(i == 0 || i == 9 || j == 0 || j == 9) {
fieldSize[i][j] = "#";
}
else {
fieldSize[i][j] = " ";
}
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public void showField() {
for(int i = 0; i < fieldSize.length; i++) {
for(int j = 0; j < fieldSize[i].length; j++) {
System.out.print(fieldSize[i][j]);
}
System.out.println();
}
}
public String[][] getFieldSize() {
return fieldSize;
}
public void setFieldSize(String[][] fieldSize) {
this.fieldSize = fieldSize;
}
public void setPlayerPosition(int i, int j) {
i++;
j++;
fieldSize[i][j] = ">";
}
}
class Player {
private static int xPosition;
private static int yPosition;
private String up = "∧";
private String down = "∨";
private String left = "<";
private String right = ">";
private String currentDirection;
Player() {
xPosition = 4;
yPosition = 4;
}
public void spawnPlayer(String[][] fieldSize, Field field) {
for(int i = 0; i < fieldSize.length; i++) {
if (i == fieldSize.length -1){
for(int j = 0; j < fieldSize[i].length; j++) {
if (j == fieldSize.length - 1 )
field.setPlayerPosition(i, j);
}
}
}
}
public static void moveForward() {
}
public static void turnPlayerLeft() {
}
public static void turnPlayerRight() {
}
}

random and time adequacy

I try to do my own version of "fruit ninja" for training based on this version : https://github.com/emmaguy/FruitNinja
I have done some minor changes. What I want to do is to affect different scores to the object in the "enum" in fruittype.
So, I add this function (in the aim to retrieve the current random value):
public static int currentrandom() {
return random.nextInt(FruitType2.values().length );
}
and I add,
if (FruitType2.currentrandom()<=9) {
score++;
} else {
score=score-5;
}
at the end of FruitProjectileManager.
Complete code for FruitProjectileManager:
public class FruitProjectileManager02 implements ProjectileManager {
private final Random random2 = new Random();
private final List<Projectile> fruitProjectiles =
new ArrayList<Projectile>();
private final SparseArray<Bitmap> bitmapCache;
private Region clip;
private int maxWidth;
private int maxHeight;
private String FruitTypen = "FruitType2";
public FruitProjectileManager02(Resources r) {
bitmapCache = new SparseArray<Bitmap>(FruitType2.values().length);
for (FruitType2 t : FruitType2.values()) {
bitmapCache.put(t.getResourceId(), BitmapFactory.decodeResource(r, t.getResourceId(), new Options()));
}
}
public void draw(Canvas canvas) {
for (Projectile f : fruitProjectiles) {
f.draw(canvas);
}
}
public void update() {
if (maxWidth < 0 || maxHeight < 0) {
return;
}
if (random2.nextInt(1000) < 30) {
fruitProjectiles.add(createNewFruitProjectile());
}
for (Iterator<Projectile> iter = fruitProjectiles.iterator(); iter.hasNext(); ) {
Projectile f = iter.next();
f.move();
if (f.hasMovedOffScreen()) {
iter.remove();
}
}
}
private FruitProjectile02 createNewFruitProjectile() {
int angle = random2.nextInt(20) + 70;
int speed = random2.nextInt(30) + 120;
boolean rightToLeft = random2.nextBoolean();
float gravity = random2.nextInt(6) + 8.0f;
float rotationStartingAngle = random2.nextInt(360);
float rotationIncrement = random2.nextInt(100) / 3.0f;
if (random2.nextInt(1) % 2 == 0) {
rotationIncrement *= -1;
}
return new FruitProjectile02(bitmapCache.get(FruitType2.randomFruit().getResourceId()), maxWidth, maxHeight,
angle, speed, gravity, rightToLeft, rotationIncrement, rotationStartingAngle);
}
public void setWidthAndHeight(int width, int height) {
this.maxWidth = width;
this.maxHeight = height;
this.clip = new Region(0, 0, width, height);
}
#Override
public int testForCollisions(List<TimedPath> allPaths) {
int score = 0;
for (TimedPath p : allPaths) {
for (Projectile f : fruitProjectiles) {
if (!f.isAlive())
continue;
Region projectile = new Region(f.getLocation());
Region path = new Region();
path.setPath(p, clip);
if (!projectile.quickReject(path) && projectile.op(path, Region.Op.INTERSECT)) {
if (FruitType2.currentrandom() <= 9) {
score++;
} else {
score = score - 5;
}
f.kill();
}
}
}
return score;
}
}
Complete code for FruitType:
public enum FruitType2 {
T02(R.drawable.n002),
T04(R.drawable.n004),
T06(R.drawable.n006),
T08(R.drawable.n008),
T10(R.drawable.n010),
T12(R.drawable.n012),
T14(R.drawable.n014),
T16(R.drawable.n016),
T18(R.drawable.n018),
T20(R.drawable.n020),
OTHER1(R.drawable.n003),
OTHER2(R.drawable.n007),
OTHER3(R.drawable.n011);
private final int resourceId;
private FruitType2(int resourceId) {
this.resourceId = resourceId;
}
public int getResourceId() {
return resourceId;
}
private static final Random random = new Random();
public static int currentrandom() {
return random.nextInt(FruitType2.values().length);
}
public static FruitType2 randomFruit() {
return FruitType2.values()[random.nextInt(FruitType2.values().length)];
}
}
I understand the problem , the current random(when the fruit is generated) is not the same that the random when the fruit is sliced and my question is how to
solve this problem. I get no idea so if you have some clues, I am interested.
Thank you in advance.
Perhaps i don't understand the problem, but why don't you store the random number in a variable? Later you can take the random number out of the variable.

How can I get value from one class to another without extends it?

I am newbie in programming and may be this will be stupid question but here it is:
This is my class board:
public class Board {
public static final int COLOR_WHITE = 1;
public static final int COLOR_BLACK = 2;
PlayingPiece[][] board;
private boolean isFirstMove;
private int color;
public Board() {
this.setBoard(new PlayingPiece[8][8]);
this.isFirstMove = true;
this.initializePieces();
}
// Initialize the chess pieces
public void initializePieces() {
for (int i = 0; i < 8; i++) {
board[1][i] = new Pawn(1, i, COLOR_WHITE);
}
for (int i = 0; i < 8; i++) {
board[6][i] = new Pawn(6, i, COLOR_BLACK);
}
board[0][0] = new Rook(0, 0, COLOR_WHITE);
board[0][7] = new Rook(0, 7, COLOR_WHITE);
board[7][0] = new Rook(7, 0, COLOR_BLACK);
board[7][7] = new Rook(7, 7, COLOR_BLACK);
board[0][1] = new Knight(0, 1, COLOR_WHITE);
board[0][6] = new Knight(0, 6, COLOR_WHITE);
board[7][1] = new Knight(7, 1, COLOR_BLACK);
board[7][6] = new Knight(7, 6, COLOR_BLACK);
board[0][2] = new Officer(0, 2, COLOR_WHITE);
board[0][5] = new Officer(0, 5, COLOR_WHITE);
board[7][2] = new Officer(7, 2, COLOR_BLACK);
board[7][5] = new Officer(7, 5, COLOR_BLACK);
board[0][3] = new Queen(3, 0, COLOR_WHITE);
board[0][4] = new King(4, 0, COLOR_WHITE);
board[7][3] = new Queen(7, 3, COLOR_BLACK);
board[7][4] = new King(7, 4, COLOR_BLACK);
this.printBoard();
}
public boolean play(int color, int fromX, int fromY, int toX, int toY) {
boolean isTrue = false;
// Check if this is the first turn and only white can move
if (isFirstMove && color == COLOR_WHITE) {
isTrue = true;
} else if (isFirstMove && color == COLOR_BLACK) {
return false;
}
// check if player plays 2 times in a raw and if you move the piece from
// current possition
if (color == this.color || (toX == fromX && toY == fromY)) {
return false;
}
isTrue = true;
if (isTrue == true) {
this.isFirstMove = false;
// Check if player plays with his own color
if (((board[fromX][fromY]).getColor() != color)) {
return false;
}
// Check the isLegal movement of every chess piece
if ((board[fromX][fromY]).move(toX, toY)) {
board[toX][toY] = board[fromX][fromY];
board[fromX][fromY] = null;
}
this.printBoard();
}
return isTrue;
}
public PlayingPiece[][] getBoard() {
return board;
}
public void setBoard(PlayingPiece[][] board) {
this.board = board;
}
I want to get the value of this:
board[toX][toY];
OK after that here is the other my class for chess pieces:
public class PlayingPiece {
public static final int COLOR_WHITE = 1;
public static final int COLOR_BLACK = 2;
public static final char BLACK_PAWN = '\u265F';
public static final char BLACK_ROOK = '\u265C';
public static final char BLACK_KNIGHT = '\u265E';
public static final char BLACK_BISHOP = '\u265D';
public static final char BLACK_QUEEN = '\u265B';
public static final char BLACK_KING = '\u265A';
public static final char WHITE_PAWN = '\u2659';
public static final char WHITE_ROOK = '\u2656';
public static final char WHITE_KNIGHT = '\u2658';
public static final char WHITE_BISHOP = '\u2657';
public static final char WHITE_QUEEN = '\u2655';
public static final char WHITE_KING = '\u2654';
public static final char NO_PIECE = ' ';
private int x, y;
private boolean isAlive;
private int color;
private char symbol;
protected PlayingPiece (int newX, int newY, int newColor) {
this.setX(newX);
this.setY(newY);
this.color = newColor;
this.isAlive = true;
}
protected PlayingPiece(int newX, int newY) {
this.setX(newX);
this.setY(newY);
}
protected PlayingPiece() {
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
protected boolean moveIsLegal (int newX, int newY) {
boolean isLegal = false;
if ((0 <= newX && newX <= 7) && (0 <= newY && newY <= 7)){
isLegal = true;
}
return isLegal;
}
public boolean move (int newX, int newY) {
if (moveIsLegal(newX, newY)) {
setX(newX);
setY(newY);
return true;
}
return false;
}
public int getColor() {
return color;
}
public boolean isAlive() {
return isAlive;
}
public void setAlive(boolean isAlive) {
this.isAlive = isAlive;
}
public char getSymbol() {
return symbol;
}
public void setSymbol(char symbol) {
this.symbol = symbol;
}
}
And now this is Pawn class which extends PlayingPieces:
public class Pawn extends PlayingPiece {
private boolean hasBeenMoved;
protected Pawn(int newX, int newY, int color) {
super(newX, newY, color);
this.hasBeenMoved = false;
if (color == COLOR_BLACK) {
this.setSymbol(BLACK_PAWN);
} else {
this.setSymbol(WHITE_PAWN);
}
}
#Override
public boolean move(int newX, int newY) {
if (super.move(newX, newY)) {
this.hasBeenMoved = true;
return true;
}
return false;
}
#Override
protected boolean moveIsLegal(int newX, int newY) {
boolean isLegal = false;
int newPositionX = newX - this.getX();
if (super.moveIsLegal(newX, newY)) {
if ((hasBeenMoved == false)
&& (((Math.abs(newPositionX) <= 2) && getY() == newY))) {
isLegal = true;
} else if ((hasBeenMoved == true)
&& (((Math.abs(newPositionX) <= 1) && getY() == newY)) && isValidTrace(newX, newY)) {
isLegal = true;
}
}
return isLegal;
}
public boolean isValidTrace(int newX, int newY) {
PlayingPiece[][] array = new PlayingPiece[8][8];
if (array[newX][newY].equals(new PlayingPiece())) {
return false;
}
return true;
}
}
Now in this method isValidTrace() I want to get the value of board[toX][toY] from class Board and how can I do this without any extends here ?
Another solution (assuming you won't need multiple Board instances) is making board static.
public static PlayingPiece[][] board;
Then you can access it from your Pawn class using Board.board
I do not know if I understand your question but..
If you have got 2 classes A and B instead of using inheritance you can use aggregation. For example, you want to use some method from object B in class A you go with:
class A {
private B b;
}
and then inside methods of class A you go with b.nameOfTheMethod()
You can create a method to return the array and call it in the class you want the data.
public PlayingPiece getBoard()
{
return board;
}

Java AI find solution for NxN Puzzle

First of all there is a lot of code because i really don't know where my issue is, I do apologise!
I'm making a program that solves a varying size puzzle for eg (3x3 with 0-8) The zero represents a blank tile the objective is to move the the blank tile around until the goal state is reached. At the moment I am using Depth First Search to solve the puzzle. Netbeans returns a 'OutOfMemory' error when i run the program however if I change the goal state so it only requires one move to complete it displays the solution. Below is my code, I've only added some of the classes because I don't want this post being ridiculously long. Please let me know if you require the other classes
EDIT: Inserted wrong code for board class
Depth First Search Class
package npuzzle;
import java.util.ArrayList;
import java.util.Stack;
public class DFSearch {
public static void search(int[][] initial, int[][] goal, int rows, int columns)
{
Board board = new Board(initial, goal, rows, columns, "");
Node root = new Node(board);
Stack<Node> stack = new Stack<Node>();
stack.add(root);
performSearch(stack, board);
}
public static void performSearch(Stack<Node> s, Board board)
{
int searchCount = 1;
while (!s.isEmpty())
{
Node tNode = (Node) s.pop();
//if not goal state
if (!tNode.getCurrentState().isGoalState())
{
ArrayList<State> tChildren = tNode.getCurrentState().gChildren();
for (int i = 0; i < tChildren.size(); i++)
{
Node newNode = new Node(tNode, tChildren.get(i), tNode.getGCost() + tChildren.get(i).findCost(), 0);
if(!isRepeatedState(newNode))
{
s.add(newNode);
}
}
searchCount++;
}
else
{
tNode.getCurrentState().printState();
System.exit(0);
//PRINTING OF DIRECTIONS
}
}
System.out.println("Error! No solution found!");
}
private static boolean isRepeatedState(Node c)
{
boolean returnVal = false;
Node checkNode = c;
while(c.getParent() != null && !returnVal)
{
if (c.getParent().getCurrentState().equals(checkNode.getCurrentState()))
{
returnVal = true;
}
c = c.getParent();
}
return returnVal;
}
}
Board Class
package npuzzle;
import java.util.ArrayList;
import java.util.Arrays;
public class Board implements State
{
private int PUZZLE_SIZE = 0;
private int outOfPlace = 0;
private int rows;
private int columns;
private int[][] GOAL;
private int[][] currentBoard;
private String directions = "";
public Board(int[][] initial, int[][] goal, int N, int M, String direction)
{
currentBoard = initial;
GOAL = goal;
rows = N;
columns = M;
PUZZLE_SIZE = rows*columns;
directions = direction;
setOutOfPlace();
}
#Override
public boolean isGoalState() {
if (Arrays.deepEquals(currentBoard, GOAL))
{
return true;
}
return false;
}
#Override
public ArrayList<State> gChildren() {
ArrayList<State> children = new ArrayList<State>();
int[] blanktile = getBlankTile();
int[] newblanktile = Arrays.copyOf(blanktile, blanktile.length);
if (blanktile[0] != 0) {
newblanktile[0]--;
Swap(newblanktile, blanktile, children, "up");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != 0) {
newblanktile[1]--;
Swap(newblanktile, blanktile, children, "left");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[0] != (this.rows - 1)) {
newblanktile[0]++;
Swap(newblanktile, blanktile, children, "down");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
if (blanktile[1] != (this.columns - 1)) {
newblanktile[1]++;
Swap(newblanktile, blanktile, children, "right");
newblanktile = Arrays.copyOf(blanktile, blanktile.length);
}
return children;
}
#Override
public double findCost() {
return 1;
}
#Override
public void printState() {
System.out.println(directions);
}
#Override
public boolean equals(State s) {
if (Arrays.deepEquals(currentBoard, ((Board) s).getCurrentBoard()))
{
return true;
}
else
return false;
}
private void setOutOfPlace() {
int i = 0;
int j = -1;
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] != GOAL[i][j])
{
outOfPlace++;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
}
private int[] getBlankTile()
{
int i = 0;
int j = -1;
int[] blanktile = {0,0};
do
{
if (j == (columns - 1)) {j = 0; i++;}
else {j++;}
if (currentBoard[i][j] == 0) {
blanktile[0] = i;
blanktile[1] = j;
}
} while (((i+1)*(j+1)) < PUZZLE_SIZE);
return blanktile;
}
public int getOutOfPlace()
{
return outOfPlace;
}
private int[][] copyBoard(int[][] state)
{
int[][] returnArray = new int[rows][columns];
for (int i = 0, j = 0; i*j < PUZZLE_SIZE; i++, j++)
{
returnArray[i] = Arrays.copyOf(state[i], state[i].length);
}
return returnArray;
}
private void Swap(int[] nbt, int[] bt, ArrayList<State> children, String direction) {
int[][] cpy = copyBoard(currentBoard);
int temp = cpy[nbt[0]][nbt[1]];
cpy[nbt[0]][nbt[1]] = currentBoard[bt[0]][bt[1]];
cpy[bt[0]][bt[1]] = temp;
children.add(new Board(cpy, this.getGOAL(), this.getRows(), this.getColumns(), (this.getDirections() + direction + ", ")));
}
public int getPUZZLE_SIZE() {
return PUZZLE_SIZE;
}
public int getRows() {
return rows;
}
public int getColumns() {
return columns;
}
public int[][] getGOAL() {
return GOAL;
}
public int[][] getCurrentBoard()
{
return currentBoard;
}
public String getDirections()
{
return directions;
}
}

"A Java Exception has occurred"

So I'm trying to run my pacman project as a jar(also tried runnable) and I just get the error message you see in the title. It runs perfectly fine in eclipse/netbeans, but whilst cleaning/building i see the warnings:
Note: C:\Users\Lucas\Documents\Eclipse\PackMan\src\game\packman\GameData.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
The main class is correct and assigned. Does anybody know what I'm doing wrong?
Here is my GameData class
public class GameData {
int mazeNo;
CopyOnWriteArrayList<Position> pills;
CopyOnWriteArrayList<Position> powerPills;
public MoverInfo packman;
public GhostInfo[] ghostInfos = new GhostInfo[4];
public int score;
Maze[] mazes;
boolean dead = false;
boolean win = false;
public GameData() {
mazes = new Maze[4];
// load mazes information
for (int m=0; m<4; m++) {
mazes[m] = new Maze(m);
}
setMaze(mazeNo);
}
private void setMaze(int m) {
packman = new MoverInfo(mazes[m].packmanPos);
for (int g=0; g<4; g++) {
ghostInfos[g] = new GhostInfo(mazes[m].ghostPos);
}
pills = new CopyOnWriteArrayList((List<Position>)(mazes[m].pills.clone()));
powerPills = new CopyOnWriteArrayList((List<Position>)(mazes[m].powerPills.clone()));
}
public void movePackMan(int reqDir) {
if (move(reqDir, packman)) {
packman.curDir = reqDir;
} else {
move(packman.curDir, packman);
}
}
private int wrap(int value, int incre, int max) {
return (value+max+incre)%max;
}
private boolean move(int reqDir, MoverInfo info) {
// current position of packman is (row, column)
int row = info.pos.row;
int column = info.pos.column;
int rows = mazes[mazeNo].rows;
int columns = mazes[mazeNo].columns;
int nrow = wrap(row, MoverInfo.DROW[reqDir], rows);
int ncol = wrap(column, MoverInfo.DCOL[reqDir], columns);
if (mazes[mazeNo].charAt(nrow, ncol) != '0') {
info.pos.row = nrow;
info.pos.column = ncol;
return true;
}
return false;
}
public void update() {
if (pills.contains(packman.pos)) {
pills.remove(packman.pos);
score += 5;
} else if (powerPills.contains(packman.pos)) {
powerPills.remove(packman.pos);
score += 50;
for (GhostInfo g:ghostInfos) {
g.edibleCountDown = 500;
}
}
for (GhostInfo g:ghostInfos) {
if (g.edibleCountDown > 0) {
if (touching(g.pos, packman.pos)) {
// eat the ghost and reset
score += 100;
g.curDir = g.reqDir = MoverInfo.LEFT;
g.pos.row = mazes[mazeNo].ghostPos.row;
g.pos.column = mazes[mazeNo].ghostPos.column;
g.edibleCountDown = 0;
}
g.edibleCountDown--;
} else {
if (touching(g.pos, packman.pos)) {
dead = true;
}
}
}
// level is cleared
if (pills.isEmpty() && powerPills.isEmpty()) {
mazeNo++;
if (mazeNo < 4) {
setMaze(mazeNo);
} else if (mazeNo == 5) {
win = true;
} else {
// game over
dead = true;
}
}
}
private boolean touching(Position a, Position b) {
return Math.abs(a.row-b.row) + Math.abs(a.column-b.column) < 3;
}
public void moveGhosts(int[] reqDirs) {
for (int i=0; i<4; i++) {
GhostInfo info = ghostInfos[i];
info.reqDir = reqDirs[i];
if (move(info.reqDir, info)) {
info.curDir = info.reqDir;
} else {
move(info.curDir, info);
}
}
}
public int getWidth() {
return mazes[mazeNo].width;
}
public int getHeight() {
return mazes[mazeNo].height;
}
public List<Integer> getPossibleDirs(Position pos) {
List<Integer> list = new ArrayList<>();
for (int d=0; d<4;d++) {
Position npos = getNextPositionInDir(pos, d);
if (mazes[mazeNo].charAt(npos.row, npos.column) != '0') {
list.add(d);
}
}
return list;
}
private Position getNextPositionInDir(Position pos, int d) {
int nrow = wrap(pos.row, MoverInfo.DROW[d], mazes[mazeNo].rows);
int ncol = wrap(pos.column, MoverInfo.DCOL[d], mazes[mazeNo].columns);
return new Position(nrow, ncol);
}
}

Categories

Resources