Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 days ago.
Improve this question
I'm writing a Chess plugin with Spigot, and I can't figure out why the GUI isn't working as I expected it to.
I've been trying to create a Chess board using the Minecraft inventory GUI, and I've managed to create a chequered pattern so far. For the time being, I've just been trying to leave spaces blank if a piece is at those given coordinates, however I've only managed to leave one space blank at a time, and at the wrong coordinates. I mostly want to figure out why only one space is being left blank though, instead of the top two and bottom two rows being blank as they should be.
I believe two classes in particular are the culprit, the "Game" and "GameGUI" classes. "Game" of course takes charge of the implementation of the actual game logic, and the "GameGUI" class handles player interactions.
Here is the constructor from the "Game" class:
public Game(GamePlayer player1, GamePlayer player2, String instance) {
Game.player1 = player1;
Game.player2 = player2;
Game.instance = instance;
Piece[][] player1Pieces = new Piece[8][6];
Piece[][] player2Pieces = new Piece[8][6];
setUpPieces(player1, player1Pieces);
setUpPieces(player2, player2Pieces);
Game.pieces.put(player1, player1Pieces);
Game.pieces.put(player2, player2Pieces);
}
So, as can be seen above, when a game is created, it gives each of the players a two-dimensional array of pieces. If you think it's odd to use a two-dimensional array for this purpose, I'm using it because I was trying to fix the problem that I'm currently facing. I was originally just using a List, then I tried an array of Lists, and now I'm on to a two-dimensional array. Of course, now there's the possibility of a piece being null, but I run a check in the GameGUI class if the piece is null, as you'll see later on in this post.
I am putting each type of Chess piece in its own array within the two-dimensional array, like so:
public static void setUpPieces(GamePlayer player, Piece[][] pieces) {
pieces[0] = setUpPawns(player);
pieces[1] = setUpRooks(player);
pieces[2] = setUpKnights(player);
pieces[3] = setUpBishops(player);
pieces[4] = setUpQueen(player);
pieces[5] = setUpKing(player);
}
Each of those methods looks roughly like this:
public static Piece[] setUpPawns(GamePlayer player) {
Piece[] initialSetup = new Piece[8];
String color = player.getColor();
int y1 = color.equals("WHITE") ? 2 : 7;
for (int i = 1; i <= 8; i++) {
initialSetup[i - 1] = new Piece(i, y1, new PieceType("PAWN"), color);
}
return initialSetup;
}
I thought it might help to mention that absolutely every variable in the "Game" class is static, as well.
So here's the GUI code, which ChatGPT helped me make:
public void initializeItems() {
Piece[][] pieces = Game.getPieces(game.getPlayer1());
Piece[][] opponentPieces = Game.getPieces(game.getPlayer2());
for (int i = 0; i < 72; i++) {
if (i % 9 < 8) {
int x = i % 9;
int y = 8 - i / 9;
boolean isOccupied = false;
for (Piece[] pieceArray : pieces) {
for (Piece piece : pieceArray) {
if (piece != null) {
if (piece.getX() == x && piece.getY() == y) {
System.out.println(piece.getType().getName());
isOccupied = true;
break;
}
}
}
}
for (Piece[] pieceArray : opponentPieces) {
for (Piece piece : pieceArray) {
if (piece != null) {
if (piece.getX() == x && piece.getY() == y) {
System.out.println(piece.getType().getName());
isOccupied = true;
break;
}
}
}
}
if (!isOccupied) {
if ((x + y) % 2 == 0) {
if (i < 54) {
inv.setItem(i, new ItemStack(WHITE_STAINED_GLASS_PANE));
} else {
pInv.setItem(i - 45, new ItemStack(WHITE_STAINED_GLASS_PANE));
}
} else {
if (i < 54) {
inv.setItem(i, new ItemStack(BLACK_STAINED_GLASS_PANE));
} else {
pInv.setItem(i - 45, new ItemStack(BLACK_STAINED_GLASS_PANE));
}
}
}
} else {
if (i < 54) {
inv.setItem(i, new ItemStack(GRAY_STAINED_GLASS_PANE));
} else {
pInv.setItem(i - 45, new ItemStack(GRAY_STAINED_GLASS_PANE));
}
}
}
}
If anyone can think of a solution to this, I would greatly appreciate it! Thanks for taking the time to read this post.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am trying to create a simple TicTacToe game but I am having trouble having the program recognize a row of x's.
If you look at the following line of code:
public void run() {
setFont("Helvetica-40");
fillArray();
checkWinner();
run();
}
//fill array:
public void fillArray() {
for(int row = 0; row<3; row++) {
String fill = readLine("");
for(int col=0; col<3;col++) {
char xo = fill.charAt(row);
String xoString = Character.toString(xo);
ticTac[row][col] = xoString;
}
}
}
public boolean checkWinner() {
// array[row][col]
if (ticTac[0][0].equals("x") && ticTac[0][1].equals("x") && ticTac[0][2].equals("x")) {
println("Player X wins!");
return true;
} else
println("no x");
return false;
}
String[][] ticTac = new String[3][3];
}
I think you have a mistake, you have to change one of these two things :
1.
if (ticTac[0][0].equals("x") && ticTac[0][1].equals("x") && ticTac[0][2].equals("x"))
to
if( ticTac[0][0].equals("x") && ticTac[1][0].equals("x") && ticTac[2][0].equals("x"))
or
2.
char xo = fill.charAt(row);
to
char xo = fill.charAt(col);
just one of them, it depend on your design
I was trying to make a battleship clone but ended up running into one problem. I made a BattleShipGrid class that had two 2D arrays, one for each player. The array called p1/p2grid holds their ship and the locations the other player has shot at. The second array called p1/p2fire is the one that shows only where they shot, and not where the enemy ship is, though they can see where they’ve hit it. Im having a problem where I want to print player 1's fire grid after them firing to show if they missed or not. But each time I print player 1's fire grid it still sets everything as 0, like they never even fired on anything. I made 1 a miss and 3 a hit and 2 to represent the location of a ship.
Here is my code in my main:
boolean player1Turn = true;
if (player1Turn) {
fire = grid.fireAtPlayerTwo(x, y);
} else {
fire = grid.fireAtPlayerOne(x, y);
}
if (fire == 0) {
System.out.println("Miss!");
} else if (fire == 2) {
System.out.println("=====================================");
System.out.println("Hit!");
if (player1Turn) {
System.out.println(grid.printP1Fire());/* printing regular old empty array filled with zeros like when a player just starts and hasn't fired on anything.*/
} else {
System.out.println(grid.printP2Fire());
}
System.out.println("=====================================");
}
Here is my methods that I called when firing on the other player( fire at player one and fire at player two do the same thing but are named different ) :
int Empty = 0;
public int fireAtPlayerTwo ( int x, int y)
{
int result = p2Grid[x][y];
if (result == EMPTY) {
p1Grid[x][y] = MISS;/* This should change the value in p1Grid at that coordinate but it is not refelcting back in the main*/
p2Fire[x][y] = MISS;
} else if (result == SHIP) {
p1Grid[x][y] = HIT;
p2Fire[x][y] = HIT;
}
return result;
}
Note: I came across the question below and I wanted to generalize the problem and implement it, but it turns out that it is not easy. This question is making me crazy. This is NOT a Homework question just a curiosity.
Question
There are three containers whose sizes are 10 pints, 7 pints and 4 pints respectively. The 7-pint and 4-pint containers start out full of water, but the 10-pint container is initially empty.
Since there are no marks on the containers, you can pour the contents of one container into another and stop under the following conditions:
the source container is empty
the destination container is full
What sequence of moves should you make if you want to isolate exactly 2 pints of water?
Source: page 102, Question 3.8
Solution
Answering that question is easy using directed graph data structure where nodes contain tuples to represent a certain state.
We start from the initial state (node), and then we create a node representing a possible next state, and we connect it to initial node, and then run BFS to find the shortest path.
Pattern of each state (or node): <10-pint container, 7-pint container, 4-pint container>
Initial state or node: <0, 7, 4>.
The nodes connected to the initial state (or node): <7, 0, 4>, <4, 7, 0>, as you can see from the picture.
Generalised Question
But suppose if want to generalized the problem, suppose we have three containers whose sizes are x, y and z pints respectively such that x >= y >= z.
The y-pint and z-pint containers start out full of water but the x-pint container is initially empty.
What sequence of moves should you make if you want to isolate exactly a pints of water?
Suggesting a Solution to Generalised Version
Here (DropBox, GitHub) is my source code so far.
Here are two important method in main class. They fill the graph based on all possibilities, and it also makes sure there is no duplicate node.
public static void fillGraph(int x, int y, int z) {
TupleContainer initialState = new TupleContainer(x, y, z);
TupleContainer currentState = initialState;
Iterator<TupleContainer> it, it_1, it_2, it_3;
Graph.addNode(initialState);
it = addAdjacentEdgesToTuple(currentState).iterator();
while (it.hasNext()) {
it_1 = addAdjacentEdgesToTuple(it.next()).iterator();
while (it_1.hasNext()) {
it_2 = addAdjacentEdgesToTuple(it.next()).iterator();
while (it_2.hasNext()) {
it_3 = addAdjacentEdgesToTuple(it.next()).iterator();
while (it_3.hasNext()) {
addAdjacentEdgesToTuple(it.next()).iterator();
}
}
}
}
public static Collection<TupleContainer> addAdjacentEdgesToTuple(
TupleContainer currentState) {
TupleContainer tempTupleContainer;
Collection<TupleContainer> CollectionLevel;
Iterator<TupleContainer> it;
CollectionLevel = currentState.MixUpContainers();
it = CollectionLevel.iterator();
while (it.hasNext()) {
tempTupleContainer = it.next();
if (graphContains(tempTupleContainer) != null)
Graph.addNode(tempTupleContainer);
else
tempTupleContainer = graphContains(tempTupleContainer);
Graph.addEdge(currentState, tempTupleContainer);
}
return CollectionLevel;
}
My Question
My code just fills the graph to depth of 4, but how can I set depth and make it run recursively or how make it run until all possibilities are taken to consideration without going into infinite loop. What is the algorithm to this generalized question?
Hm ... there may be better algorithms, but if you simply want arbitrarily deep recursion without going into endless loops, you can use a breadth first search that visits each node only once, i.e. if it hasn't already been visited:
public class Test {
public static void main(String[] args) throws Exception {
State initialState = new State(null, 0, 7, 4);
Set<State> reached = new HashSet<>();
Queue<State> pending = new ArrayDeque<>();
pending.add(initialState);
while (!pending.isEmpty()) {
State state = pending.remove();
if (isGoal(state)) {
printPathTo(state);
return;
}
for (State s : state.adjacentStates()) {
if (!reached.contains(s)) {
reached.add(s);
pending.add(s);
}
}
}
System.out.println("There appears to be no solution.");
}
private static boolean isGoal(State state) {
for (int a : state.content) {
if (a == 2) {
return true;
}
}
return false;
}
private static void printPathTo(State state) {
if (state != null) {
printPathTo(state.previous);
System.out.println(state);
}
}
}
class State {
final static int[] capacity = { 10, 7, 4 };
final int[] content;
final State previous;
public State(State previous, int... content) {
this.content = content;
this.previous = previous;
}
Iterable<State> adjacentStates() {
List<State> result = new ArrayList<>();
for (int i = 0; i < content.length; i++) {
for (int j = 0; j < content.length; j++) {
if (i != j) {
int[] newContent = Arrays.copyOf(content, content.length);
int movedQuantity = Math.min(content[i], capacity[j] - content[j]);
newContent[i] -= movedQuantity;
newContent[j] += movedQuantity;
result.add(new State(this, newContent));
}
}
}
return result;
}
#Override
public int hashCode() {
return Arrays.hashCode(content);
}
#Override
public boolean equals(Object obj) {
return Arrays.equals(content, ((State) obj).content);
}
#Override
public String toString() {
return Arrays.toString(content);
}
}
You can also try iterative deepening search, we were given a demonstration of it working on the same problem in uni and it worked well.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am writing a TicTacToe game, and it repeatedly prompts the user for a move. It is asking for a selection more than 9 times and I am not sure why.
My design has a 2-dimensional array to store information about the current state of the board, use JOptionPane to ask users for selection of the board (1 for top left, 2 for top middle, 3 for top right, 4 for middle left, etc). After every move, output into the console the current board. If a spot is already used, prompt the user again. (There is no need for a winner check, as we were told to do this another time.
Here is my entire code:
import javax.swing.JOptionPane;
// Basic TicTacToe game.
public class TicTacToe1 {
public static void main(String[] args){
// Hello there!
Object[] options = { "I'm ready to play!",};
Object[] options2 = { "Select another number.",};
JOptionPane.showOptionDialog(null,"To play TicTacToe, use the numbers 1 to 9 to choose where you place a mark. Are you ready?","TicTacToe1",
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
// Define the board.
char board[][] = new char[3][3];
// Zero out the board.
for(int a=0; a<3; a++) {
for(int b=0; b<3; b++) {
board[a][b] = ' ';
}
}
// Print an initial, clean board.
print(board);
// Use a for loop to ask for the selection and nest the selector into it.
for(int i=1; i<10 ; i++) {
if ((i%2) == 1) {
boolean goahead = true;
while (goahead) {
int selection = Integer.parseInt(JOptionPane.showInputDialog(null,"Where do you want to place an X?"));
if ((board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3]=='X') || (board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3]=='O')) {
JOptionPane.showOptionDialog(null,"I'm sorry, the number "+selection+" spot is already being used.","TicTacToe1",
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options2, options2[0]);
} else {
goahead = false;
board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3] = 'X';
print(board);
}
}
}
if ((i%2) == 1) {
boolean goahead = true;
while (goahead) {
int selection = Integer.parseInt(JOptionPane.showInputDialog(null,"Where do you want to place an O?"));
if ((board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3]=='X') || (board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3]=='O')) {
JOptionPane.showOptionDialog(null,"I'm sorry, the number "+selection+" spot is already being used.","TicTacToe1",
JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options2, options2[0]);
} else {
goahead = false;
board[(((selection-1)-((selection-1)%3))/3)][(selection-1)%3] = 'O';
print(board);
}
}
}
// didsomeonewinyet(board);
}
}
// Make a helper function named print to print the board
public static void print(char board[][]){
for(int a=0; a<3; a++) {
for(int b=0; b<3; b++) {
System.out.print("|"+board[a][b]+"|");
}
System.out.println();
}
System.out.println();
}
// Winner checker.
// public static void didsomeonewinyet(char board[][]){
// Manually checking will yield 16 cases (2 diagonal, 3 horizontal, 3 vertical, either X or O), which is not that bad.
// }
}
Why does it ask for a selection too many times?
Your if conditions in the for loop are the same so they both occur during the same iteration of the loop:
if ((i%2) == 1) {
one of the if statements should be:
if ((i%2) == 0) {
depending on who you want to go first.
Alternatively you could just use an else statement:
if ((i%2) == 1) {
//code for x to go
}else {
//code for y to go
}
I've got some java code that is used for my games NPCs to move arround.
Those are obviously in an 1d array.
public void route11() {
Scanner in = new Scanner(System.in);
Random number = new Random();
int random = number.nextInt(2);
if(random ==1)
hunters[1].x = hunters[1].x -1;
else
hunters[1].y = hunters[1].y -1;
}
public void Update() {
route11();
route2();
route3();
route4();
route5();
}
Methods route2, route3, ..., route5 look pretty much the same, the only thing that changes is the value of the array to correspond with a different hunter.
Could this code be "shrinked"? Im pretty sure my lecturer will be happy to minus my mark for such a messy and very much anti-OO code.
Also, all my collision/score code looks something like this, and it works for individual hunters:
if(hunters[i].x==0 && hunters[i].y == 0){
hunters[i].x = 11;
hunters[i].y = 11;
Player.score = Player.score + 1;
}
Your issue has nothing to do with OOP design. This is just about learning to use the tools available to write less redundant and more manageable code. If you utilize a for loop in your update and pass each individual hunter then this becomes much more condensed.
I will note that there are some unrelated OOP issues that you would do well to correct.
Hunter's members such as X and Y should not be exposed publicly, utilize getters/setters
The same goes for the Player's score member/field
public void update()
{
for(var i = 0; i < 5; i++)
{
route(hunters[i]);
collisionAndScoring(hunters[i]);
}
}
public void route(Hunter hunter)
{
Scanner in = new Scanner(System.in);
Random number = new Random();
int random = number.nextInt(2);
if(random == 1)
{
hunters.x--;
}
else
{
hunter.y--;
}
}
public void collisionAndScoring(Hunter hunter)
{
if (hunter.x == 0 && hunter.y == 0) //You should define constants for these to give them more meaning
{
hunter.x = 11; //another opportunity for a constant
hunter.y = 11; //another opportunity for a constant
Player.score++;
}
}