how do i randomly perform button's action - java

I'm really new to JAVA and I'm making tic tac toe game i finished player vs player and now i want to do player vs cpu what i want to do is when player click on a button for X to appear then cpu will select their button randomly for O to appear but i don't know the code to randomly perform action
I was searching on internet for hour and still no result
here's my code
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
//my code here to set text and background etc
if(jButton3.getActionCommand().equals("X") && jButton1.getActionCommand().equals("") && jButton2.getActionCommand().equals("")){
//this where i wanna random between 2 button action
}
I want the CPU to choose between
jButton1ActionPerformed(evt);
jButton2ActionPerformed(evt);
but i really have no idea how to do it

My Understanding
I am interpreting your question as How do I write a function which randomly marks one of the remaining squares with the letter 'O', after the user has performed a move. Correct me with a comment if I am mistaken.
Problem Approach
Because I do not know the exact nature of the code representing your cpu player I will provide a high level solution that you can implement.
1. Firstly, after a player marks a square with the letter 'X' you must check which squares still remain unmarked. You can do this by initializing an ArrayList of Integers, 1 through 9, at the start of the game which represent the squares (buttons) which are still unmarked.
Figure: Numbered Tic-Tac-Toe Board
2. Second, each time one of the squares is marked, either by the player or the cpu, remove the corresponding Integer from the list.
3. Watch for button action events in the way you currently are and add the following code. (our ArrayList of Integers is named unmarked_boxes).
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
//my code here to set text and background etc
if(jButton3.getActionCommand().equals("X") && jButton1.getActionCommand().equals("") && jButton2.getActionCommand().equals("")){
Random rand_gen = new Random();
int index_selected = rand_gen.nextInt(unmarked_boxes.size());
box_selected = unmarked_boxes.remove(index_selected);
/*
here you select and mark the button which corresponds to the box
selected. i.e. if the box_selected = 3, then find and mark button3 (not sure
how you access your buttons).
*/
}
In the code I inserted we instantiate and Object of type Random and call its member function nextInt(int bound). This function will generate a number between 0 and the int 'bound'.
In this case we want to select a square from the entire list of unmarked squares.
Hence we generated a number between 0 and the number of remaining squares.
Then we grab (and simultaneously remove) the number which is at 'index_selected' in our list of unmarked_boxes and mark the corresponding button with an 'O'.
After this point, you need to implement your code to mark the chosen button.
Note: If you are dead set on selecting between only 2 squares, then forget about the ArrayList approach I have described. Just call rand_gen.nextBoolean() and insert an if statement which picks one button if true and the other if false.
This should be enough to get you started implementing your solution,
Good Luck

Related

ActionListener and dynamic(?) GUI

