Java Swing: How to build Connect 4 GUI - java

So I'm trying to create a Connect 4 GUI program in Java using the MVC pattern, where this class is the Model:
public class ConnectFourGame {
private Board board;
private Player playerX;
private Player playerO;
private int turnCount;
private CheckWinnerAlgorithm checkWinner;
/**
* Constructs a new ConnectFourGame instance.
*/
public ConnectFourGame() {
this.board = new Board();
this.playerX = new Player('X');
this.playerO = new Player('O');
this.turnCount = 1;
this.checkWinner = new CheckWinnerAlgorithm();
}
/**
* Accesses the current game board.
* #return a Board object representing the current game board
*/
public Board getBoard() {
return this.board;
}
/**
* Accesses player X and their attributes.
* #return a PlayerX object
*/
public Player getPlayerX() {
return this.playerX;
}
/**
* Accesses player O and their attributes.
* #return a PlayerO object
*/
public Player getPlayerO() {
return this.playerO;
}
/**
* Returns the winner of the game.
* #return a CheckWinnerAlgorithm object containing the winner token
*/
public CheckWinnerAlgorithm getWinner() {
return this.checkWinner;
}
/**
* Determines whose turn it is based on the game's turn counter.
* #return the Player whose turn it currently is
*/
public Player determineTurn() {
if (this.turnCount % 2 == 0) {
return this.playerO;
}
else {
return this.playerX;
}
}
/**
* Assesses whether a player move can be made, placing a token if valid.
* #param colNum An int specifying the column chosen by the player
* #param playerToken A char representing the player's token
* #return a boolean, true if a valid move has been made and false otherwise
*/
public boolean moveIsMade(int colNum, char playerToken) {
// move cannot be made if selected column is full
if (board.getBoard()[0][colNum-1] != ' ') {
System.out.println("The selected column is full.");
return false;
}
// if column is not full, place token at bottom-most available spot
for (int row=0; row<6; row++) {
if (board.getBoard()[row][colNum-1] != ' ') {
board.getBoard()[row-1][colNum-1] = playerToken;
this.turnCount++;
return true;
}
}
// place token at bottom of empty column
board.getBoard()[5][colNum-1] = playerToken;
this.turnCount++;
return true;
}
/**
* Specifies whether the game is over.
* #return a boolean, true if the game is over and false otherwise
*/
public boolean isOver() {
if (this.checkWinner.findWinner(this.board)!=' ') {
this.resetGame();
return true;
}
return false;
}
/**
* Resets the game to a beginning state.
*/
public void resetGame() {
this.board.clearBoard();
this.checkWinner.resetWinnerToken();
this.turnCount = 1;
}
}
Now I'm trying to figure out how to start building the View class with Swing GUI elements. Below is a rough mockup of the GUI I have in mind:
The top row are JButtons which will drop a token into the corresponding column of the board when clicked. I'm thinking of using a 2D 6*7 array of JLabels to represent the board. How can I display this in the above manner?
Help would be greatly appreciated!

How can I display JLabels in the above manner (like a grid)?
You would use the GridLayout.
Your other alternative is to use a JPanel as a drawing panel, and draw the game board. By drawing the game board, you can make the pieces circles instead of squares.
How do I set up handling for all this in the Controller class?
You will have more than one controller class. In Java Swing, action listeners are the controllers in your model / view / controller pattern.
The JButtons to drop pieces will each have a separate action listener.

Related

