So well I tried creating a simpler Minesweeper game and I encountered one main problem..
I am not able to count the number of bombs and print it in a JTextField
Any ideas as to how to count these as I'm setting a random value to check whether they are a bomb
Tried counting it in the ActionListener but the bombs were counted only after the button was clicked.
if(e.getSource()==b[i][j])
{
b[i][j].setVisible(false);
tf[i][j].setVisible(true);
int r1 = rand.nextInt(6);
if(r1>1)
{
tf[i][j].setText("Safe");
tf[i][j].setBackground(Color.green);
}
else
{ count++;
tf[i][j].setText("Bomb");
tf[i][j].setBackground(Color.red);
f.setVisible(false);
restart.setVisible(true);
}
}
As I understand you decide if the the tile will be a bomb in the run-time using a random generator. Doing this you can't really know how many mines are in your game. I think you should decide the number of mines at the beginning of the game and randomly place them to your game board (you can choose the number according to a difficulty level).
EDIT
You can create a list with some random points that contain the mines
int numOfMines = 10;
int rows=5,columns=5;
ArrayList listWithMines = new ArrayList();
while(listWithMines.size()<numOfMines) {
int randRow = random.nextInt(rows);
int randCol = random.nextInt(columns);
Point point = new Point(randRow, randCol);
if(listWithMines.contains(point))
continue;
else
listWithMines.add(point);
}
This list now contains the Points that have the mines.
You can check if Point(x,y) has a mine like this:
if(listWithMines.contains(new Point(1, 2))) {...}
Instead of a list you can use a 2D array, store a boolean value (or int if you store more states) and make a loop until you place 10 mines. You should keep a counter(placedMines like the list.size()) of the mines you placed and make sure you don't add a mine to a tile that has already a mine and you increase the counter(placedMines) until it reaches the numOfMines.
Related
I'm making a snake game and the apples shouldn't spawn inside the snake when randomly spawned on the screen. I have tried looking for a new place for the apples, when they get placed inside the snake with:
for (int i = 0; i < snake.size() - 1; i++) {
if (snake.get(i).xPos == plum.get(0).xPos && snake.get(i).yPos == plum.get(0).yPos) {
plum.remove(0);
plum.add(new Coordinate(rollDice(squaresX - 1) * (squareSize + sizeOfSpace) + sizeOfSpace, rollDice(squaresY - 1) * (squareSize + sizeOfSpace) + sizeOfSpace, new Color(199, 7, 255)));
}
}
This is not a good solution so I'm looking for a new one where I can create invalid coordiantes which are the snakes coordinates and valid coordinates that is the rest. So I can randomize the apples new position from just valid coordinates. But I'm not sure how I'm supposed to code this
This is just a general suggestion, but I think it might work for you.
Keep the length of the snake updated all of the time
Now when creating a new apple, create an array of Coordinations of size of the grid size minus snake length. For example: if your grid size is 9x9 and your snake length is 6, create an array of length 75.
Run over the grid and array and add to the array just Coordinations that do not have the snake in them. It should look something like this:
int arrayLocation=0;
for(int i=0; i< grid.length();i++)
{
for(int j=0; j<grid[i].length(); j++)
{
if (!snakeAtLocation(i,j))
{
arr[arrayLocation++] = new Coordinate(i, j);
}
}
}
Then you can randomly pick a number n between 0 to arr.length(), then retrieve the coordination from arr[n] and you should have a coordination without a snake in it. Hope it helps and if you need more detailed example I will provide tommorow as I'm writing this from my phone and I don't have pc right now:)
By the way, this answer if for a simple use case, as it isn't optimized and running with o(n)^2 each time you eat an apple. If you want more optimized solutions, you would have to track the snake location with each move he make. I'll be able to post both answers tommorow if needed:)
I am currently making a tower defence game.
Simply put it works like this: green circles (enemies) move across the screen. By clicking, you can place a tower. The enemy has a rectangle hidden underneath it, and the tower has a large opaque rectangle around it indicating its hit range. If they are colliding, the enemy starts to lose health, until it dies.
Before, I used this test to see if the enemy was within range of the tower:
for(int i=0;i<enemy.length; i++) //Runs for the total amount of enemies
{
for(int j=0; j<boxes.length;j++) //Runs for the total amount of towers placed
{
if(enemy[i].getEBox().intersects(boxes[j])) //boxes[j] is the towers' range box
{
enemy.setHealth(enemy.getHealth()-1);
}
}
}
However, I would like the towers to only be able to shoot one enemy at a time, most preferably the enemy at the front. To do this I need java to detect that there are multiple enemies colliding with the rectangle and only damage the front enemy.
Here is the test I ran to do this (The enemies array value go backwards so the first one to appear is enemy[0] and the last enemy[10] for example):
for(int i=1;i<enemy.length; i++)
{
for(int j=0; j<boxes.length;j++)
{
if(enemy[i].getEBox().intersects(boxes[j])&&!(enemy[i-1].getEBox().intersects(boxes[j])))
{
enemy.setHealth(enemy.getHealth()-1);
}
}
}
however, the second condition always returns a positive. How can I change my if statement to conduct a successful test?
To make a tower only shoot at one enemy, flip the loops and break the inner loop when shooting starts.
for(int j=0; j<boxes.length;j++) //Runs for the total amount of towers placed
{
for(int i=0;i<enemy.length; i++) //Runs for the total amount of enemies
{
if(enemy[i].getEBox().intersects(boxes[j])) //boxes[j] is the towers' range box
{
enemy[i].setHealth(enemy[i].getHealth()-1);
break; // skip remaining enemies, since towers has used
// up it's shooting capability for this round
}
}
}
If a tower can prioritize which enemy to shoot at, loop through all the enemies to find the best candidate, then shoot at it.
for (int j=0; j<boxes.length; j++) //Runs for the total amount of towers placed
{
int enemyToShootIdx = -1;
for (int i=0; i<enemy.length; i++) //Runs for the total amount of enemies
if (enemy[i].getEBox().intersects(boxes[j])) //boxes[j] is the towers' range box
if (enemyToShootIdx == -1 || betterCandidate(boxes[j], enemy[i], enemy[enemyToShootIdx]))
enemyToShootIdx = i;
if (enemyToShootIdx != -1)
enemy[enemyToShootIdx].setHealth(enemy[enemyToShootIdx].getHealth()-1);
}
Now you just have to implement the betterCandidate() method.
You could store the enemies in the order you detect them so you will know which is the closest. Like an ArrayList for detected enemies or an ID kind of variable for each enemy object, which initialized when detected. Im pretty sure there are a lot ways like this, so storing an order somehow could work. Once you have an order you can attack only that one and there is no need to test the detected objects anymore while still looking for coming enemies and keep storing them so on.
In your case
if(enemy[i].getEBox().intersects(boxes[j])&&!(enemy[i- 1].getEBox().intersects(boxes[j])))
I don't really see (or maybe just too tired) why you need these conditions to attack. If your array of enemies is already in order why dont you just attack the first? If inRange && isAlive if not you go on the next one.
I hope i did not misunderstand anything and probably could help a bit. :)
I'm in the process of writing a very simple quiz-style boardgame that moves players around the board based on if they answer the question correctly and what they roll on the dice. I'm attempting to create and pass an array mehtod that stores the scores of player 1 and player 2, but the array doesn't seem to actually keep track of the score. For example, a fragment of some of the code is as follows:
public static int[] scorearray
{
int scoreplayer1 = 0;
int scoreplayer2 = 0;
return new int[] = {scoreplayer1, scoreplayer2};
}
public static int questions(int diceroll, int[] score)
{
String textinput = input("What's 9+10?");
int ans = Integer.parseInt(textinput);
if (ans == 19)
{
output("Fantastic answer, that's correct!");
diceroll = dicethrow(diceroll); // rolls the dice
output("Move forward " + diceroll + " squares. You are on square " + score[0]);
//I need the output above to print position 0 in the above array
score[0] = score[0] + diceroll; //array stores the cumulative score
}
else
{
output("Sorry, the answer was 19. Next player's turn.")
//This is where I need the loop to switch between players
}
In addition, I need to come up with a way of switching between player 1 and 2 while also switching to the position 1 in the above array, that is, I need to add to player two's score instead of player one's. I've been combing through this code for ages now trying to figure out how to do this but I can only come up with the idea of using a for/while loop. Other than that I'm truly stumped.
Thanks.
EDIT: It appears that my array apparently still does not store the score when being used in the method questions.
Also I have now realised I can control whose turn it is by creating another method, for example public static void activePlayer() but I'm still not sure how to use a loop (or anything else for that matter) to switch between the two. Also my concern is where I use score[0] = score[0] + diceroll; in my questions method only keeps the score (or at least attempts to; see above problem) for player one. How would I switch it to keep score for score[1]? Please.
your options here seem to be either have your questions function output the score or change your score object to be a static object instead of a static function.
public static int[] scorearray = [0,0];
or
public static int[] questions(int diceroll, int[] score)
I created two methods for my Bingo Game in Java. One method creates a new board which populates the Bingo Board with integers according to the Bingo rule (1-75). My second method generates random numbers with a range of 1 - 75.
public static int drawNum(){
Random rand = new Random();
int num = rand.nextInt(75)+1;
return num;
}
public static void bingoCard(){
int [][]card=new int [5][5];
ArrayList<Integer> alreadyUsed = new ArrayList<Integer>();
boolean valid = false;
int tmp = 0;
for(int i = 0; i <= 4; i++){
for(int row = 0; row < card.length; row++){
while(!valid){
tmp = (int)(Math.random() * 15) + 1 + 15 * i;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][i] = tmp;
valid = false;
}
}
card[2][2] = 0;
//create array to make title.
String title []={"B","I","N","G","O"};
for(int i=0;i<title.length;i++){
System.out.print(title[i]+ "\t");
}
System.out.println();
for(int row=0;row<card.length;row++){
for(int col=0;col<card[row].length;col++){
System.out.print(card[row][col]+ "\t");
}
System.out.println();
}
}
What I need help with is, how do I check whether or not the drawNum() method corresponds to any values stored inside my bingoCard() array? If so, print out a new array with the integers filled in. If the condition is met for a bingo, then you win.
I hope I don't make it sound like I want you to do it for me, but I am confused as to how to start coding that part. Thank you.
This my recommendation - Learn Object Oriented Programming immediately
I see you are using objects provided in the JDK, so why not learn to make your own?
Make two classes with the following methods (-) and members (+) (PS. This is not a formal way to document code)
BingoCard
+list of numbers on card
-reset() : gets new numbers for this card
-test(BingoDrawer) : Tests to see if this card won on this drawing
-toString() : returns a String representation of this card
BingoDrawer
+list of numbers drawn
-reset() : draws new numbers
-hasNumber(int number) : tests if this number was drawn
-toString() : returns a String representation of this drawing
One more suggestions
Instead of keeping track of what you used, keep track of what you have not used, it will make things much easier because you can just choose stuff from that list randomly. Unlike your current action which is choosing (a logical number) from thin air and hoping (which causes issues) it is not a collision
If you follow my recommendation you can write code like this
public static void main(String[] args) {
BingoCard bc = new BingoCard();
BingoDrawer bd = new BingoDrawer();
while(thePlayerWantsToPlay()) { //function to be defined by you
bc.reset();
bd.reset();
System.out.println(bc);
System.out.println(bd);
System.out.println(bc.test(bd));
}
}
You can take it a step further and make a BingoGame class and do what I did in main there and just create an instance of BingoGame and call some start method on the object.
For checking if you have the number in your board, read through the board in a similar manner as you do for the already_used numbers, except with the number the user just entered.
The conditions for the user to win should be checked after the board has another number guessed.
There are a few ways to do this, a simple one would be to iterate over every possible pattern that could win, checking to see if there are tokens there.
All of this would be in a loop, that goes a little like this:
Set up board via user entering numbers.
Start loop
set either a timer to wait for, or wait for a keypress (so the game doesn't just play really fast)
Get random number
Possibly add to board
Check if winner
if winner, break the loop and do something else.
Print the new board out.
(end of loop)
If they got here, that could mean they won!
Wait to exit
You can just write it out as pseudo-code and fill in the methods after that. It usually helps to work on these things in a top-down fashion. So, for bingo you might have:
board = generateBoard();
while (!bingoFound(board)) {
number = drawNumber();
board = stampNumbers(board, number);
}
If that makes sense, you can go a step deeper and define each method. For example, bingoFound might look like:
public boolean bingoFound(int[][] board) {
boolean wasFound = bingoRowFound(board)
|| bingoColFound(board)
|| bingoDiagonalFound(board);
return wasFound;
}
Again, I've defined everything in (mostly) pseudo-code. If this looks ok, you can move a step deeper. Let's define the bingoRowFound method.
public boolean bingoRowFound(int[][] board) {
for (int row = 0; row < NUM_ROWS; row++) {
boolean rowIsABingo = true;
for (int col = 0; col < NUM_COLS; col++) {
// We have to check that everything up until this point has
// been marked off. I am using -1 to indicate that a spot has
// been marked.
rowIsABingo = rowIsABingo && board[row][col] == -1;
}
if (rowIsABingo) { return rowIsABingo; }
}
return false; // If we didn't find a bingo, return false.
}
Some of the methods (like drawNumber) will be really easy to implement. Others, like looking for a diagonal bingo might be a bit more difficult.
Feb 12 2014 Update:
Retracted code, since this was a college course assignment, and I want to prevent people just copying the code. I almost got in trouble for being accused of sharing code (which is a nono in assignments) when another student lifted my code from my Github repo and sent it in as their own.
There were two classes, one main class and a class to hold my methods and constructors.
BINGOFINAL.java was my main class.
Bingo_Card.java held my constructor and methods.
If you want to run this, make sure you create a new project called BINGOFINAL, and put Bingo_Card.java into that same */src/ extension.
I am creating a game using a 10x10 2D array. The player starts at the top left hand corner indicated as "P" and the objective is to get the player to avoid obstacles to get to the treasure indicated as "T" located in the lower right corner.
How would I go about making the player move about the grid using commands Up/Down/Left/Right?
Would I use a for loop to count through the elements in the array to designate the move?
Here is what I have so far:
import java.util.Scanner;
import java.util.Random;
public class Adventure {
public static void main(String[] args) {
char grid[][]= new char[10][10];
Scanner move = new Scanner(System.in);
System.out.println("Here is the current game board:");
System.out.println("-------------------------------");
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid.length; j++) {
double random = Math.random();
if(random <=.05) {
grid[i][j]='*';
}
else if(random > .06 && random <= .15) {
grid[i][j]='X';
}
else {
grid[i][j]='.';
}
grid[0][0]='P';
grid[9][9]='T';
System.out.print(grid[i][j]);
}
System.out.println("");
}
System.out.print("Enter your move (U/D/L/R)>");
}
}
you should keep track of the current position of the player and just update those variables.
initial values would be (0,0) as you said.
int px = 0;
int py = 0;
when a move is made, update the variables accordingly:
grid[px][py] = <empty cell>;
switch (move) {
case 'u': py += 1; break;
case 'r': px += 1; break;
...
}
grid[px][py] = 'P';
of course you shouldn't just updated the values "blindly", you should insert some validation logic to follow the rules of the game:
if (grid[px][py] != <obstacle> )
// update player coordinates...
Looks like you're using row-major ordering, judging from the way your board prints out. Based on that, here's what you'll need to do:
First, you need to store the player's position somewhere. Right now it's hardcoded to 0,0.
Second, you need to read in the player's move. That will have to happen in a loop, where you get a move, check if the move is allowed, perform the move, and display the results.
Third, you need to be able to calculate the new position based on the move. Up means row -= 1. Right means column += 1. Etc.
Given the new coordinates, you need to make sure the move is valid. At the very least, you have to stop them from walking off the board, but you may also prevent them from entering a square with an obstacle, etc.
Once you know that the move is valid, you have to update the variables you're storing the current coordinates in.
At the end of the loop, you'll need to redraw the board.
That's the basic gist of it. Right now you are doing everything in main(), and that's okay, but if it were me I would start to split things out into separate methods, like InitializeBoard(), GetNextMove(), CheckIfMoveIsValid(int r, int c), and so on. That way, main() becomes a high-level view of your game loop, and the guts of the different operations are compartmentalized and more easy to deal with. This will require storing off things like your game board into class variables rather than local variables, which should actually make things like obstacle detection easier than it would be currently.
All of the above answers are great. Here are a few suggestions I would make:
Instead of a char two-dimensional array, I would make a custom object, such as Space, and define a two-dimensional array of Spaces (eg, Space[][]). There are a few reasons for this:
You can define a space in a variety of ways (rather than just 1 character). For example, Space[i][j].hasTreasure() can return a boolean to let you know whether or not you found the treasure.
If you want to add functionality later, its as easy as adding an attribute to your Space class. Again, you are not limited to one character here.
More to your question of movement, I would also recommend a few things. Similar to redneckjedi's suggestion of a CheckIfMoveIsValid() method, I would pass the grid and move direction as parameters and return a boolean. To ensure that you do not end up with ArrayIndexOutOfBounds issues, I would also suggest adding a row/column of walls on each side. I would widen the grid out to 12x12 and put a strip of obstacle-type blocks around the outside. This will ensure that you cannot step outside of the grid as hitting a wall will always return 'false' on a valid move.