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];