Problem with BFS in graph java . It is n`t returning anything

I am making a project like google map in which I have to construct a graph in which vertices are intersections and edges are roads .
In my code I was able to add intersections and roads but I`m not able to return a path through breadth first search . And this is my code ,
public class MapGraph {
//TODO: Add your member variables here in WEEK 3
HashSet<GeographicPoint> intersections ;
HashMap<GeographicPoint,LinkedList<GeographicPoint>> roads ;
HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>> roadInfo ;
/**
* Create a new empty MapGraph
*/
public MapGraph()
{
// TODO: Implement in this constructor in WEEK 3
intersections = new HashSet<GeographicPoint>() ;
roads = new HashMap<GeographicPoint,LinkedList<GeographicPoint>>() ;
roadInfo = new HashMap<HashMap<GeographicPoint,GeographicPoint>,ArrayList<String>>() ;
}
/**
* Get the number of vertices (road intersections) in the graph
* #return The number of vertices in the graph.
*/
public int getNumVertices()
{
//TODO: Implement this method in WEEK 3
return intersections.size();
}
/**
* Return the intersections, which are the vertices in this graph.
* #return The vertices in this graph as GeographicPoints
*/
public Set<GeographicPoint> getVertices()
{
//TODO: Implement this method in WEEK 3
return intersections;
}
/**
* Get the number of road segments in the graph
* #return The number of edges in the graph.
*/
public int getNumEdges()
{
//TODO: Implement this method in WEEK 3
int num = 0 ;
for(GeographicPoint gp : roads.keySet()) {
num+=roads.get(gp).size() ;
}
return num;
}
/** Add a node corresponding to an intersection at a Geographic Point
* If the location is already in the graph or null, this method does
* not change the graph.
* #param location The location of the intersection
* #return true if a node was added, false if it was not (the node
* was already in the graph, or the parameter is null).
*/
public boolean addVertex(GeographicPoint location)
{
// TODO: Implement this method in WEEK 3
if(!intersections.contains(location) && !(location == null)) {
intersections.add(location) ;
return true ;
}
return false;
}
/**
* Adds a directed edge to the graph from pt1 to pt2.
* Precondition: Both GeographicPoints have already been added to the graph
* #param from The starting point of the edge
* #param to The ending point of the edge
* #param roadName The name of the road
* #param roadType The type of the road
* #param length The length of the road, in km
* #throws IllegalArgumentException If the points have not already been
* added as nodes to the graph, if any of the arguments is null,
* or if the length is less than 0.
*/
public void addEdge(GeographicPoint from, GeographicPoint to, String roadName,
String roadType, double length) throws IllegalArgumentException {
//TODO: Implement this method in WEEK 3
if(roads.containsKey(from)) {
roads.get(from).add(to) ;
} else {
List curr1 = new LinkedList<GeographicPoint>() ;
curr1.add(to);
roads.put(from, (LinkedList<GeographicPoint>) curr1) ;
HashMap<GeographicPoint,GeographicPoint> curr = new HashMap<GeographicPoint,GeographicPoint>() ;
curr.put(from, to) ;
List<String> info = new ArrayList<String>() ;
info.add(roadName);info.add(roadType);info.add(Double.toString(length));
roadInfo.put(curr , (ArrayList<String>) info) ;
}
}
/** Find the path from start to goal using breadth first search
*
* #param start The starting location
* #param goal The goal location
* #return The list of intersections that form the shortest (unweighted)
* path from start to goal (including both start and goal).
*/
public List<GeographicPoint> bfs(GeographicPoint start, GeographicPoint goal) {
// Dummy variable for calling the search algorithms
Consumer<GeographicPoint> temp = (x) -> {};
return bfs(start, goal, temp);
}
/** Find the path from start to goal using breadth first search
*
* #param start The starting location
* #param goal The goal location
* #param nodeSearched A hook for visualization. See assignment instructions for how to use it.
* #return The list of intersections that form the shortest (unweighted)
* path from start to goal (including both start and goal).
*
*/
private List<GeographicPoint> getNeighbors(GeographicPoint curr){
List<GeographicPoint> answer = new ArrayList<GeographicPoint> () ;
for(GeographicPoint gp : roads.keySet()) {
if(curr==gp) {
answer = roads.get(gp) ;
}
}
System.out.println(answer);
return answer ;
}
public List<GeographicPoint> bfs(GeographicPoint start,
GeographicPoint goal, Consumer<GeographicPoint> nodeSearched)
{
// TODO: Implement this method in WEEK 3
// Hook for visualization. See writeup.
//nodeSearched.accept(next.getLocation());
if (start == null || goal == null) {
System.out.println("Start or goal node is null! No path exists.");
return new LinkedList<GeographicPoint>();
}
HashSet<GeographicPoint> visited = new HashSet<GeographicPoint>();
Queue<GeographicPoint> toExplore = new LinkedList<GeographicPoint>();
HashMap<GeographicPoint, GeographicPoint> parentMap = new HashMap<GeographicPoint, GeographicPoint>();
toExplore.add(start);
boolean found = false;
while (!toExplore.isEmpty()) {
GeographicPoint curr = toExplore.remove();
if (curr == goal) {
found = true;
break;
}
List<GeographicPoint> neighbors = getNeighbors(curr);
ListIterator<GeographicPoint> it = neighbors.listIterator(neighbors.size());
while (it.hasPrevious()) {
GeographicPoint next = it.previous();
nodeSearched.accept(next);
if (!visited.contains(next)) {
visited.add(next);
parentMap.put(next, curr);
toExplore.add(next);
}
}
}
if (!found) {
System.out.println("No path exists");
return new ArrayList<GeographicPoint>();
}
// reconstruct the path
LinkedList<GeographicPoint> path = new LinkedList<GeographicPoint>();
GeographicPoint curr = goal;
while (curr != start) {
path.addFirst(curr);
curr = parentMap.get(curr);
}
path.addFirst(start);
return path;
}
strong text
This is the code with comments could anyone figure what is wrong with my implementation

Saving enum values in a hashmap in a Class

I need to extend the class Room such that a room can contain zero or many characters by adding a field and a method in Room class that adds characters to rooms created. I already created an enum class called Character as can be seen below but I don't know how to use that in my Room class to add characters to a Room object.
I already created a HashMap field for storing the characters called charactersroom. The method in my code for adding characters is called addCharacter.
Room Class
public class Room
{
private String description;
private HashMap<Direction, Room> exits; // stores exits of this room.
private HashMap<Character, Room> charactersroom;
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* #param description The room's description.
* Pre-condition: description is not null.
*/
public Room(String description)
{
assert description != null : "Room.Room has null description";
this.description = description;
exits = new HashMap<Direction, Room>();
charactersroom = new HashMap<Character, Room>();
sane();
}
public void addCharacter(Character character)
{
}
/**
* Class invariant: getShortDescription() and getLongDescription() don't return null.
*/
public void sane()
{
assert getShortDescription() != null : "Room has no short description" ;
assert getLongDescription() != null : "Room has no long description" ;
}
/**
* Define an exit from this room.
* #param direction The direction of the exit.
* #param neighbor The room to which the exit leads.
* Pre-condition: neither direction nor neighbor are null;
* there is no room in given direction yet.
*/
public void setExit(Direction direction, Room neighbor)
{
assert direction != null : "Room.setExit gets null direction";
assert neighbor != null : "Room.setExit gets null neighbor";
assert getExit(direction) == null : "Room.setExit set for direction that has neighbor";
sane();
exits.put(direction, neighbor);
sane();
assert getExit(direction) == neighbor : "Room.setExit has wrong neighbor";
}
/**
* #return The short description of the room
* (the one that was defined in the constructor).
*/
public String getShortDescription()
{
return description;
}
/**
* Return a description of the room in the form:
* You are in the kitchen.
* Items: map
* Exits: north west
* #return A long description of this room
*/
public String getLongDescription()
{
return "You are " + description + ".\n" + getExitString();
}
/**
* Return a string describing the room's exits, for example
* "Exits: north west".
* #return Details of the room's exits.
*/
private String getExitString()
{
String returnString = "Exits:";
Set<Direction> keys = exits.keySet();
for(Direction exit : keys) {
returnString += " " + exit;
}
return returnString;
}
/**
* Return the room that is reached if we go from this room in direction
* "direction". If there is no room in that direction, return null.
* #param direction The exit's direction.
* #return The room in the given direction.
* Pre-condition: direction is not null
*/
public Room getExit(Direction direction)
{
assert direction != null : "Room.getExit has null direction";
sane();
return exits.get(direction);
}
}
Character enum class
public enum Character
{
LAURA("Laura",Item.SANDWICH),SALLY("Sally", Item.CRISPS),ANDY("Andy", Item.DRINK),ALEX("Alex", null);
private String charDescription;
private Item item;
private Character(String Chardescription, Item item) {
this.charDescription = charDescription;
this.item = item;
}
public String toString()
{
return charDescription+item;
}
/**
* Takes the indicated item from the character
* #return true if successful
*
*/
public boolean take(Item item)
{
if (item == this.item) {
this.item = null;
return true;
}
return false;
}
}
EDIT: This method is in my superclass Game for creating the rooms and their exits:
/**
* Create all the rooms and link their exits together.
*/
private void createRooms()
{
Room trafalgarSquare, chinatown, oxfordStreet, soho, coventGarden,
britishMuseum, stPancras, kingsCross, britishLibrary, leicesterSquare;
// create the rooms
trafalgarSquare = new Room("on Trafalgar Square");
chinatown = new Room("in Chinatown");
oxfordStreet = new Room("on Oxford Street");
soho = new Room("in Soho");
coventGarden = new Room("in Covent Garden");
britishMuseum = new Room("in the British Museum");
stPancras = new Room("in St Pancras");
kingsCross = new Room("in Kings Cross");
britishLibrary = new Room("in the British Library");
leicesterSquare = new Room("on Leicester Square");
// initialise room exits
kingsCross.setExit(Direction.WEST, stPancras);
stPancras.setExit(Direction.EAST, kingsCross);
stPancras.setExit(Direction.WEST, britishLibrary);
britishLibrary.setExit(Direction.EAST, stPancras);
britishLibrary.setExit(Direction.SOUTH, britishMuseum);
britishMuseum.setExit(Direction.NORTH, britishLibrary);
britishMuseum.setExit(Direction.WEST, oxfordStreet);
oxfordStreet.setExit(Direction.EAST, britishMuseum);
britishMuseum.setExit(Direction.SOUTH, coventGarden);
coventGarden.setExit(Direction.NORTH, britishMuseum);
oxfordStreet.setExit(Direction.SOUTH, soho);
soho.setExit(Direction.NORTH, oxfordStreet);
soho.setExit(Direction.SOUTH, chinatown);
chinatown.setExit(Direction.NORTH, soho);
chinatown.setExit(Direction.SOUTH, leicesterSquare);
leicesterSquare.setExit(Direction.NORTH, chinatown);
leicesterSquare.setExit(Direction.EAST, coventGarden);
coventGarden.setExit(Direction.WEST, leicesterSquare);
leicesterSquare.setExit(Direction.SOUTH, trafalgarSquare);
trafalgarSquare.setExit(Direction.NORTH, leicesterSquare);
currentRoom = stPancras; // start game at St Pancras
}

Easy way to add 3 different types of Objects to one ArrayList with one method?

This is a copy from an assignment I've done, so apologizes for some of the Norwegian commenting.
My question is:
I have an items ArrayList which holds Objects from the classes Item, Swords, Potions. (Potions & Swords are subclasses of Items). And I have 3 different methods to add these Objects to the ArrayList.
My question is Simple actually. Is there a (simple, I'm new and learning still) way for me to add all Items and Subclasses of Item to the ArrayList without having 3 different methods which look all alike. (addItem, addSword, addPotion), all close to the bottom of the code.
I'd want something like this ( not thought through, just wrote something)
public void addItem(String typeofItem){
item = new typeofItem;
items.add(item);
}
There is alot more to the code, but i feel like this is whats relevant.
public class Player
{
// Fields -------
private String name;
private String type;
private int health;
private ArrayList<Item> items = new ArrayList<>();
private Item item;
private Swords sword;
private Potions potion;
private Checker valid;
private int maxCarry;
private int gold;
private int currentWeight;
// ----------------
/**
* Klassens konstruktør. Players health vil alltid settes til 100.
*
* #param name Player navn
* #param type Player type
* #param goldValue Players starting gold
* #param setMaxWeight Players max carry weight
*/
public Player (String name, String type, int goldValue, int setMaxWeight) {
valid = new Checker(); // Creates a checker object to do String and integer checks
this.name = valid.checkString(name); // Setter player name, etter å ha sjekka at den ikke er tom
this.type = checkType(type); // Setter type, etter å ha processet den
health = 100; // Health skal alltid starte som 100
maxCarry = valid.checkInt(setMaxWeight); // Sets max carry weight
currentWeight = 0; // Start vekten til player
gold = valid.checkInt(goldValue); // setter goldbeholding etter å ha sjekka at den ikke er negativ
}
/**
* En metode for å selge ett Item objekt, reduserer gold og øker weight ved kjøp.
*
* #param item Item object to sell
*/
private void buyItem(Item item)
{
// Temporary values given from items methods getweight and getvalue to be used in a mutation
int tempWeight;
int tempValue;
tempWeight = item.getWeight();
tempValue = item.getValue();
// Checks if the item meets te conditions to be bought (enough gold, and can be carried)
if (checkConditions(tempValue, tempWeight)) {
// Adds the item to ArrayList if conditions met and updates gold and weight
items.add(item);
currentWeight += tempWeight;
gold -= tempValue;
}
}
/**
* Method to calculate if given value and weight is accepted to perform a purchase (total gold > 0 && total weight < maxWeight)
*
* #param value Gold value of item
* #param weight Weight of item
* #return boolean Returns true if conditions met
*/
private boolean checkConditions(int value, int weight)
{
if (!(gold >= value))
{
System.out.println("You don't have enough gold!");
return false;
} else {
if (!(weight + currentWeight <= maxCarry)){
System.out.println("You'll be too heavy carry this item!");
return false;
} else {
// All conditions met
return true;
}
}
}
/**
* Adds an item to player inventory (uses method buyItem to process the item as a purchase)
*
* #param itemName String to name item
* #param itemDesc String to describe item
* #param itemValue int to declare items value
* #param itemWeight int to declare items Weight
* #param itemAction String to give item an action
*/
public void addItem(String itemName, String itemDesc, int itemValue, int itemWeight, String itemAction)
{
// A Player generated item, which needs all parameters to specify it
item = new Item(itemName, itemDesc, itemValue, itemWeight, itemAction);
buyItem(item);
}
/**
* Randomly generates a Sword object and adds it to players inventory (uses buyItem to process)
* #see Swords#Swords
*/
public void addSword()
{
sword = new Swords();
buyItem(sword);
}
/**
* Randomly generates a Potion object and adds it to players inventory (uses buyItem to process)
* #see Potions#Potions
*/
public void addPotion()
{
potion = new Potions();
buyItem(potion);
}
You can create something called a Factory class. A factory class's responsibility is to generate instances of a type of item for you.
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm
Essentially you wrap the method you talk about in a class and return a new instance of that object.
public class ItemFactory{
public static Item addItem(String typeofItem){
switch(typeofItem){
case "Sword":
return new Sword();
case "Potion":
return new Potion();
...
default:
//put any code here that is like the "else" of an if-else block
return null;
}
}
}
Then when you need to add a new item of a specific type:
buyItem(ItemFactory.addItem("Sword"));

private method call between classes

trying to get areasConnected to display. As you can see I have attemped (poorly I know) to substitute this method with the nextArea method. Will post the GameWorld class below this one. Please note that I DO NOT want someone to do the work for me, just point me in the right direction.
/**
* Auto Generated Java Class.
*/
import java.util.Scanner;
public class WereWolfenstein2D {
GameWorld gameOne = new GameWorld(true);
private boolean tracing = false;
Scanner sc = new Scanner(System.in);
String input, answer, restart;
int walk, current;
char area;
public void explain() {
System.out.print("You are a hunter, defend the village and capture the Werewolf by shooting it three times. ");
System.out.println("If you get bitten visit the village to be cured. " +
"If you get bitten twice you'll turn." +
"If none of the town folk survive, you lose. " +
"Now choose how what circumstances you're willing to work in.");
}
public void pickDifficulity(){
{
System.out.println("Easy, Normal or Hard?");
input = sc.nextLine();
input = input.toUpperCase();
if (input.equals("EASY")){
System.out.println(Difficulty.EASY);
}
else if (input.equals("NORMAL")) {
System.out.println(Difficulty.NORMAL);
}
else if (input.equals("HARD")) {
System.out.println(Difficulty.HARD);
}
}
}
public void preMove(){
System.out.println("current stats");
// no. of actions until dawn
gameOne.checkForDawn();
// current population
gameOne.getVillagePopulation();
// if they can hear village
gameOne.isVillageNear();
// if not bitten:
gameOne.getShotCount();
// current area no.
gameOne.getCurrentArea();
// number of connecting areas
// gameOne.nextArea(char direction);
//gameOne.areasConnected(int s1, int s2);
// no of times werewolf shot
// no. of bullets left
gameOne.getShotCount();
// if the player can smell the wolf
gameOne.werewolfNear();
}
public void pickMove(){
System.out.print("walk shoot, quit or reset?");
answer = sc.nextLine();
//walk
//if area not connected: alert
//if into village: alert that they are healed
//if containing wolf: altert they are bitten, if already bitten game ends
switch(answer) {
case "walk": System.out.println("Pick a direction to walk in south(s), east(e), north(n), west(w)");
current = gameOne.getCurrentArea(); //current area they are in
char direction = sc.next().charAt(current); //direction they wish to travel
// char area = sc.next().charAt(current);
char area1 = 's';
char area2 = 'e';
char area3 = 'n';
char area4 = 'w';
System.out.println("the area to the south is: " + gameOne.nextArea(area1));
System.out.println("the area to the east is: " + gameOne.nextArea(area2));
System.out.println("the area to the north is: " + gameOne.nextArea(area3));
System.out.println("the area to the west is: " + gameOne.nextArea(area4));
System.out.println(current +"<< >>" + direction);
System.out.println("pick again");
int newcurrent = direction;
direction = sc.next().charAt(newcurrent);
System.out.println(newcurrent + "<< new >>" + direction);
break;
case "shoot":
break;
case "quit": System.out.print("would you like to start again? (yes/no)");
restart = sc.nextLine();
if (restart.equals("yes")) {
gameOne.reset();
}
else {
System.out.println("Thanks for playing");
}
break;
case "reset": //gameOne.reset();
this.pickDifficulity();
break;
}
}
public void play() {
this.explain();
this.pickDifficulity();
this.preMove();
this.pickMove();
// gameOne.reset();
}
public void setTracing(boolean onOff) {
tracing = onOff;
}
public void trace(String message) {
if (tracing) {
System.out.println("WereWolfenstein2D: " + message);
}
}
}
GAMEWORLD CLASS>>>
public class GameWorld {
// Final instance variables
public final int NIGHT_LENGTH = 3; // three actions until dawn arrives (day is instantaneous)
private final int MAX_SHOTS_NEEDED = 3; // successful hits required to subdue werewolf
//This map is _deliberately_ confusing, although it actually a regular layout
private int[] east = {1,2,0,4,5,3,7,8,6}; // areas to east of current location (index)
private int[] west = {2,0,1,5,3,4,8,6,7}; // areas to west of current location (index)
private int[] north = {6,7,8,0,1,2,3,4,5}; // areas to north of current location (index)
private int[] south = {3,4,5,6,7,8,0,1,2}; // areas to south of current location (index)
private int numAreas = south.length; // number of areas in the "world"
// Non-final instance variables
private int currentArea; // current location of player
private int villagePos; // area where the village is located
private int wolfPos; // area where the werewolf can be found
private Difficulty level; // difficulty level of the game
private int villagerCount; // number of villagers remaining
private int stepsUntilDawn; // number of actions until night falls
private boolean isBitten; // is the player currently bitten and in need of treatment?
private int hitsRemaining; // number of shots still needed to subdue the werewolf
private Random generator; // to use for random placement in areas
private boolean tracing; // switch for tracing messages
/**
* Creates a game world for the WereWolfenstein 2D game.
* #param traceOnOff whether or not tracing output should be shown
*/
public GameWorld(boolean traceOnOff) {
trace("GameWorld() starts...");
generator = new Random();
generator.setSeed(101); //this default setting makes the game more predictable, for testing
setTracing(traceOnOff); //this may replace random number generator
trace("...GameWorld() ends");
}
/**
* Returns the number of the current area.
* #return which area number player is within
*/
public int getCurrentArea() {
trace("getCurrentArea() starts... ...and ends with value " + currentArea);
return currentArea;
}
/**
* Returns the number of shot attempts, formatted as "total hits/total required"
* #return the fraction of shots that have hit the werewolf (out of the required number of hits)
*/
public String getShotCount() {
String count; // formatted total
trace("getShotCount() starts...");
count = (MAX_SHOTS_NEEDED - hitsRemaining) + "/" + MAX_SHOTS_NEEDED;
trace("getShotCount() ...ends with value " + count);
return count;
}
/**
* Returns the current number of villagers.
* #return the villager count, >= 0
*/
public int getVillagePopulation() {
return villagerCount;
}
/**
* Returns the number of actions remaining until dawn arrives.
* #return actions remaining until dawn event
*/
public int getActionsUntilNight() {
return stepsUntilDawn;
}
/**
* Randomly determines a unique starting location (currentArea), village
* position (villagePos) and werewolf position (wolfPos).
* #param difficulty - the difficulty level of the game
* #return the starting location (area)
*/
public int newGame(Difficulty difficulty) {
trace("newGame() starts...");
level = difficulty;
//determine village location and initialise villagers and night length
villagePos = generator.nextInt(numAreas);
stepsUntilDawn = NIGHT_LENGTH;
villagerCount = level.getVillagerCount();
// determine player's position
if (level.getPlayerStartsInVillage()) {
//place player in village
currentArea = villagePos;
} else {
//pick a random location for player away from the village
do {
currentArea = generator.nextInt(numAreas);
} while (currentArea == villagePos);
}
trace("player starts at " + currentArea);
// determine werewolf's position
trace("calling resetTargetPosition()");
resetWolfPosition();
// define player's status
trace("player is not bitten");
isBitten = false;
trace("werewolf is not hit");
hitsRemaining = MAX_SHOTS_NEEDED;
trace("...newGame() ends with value " + currentArea);
return currentArea;
}
/** Randomly determines a unique location for werewolf (wolfPos). */
private void resetWolfPosition() {
int pos; // werewolf position
trace("resetWolfPosition() starts...");
pos = generator.nextInt(numAreas);
while (pos == currentArea || pos == villagePos) {
trace("clash detected");
// avoid clash with current location
pos = generator.nextInt(numAreas);
}
wolfPos = pos;
trace("werewolf position is " + wolfPos);
trace("...resetWolfPosition() ends");
}
/**
* Returns the nearness of the werewolf.
* #return Status of werewolf's location
* BITTEN: if player is currently bitten (and delirious)
* NEAR: if werewolf is in a connected area
* FAR: if werewolf is elsewhere
*/
public Result werewolfNear() {
trace("werewolfNear() starts");
if (isBitten) {
trace("werewolfNear(): player is still delirious from a bite so cannot sense nearness of werewolf");
return Result.BITTEN;
}
trace("werewolfNear() returning result of nearnessTo(" + wolfPos + ")");
return nearnessTo(wolfPos);
}
/**
* Returns true if the village is near the player (in an adjacent area),
* false otherwise.
* #return true if the player is near (but not in) the village, false otherwise.
*/
public boolean isVillageNear() {
trace("villageNear() starts and returns result of nearnessTo(" + villagePos + ") == Result.NEAR");
return nearnessTo(villagePos) == Result.NEAR;
}
/**
* Returns the nearness of the player to the nominated area.
* #param area the area (werewolf or village) to assess
* #return Nearness of player to nominated area
* NEAR: if player is adjacent to area
* FAR: if player is not adjacent to the area
*/
private Result nearnessTo(int area) {
Result closeness; // closeness of player to area
trace("nearnessTo() starts...");
if ((east[currentArea] == area) ||
(west[currentArea] == area) ||
(north[currentArea] == area) ||
(south[currentArea] == area))
{
// player is close to area
closeness = Result.NEAR;
trace("area is close");
} else {
// player is not adjacent to area
closeness = Result.FAR;
trace("area is far");
}
trace("...nearnessTo() ends with value " + closeness);
return closeness;
}
/**
* Try to move the player to another area. If the move is not IMPOSSIBLE
* then the number of actions remaining before dawn arrives is decremented.
* #param into the area to try to move into
* #return Result of the movement attempt
* SUCCESS: move was successful (current position changed)
* VILLAGE: move was successful and player has arrived in the village (and is not longer bitten)
* BITTEN: move was successful but player encountered the werewolf
* FAILURE: move was successful but already bitten player encountered the werewolf again
* IMPOSSIBLE: move was impossible (current position not changed)
*/
public Result tryWalk(int into) {
Result result; // outcome of walk attempt
trace("tryWalk() starts...");
if (areasConnected(currentArea, into)) {
trace("move into area " + into );
currentArea = into;
if (currentArea != wolfPos) {
// werewolf not found
trace("werewolf not encountered");
result = Result.SUCCESS;
if (currentArea == villagePos) {
isBitten = false;
result = Result.VILLAGE;
}
} else {
// werewolf encountered
if (isBitten) {
trace("werewolf encountered again");
result = Result.FAILURE;
} else {
// not bitten
trace("werewolf encountered");
result = Result.BITTEN;
isBitten = true;
resetWolfPosition();
}
}
stepsUntilDawn--; //one more action taken
} else { // area not connected
trace("move not possible");
result = Result.IMPOSSIBLE;
}
trace("...tryWalk() ends with value " + result);
return result;
}
/**
* Try to shoot a silver bullet at the werewolf from the current area.
* If the shot is not IMPOSSIBLE then the number of actions remaining
* before dawn arrives is decremented.
* #param into the area to attempt to shoot into
* #return status of attempt
* CAPTURED: werewolf has been subdued and captured
* SUCCESS: werewolf has been hit but is not yet captured
* VILLAGE: the shot went into the village and a villager has died
* FAILURE: werewolf not present
* IMPOSSIBLE: area not connected
*/
public Result shoot(int into) {
Result result; // outcome of shooting attempt
trace("shoot() starts...");
if (areasConnected(currentArea, into)) {
// area connected
trace("shoot into area " + into );
if (into == villagePos) {
result = Result.VILLAGE;
villagerCount--;
trace("shot into village");
} else if (into != wolfPos) {
// not at werewolf location (but at least didn't shoot into the village!)
result = Result.FAILURE;
trace("werewolf not present");
} else {
// at werewolf location
hitsRemaining--;
if (hitsRemaining == 0) {
// last hit required to subdue the werewolf
trace("werewolf subdued and captured");
result = Result.CAPTURED;
} else {
// not the last shot
result = Result.SUCCESS;
if (level.getWolfMovesWhenShot()) {
resetWolfPosition();
}
trace("werewolf found but not yet captured");
}
}
stepsUntilDawn--; //one more action taken
} else {
// not at valid location
result = Result.IMPOSSIBLE;
trace("area not present");
}
trace("...shoot() ends with value " + result);
return result;
}
/**
* Checks if there are no more actions left until dawn arrives. If dawn is
* here then decrements the number of villagers, repositions the werewolf
* and resets the number of actions until dawn arrives again. Returns true
* if dawn occurred, false if it did not.
* #return true if dawn just happened, false if has not yet arrived
*/
public boolean checkForDawn() {
if (stepsUntilDawn == 0) {
if (villagerCount > 0) { //dawn may arrive after shooting the last villager
villagerCount--;
}
stepsUntilDawn = NIGHT_LENGTH;
resetWolfPosition();
return true;
}
return false;
}
/**
* Returns true if areas s1 and s2 are connected, false otherwise.
* Also returns false if either area is an invalid area identifier.
* #param s1 the first area
* #param s2 the second area
* #return true if areas are connected, false otherwise
*/
private boolean areasConnected(int s1, int s2) {
if (Math.min(s1, s2) >= 0 && Math.max(s1, s2) < numAreas) { //valid areas...
//...but are they connected?
return east[s1] == s2 || north[s1] == s2 || west[s1] == s2 || south[s1] == s2;
}
//Either s1 or s2 is not a valid area identifier
return false;
}
/**
* Determine ID number of an adjacent area given its direction from the
* current area.
* #param direction the direction to look (n for north, e for east, s for south, w for west)
* #return number of the area in that direction
* #throws IllegalArgumentException if direction is null
*/
public int nextArea(char direction) {
int nextIs; // area number of area in indicated direction
//Valid values
final char N = 'n', E = 'e', S = 's', W = 'w';
trace("nextArea() starts...");
// examine adjacent areas
switch (direction) {
case N: trace("determining number of area to the north");
nextIs = north[currentArea];
break;
case E: trace("determining number of area to the east");
nextIs = east[currentArea];
break;
case S: trace("determining number of area to the south");
nextIs = south[currentArea];
break;
case W: trace("determining number of area to the west");
nextIs = west[currentArea];
break;
default: throw new IllegalArgumentException("Direction must be one of " + N + ", " + E + ", " + S + " or " + W);
}
trace("...nextArea() ends with value for '" + direction + "' of " + nextIs);
return nextIs;
}
/** Resets all game values. */
public void reset() {
trace("reset() starts...");
// reset all game values
trace("resetting all game values");
newGame(level); //start a new game with the same difficulty
trace("...reset() ends");
}
/**
* Turn tracing messages on or off. If off then it is assumed that
* debugging is not occurring and so a new (unseeded) random number
* generator is created so the game is unpredictable.
* #param shouldTrace indicates if tracing messages should be displayed or not
*/
public void setTracing(boolean shouldTrace) {
if (! shouldTrace) { // not tracing so get an unseeded RNG
generator = new Random();
}
tracing = shouldTrace;
}
/**
* Prints the given tracing message if tracing is enabled.
* #param message the message to be displayed
*/
public void trace(String message) {
if (tracing) {
System.out.println("GameWorld: " + message);
}
}
}
You can use reflection. Actually, it's the only way out if you want to directly access the private methods/fields of an object or a class.

sudoku game constructor

I am having trouble initializing a parameterless constructor with a defined game. Somehow it keeps on returning null if I use a getter method to return the game. Can anyone tell me what would be the best method to initialize the game?
Currently I'm calling a method from within another class which has a static method but it doesn't seem to work because it gives a null value if I get the game.
This is how I this game to be:
{{7,8,1,0,0,4,0,0,6},
{2,0,9,3,6,0,1,0,0},
{6,0,0,0,9,0,8,0,0},
{0,0,0,0,3,5,0,0,0},
{3,5,0,0,0,0,0,1,9},
{0,0,0,4,2,0,0,0,0},
{0,0,3,0,1,0,0,0,8},
{0,0,7,0,8,3,4,0,1},
{9,0,0,6,0,0,5,7,3}},
public class SudokuPlayer
{
private int [][] game;
public enum CellState { EMPTY, FIXED, PLAYED };
private CellState[][] gamestate;
private static final int GRID_SIZE=9;
public SudokuPlayer()
{
int[][] copy= SudokuGames.getGame(4);
int size = copy.length;
int[][] game = new int[GRID_SIZE][GRID_SIZE];
for ( int row = 0; row < size; row++)
{
for ( int col =0; col < size; col++)
{
game[row][col] = copy[row][col];
}
}
}
public int[][] getGame()
{
return game;
}
}
here is the method from a diferent class im calling:
public class SudokuGames {
public static final int [][][] GAMES = {
// Game 0 VE - DEFAULT 30 squares filled
{{5,3,0,0,7,0,0,0,0},
{6,0,0,1,9,5,0,0,0},
{0,9,8,0,0,0,0,6,0},
{8,0,0,0,6,0,0,0,3},
{4,0,0,8,0,3,0,0,1},
{7,0,0,0,2,0,0,0,6},
{0,6,0,0,0,0,2,8,0},
{0,0,0,4,1,9,0,0,5},
{0,0,0,0,8,0,0,7,9}},
// Game 1 VE
{{8,0,1,0,3,7,0,5,6},
{0,0,0,9,0,0,0,0,7},
{6,0,3,0,1,2,0,9,0},
{0,2,0,0,0,0,7,0,3},
{3,0,0,0,2,0,0,0,9},
{1,0,9,0,0,0,0,8,0},
{0,3,0,2,7,0,4,0,1},
{7,0,0,0,0,6,0,0,0},
{5,6,0,1,9,0,3,0,8}},
// Game 2 VE
{{0,9,0,0,3,0,1,4,0},
{7,0,3,0,0,4,0,0,8},
{5,0,0,6,0,7,0,2,0},
{0,7,4,5,0,2,9,0,0},
{1,0,0,0,0,0,0,0,2},
{0,0,9,1,0,8,4,6,0},
{0,5,0,7,0,9,0,0,6},
{4,0,0,2,0,0,5,0,1},
{0,8,6,0,5,0,0,7,0}},
// Game 3 VE
{{0,0,9,7,3,0,5,2,6},
{0,0,5,0,2,0,8,0,0},
{6,0,8,0,0,0,0,4,7},
{0,0,0,0,0,9,0,6,2},
{0,4,0,6,0,3,0,8,0},
{8,9,0,5,0,0,0,0,0},
{2,6,0,0,0,0,1,0,8},
{0,0,7,0,1,0,6,0,0},
{9,5,1,0,6,4,2,0,0}},
// Game 4 VE
{{7,8,1,0,0,4,0,0,6},
{2,0,9,3,6,0,1,0,0},
{6,0,0,0,9,0,8,0,0},
{0,0,0,0,3,5,0,0,0},
{3,5,0,0,0,0,0,1,9},
{0,0,0,4,2,0,0,0,0},
{0,0,3,0,1,0,0,0,8},
{0,0,7,0,8,3,4,0,1},
{9,0,0,6,0,0,5,7,3}},
// Game 5 E
{{0,0,0,9,1,0,0,0,2},
{5,0,0,0,0,0,0,0,0},
{3,0,0,5,4,0,0,6,8},
{0,4,2,7,0,0,3,0,5},
{0,0,3,4,5,6,2,0,0},
{1,0,9,0,0,8,7,4,0},
{8,1,0,0,7,5,0,0,4},
{0,0,0,0,0,0,0,0,1},
{9,0,0,0,8,4,0,0,0}},
// Game 6 E
{{0,0,0,1,0,7,0,9,0},
{0,0,0,4,9,0,3,0,0},
{6,0,0,0,3,0,4,1,0},
{4,0,5,0,0,0,0,3,0},
{8,2,0,0,0,0,0,5,4},
{0,3,0,0,0,0,2,0,6},
{0,1,4,0,7,0,0,0,5},
{0,0,8,0,2,5,0,0,0},
{0,6,0,8,0,1,0,0,0}},
// Game 7 E
{{0,0,2,8,0,7,5,0,0},
{6,0,0,0,0,0,0,0,4},
{0,8,0,0,6,0,0,7,0},
{1,3,0,4,0,9,0,2,5},
{0,0,0,0,0,0,0,0,0},
{4,5,0,7,0,1,0,6,8},
{0,6,0,0,3,0,0,9,0},
{5,0,0,0,0,0,0,0,7},
{0,0,1,6,0,4,2,0,0}}
}; //End
/**
* getGame(int gameID) returns a a Sudoku game as int [][]
* as specified by the gameID. If the gameID is outside the
* list of possible games, null is returned.
* #param gameID number of game to be played
* #return int[][] a game to be played
*/
public static int [][] getGame (int gameID) {
/** A little dangerous. A copy of the reference to the original array
* is returned. Not a copy of the array.
**/
if (gameID >= 0 && gameID < GAMES.length) {
return GAMES[gameID];
}
else {
return null;
}
}
}
You are hiding the instance variable.
Change the following
int[][] game = new int[GRID_SIZE][GRID_SIZE];
to
game = new int[GRID_SIZE][GRID_SIZE];

Categories