I've read through a dozen or so actionlistener/loop related questions here, but I'm not sure I've found my answer. I started on my first large Java project, a text RPG that's spiraled into around 5K lines of logic and game features which was functioning as intended using just the console - when I decided I'd try to build a Java swing GUI for it instead. Here's my problem:
I use a Room object which handles the description of where the player is at and also has an array of options for the player to choose next which it creates dynamically based on what cell the room's id is in on a csv file and what is beside it. I stopped outputting this to the console and instead started creating JButtons based on the options array like so:
public void showNarrate(){
add(dd,gridConstraints);
optionCopy.clear();
int i = 0;
for(JButton j : optionButtons){
//adding and formatting buttons to gridBagConstraint I also set actionCommand for each button to the triggerValue (ID of the next room which the button should take the player to)
}
//I tried using a copy of my JButton array here so I could have something to iterate over in actionListener after clearing out the original
//(Since it needs to be cleared so the next Room's buttons can be built after the player chooses an option)
for(JButton j : optionButtons){
optionCopy.add(j);
}
optionButtons.clear();
//dd is a seperate drawingComponent I used for outputting room descriptions which may be totally unnecessary at this point :/
dd.repaint();
setVisible(true);
}
Over in actionlistener (Same class) this is how I tried to swing it:
for(JButton j : optionCopy){
if(e.getActionCommand().equals(j.getActionCommand())){
Main.saveRoom = Main.currentRoom;
Main.currentRoom = j.getActionCommand();
System.out.println(Main.currentRoom);
}
}}
Then in my main class I call:
narrator.narrate(currentRoom, saveRoom); which takes care of some other logic concerning locked doors, encounters, etc.
Also in Main loop are some other methods related to autosave and tracking which rooms the player has visited. I know from other q/a i'v read on here that this is all pretty bad design, and I'm sttarting to understand that now, but my issue is this:
The first room of the game loads up fine, when I click a button it outputs to console(Just for testing) the correct trigger value of the room the button should be calling, so I'm getting that far, but how can I call the same method over again now?
-If I call narrate from actionListener it will wind up calling itself again and complain about ConcurrentModification.
-If I try to keep a loop going in my Main class it will keep looping and won't allow for the player to actually choose a button.
I've never used threads before, which I wonder might be the answer,and the closest thing to a related answer I've found is this:
Java: Method wait for ActionListener in another class
but I don't think moving actionListener to Main class would resolve my problem which is actionListener winding up calling itself recursively. And as for the observer-observable pattern... I just can't understand it :(
I appreciate any and all help, I've learned a LOT trying to make this thing work without seeking help as much as possible but this has stumped me.
Your loop in actionPerformed only checks whether a JButton exists in your optionList with the given actionCommand. However this can be done before actually doing something:
boolean contained = false;
for (JButton j : optionButtons)
if (j.getActionCommand().equals(e.getActionCommand()))
contained = true;
if (contained) {
// change room
}
now you can call narrate because you have finished iterating over the collection beforehand and will not get a ConcurrentModificationException

How to move/iterate forward to next value in Array (java/android)

Spent the last 1-2 hours looking for the answer and haven't quite got it, I'm hoping it's something simple.
I have created an array of a custom class with just a small number of values like so (where Person is a Class):
Person person[] = new Person[2];
(Note I'll be replacing the 2 with a variable like numberOfPeople)
I need to create a method that I can call when needed (on a button press for example) that will move from the current person to the next in the array (going back to the start when it reaches the end).
In other words: On button press - move from player0 to player1.
I've been looking at how to use For, ForEach, If etc to do this but can't work it out.
SOLVED VIA Vincent Ugenti's ANSWER.
In case other noobs come across this to solve their problem, had a few subsequent noob issues where I was trying to define the number of values in the array with a variable which wasn't given a value until after the array was made (causing instant crashing) and then I forgot doing nothing more with the code than this won't run each objects Constructor which needs to be done separately.
Create a variable such as "currentPerson"
In your event handler (whenever you want to advance to the next person), currentPerson = (currentPerson + 1) % numberOfPeople
The current person is then always person[currentPerson]
Keeping track of the current index and hooking a button event is what you want to do.
On button press check your variable, increment it by 1 and check if that value is not greater than the length of the array.
If its not greater than the array length you can grab the element, else reset the count to 0 and do what you need to do.
If youre only doing this on button press (event handler) you shouldnt need to use any loops.

Selecting Objects from an ArrayList using Keyboard Input

thanks for coming by. I have been working on a game inventory system, its been working awesome when I pick items from the world and then they get added into the list and displayed inside an inventory box when I hit "I", but now I want to be able to interact with them using the arrow keys and the ENTER key, every item has a method called "use" in which it executes an action, (Ex: HP potion, increases player health) now I want to be able to select items from the list and when I hit enter that the selected item's method "use" is actually used, I've got the input handling covered, I only wish to know how to access the objects inside the arraylist depending on the selected choice.
So far I got:
private int currentChoice=0;//the value is the index position within the
//array, so 0 would mean I selected an object
//at index 0.
private ArrayList<Item> playerItems;//This is the array in which I store
//the player's items.
private boolean inventoryDisplayed;//This is used when I click "I" then the
//the arrow keys stop moving the player
//and should now be used to interact with
//the items inside the inventory.
If you guys could help me that would brighten my week, seriously, this project is very important to me, any help is very appreciated, thanks for taking your time to help a fellow member from stackOverflow, may good fortune shine on your life, have a big choco cookie just for reading up 'till here. :)
Basically you can get the element at a specific position in a list by using
list.get(index);
or in your case
playerItems.get(currentChoice);
First thing, define playerItems as private List<Item> playerItems; and then instantiate it as playerItems = new ArrayList<Item>();. This is one of the core principles of well designed code, particularly if you need to change playerItems to a LinkedList later on.
You'll need to add a KeyListener or KeyAdapter to the appropriate component when the 'i' character is typed. Then, implement the keyTyped (or maybe the keyPressed) method as follows:
#Override
public void keyTyped(KeyEvent e)
{
switch(e.getKeyChar())
{
case KeyEvent.VK_LEFT:
if(--currentChoice < 0)
currentChoice = playerItems.size() - 1;
break;
case KeyEvent.VK_RIGHT:
if(++currentChoice >= playerItems.size())
currentChoice = 0;
break;
}
}
Then you can retrieve the appropriate item with: playerItems.get(currentChoice);

Java JButton Only Doing some calls on double-click

So I have a massive project due soon, and for whatever reason my JButton's in my grid will call my incMoves() method which updates the private state of the move counter, but on the other hand, will not update the grid as it should be until i click the same button again.
The incMoves() method is called both times, so my move counter is completely out of whack.
Here is the code for my button:
class genWindow:
http://pastebin.com/SJ4wzYX0
class Jam: http://pastebin.com/87nqPBYP
Here is my test file: (txt)
6 5
4
0 3 2 3
3 1 3 3
3 0 5 0
2 0 2 1
Let me know if more information is needed.
Other than debugging the program with breakpoints within the ActionListener inner class to check whether it was actually making it in to the actionPerformed method, I don't know what else to attempt to fix it. I'm reasonably new to swing, and am rather confused by this, considering no errors or noticeable changes happen, besides the colors not switching.
The car buttons should be shifting depending on the large if statements in the actionPerformed method, and then updating grid with the addGrid function. The move counter is incremented, although the buttons don't actually shift unless clicked again.

Java 2D turn-based game programming: handle 2 mouse clicks per player

So suppose I'm developing a chess-like program using Java's Swing. I added a MouseListener to handle user input. To make a move the user must click a valid piece and then click a valid place. What's the best way to track the 2 mouse clicks in a turn? I'm thinking in use some kind of variable to record if is the turn's first click or second.
You have to distinguish the two game states, using a variable is fine.. you can also think something as suggested by NomeN comment and use two different listeners by swapping them.
Your case is quite simple but in general the formalism you use to handle these things is a sort of finite state machine that describes the states of your game and how to pass from one to another.
In this case you can have some states like:
player 1 turn
player 2 turn
main screen
pause screen
option screen
and you decide how and when to pass from a state to another, for example
after player1 moved you pass to player2 turn
after player2 moves you go back to player1 turn
when game starts you go in main screen
if you start a new game then you go to player1 turn
if you press pause key while in game you go from turn to pause screen and when closed you go back to the turn that was going before pause
This is just to give you an idea, so for example your MouseListener could care about states:
enum State { TURN_P1, TURN_P2, MAIN, PAUSE, ... }
public State gameState
...
public void mouseClicked(MouseEvent e)
{
if (gameState == TURN_P1)
{
...
if (move_is_legal and so on)
gameState = TURN_P2;
}
else if (gameState == TURN_P2)
{
...
if (move_is_legal and so on)
gameState = TURN_P1;
}
}
Oops, I answered too quickly. Yes, a structure that encodes a click location, looks for intervening motion events and then records the second click. There should be an initiated state, an accept state, and it should probably record a abort state (maybe a press of ESC).

Categories