I hava a
Composite descComp
with some stuff in it... basically it is a container for a form, consisting of number of labels, Combos and buttons, all aligned in a line.
My form is not finite, I have a button that adds one extra line for extra input. However for that to work it seams I have to dispose old children of my descComp...
private void populateConstantMain(ContentData tariffConstantsOfType, Composite descComp,GridLayout descCompLayout, Boolean resize) {
int arraySize;
if (resize == false) {
arraySize = tariffConstantsOfType.getQueryRowCount();
} else {
for (int i = 0 ; i < descComp.getChildren().length; i++) {
System.out.println("Disposing: " + i + " " + descComp.getChildren()[i].toString());
//descComp.getChildren()[i].setEnabled(false);
descComp.getChildren()[i].dispose();
}
arraySize = tariffConstantsOfType.getQueryRowCount() + 1;
}
......
}
For some reason
descComp.getChildren()[i].dispose();
does not work, meaning it wont dispose all children, that results in errors in inserting new children, therefore spoiling the layout :/ Interesting thing is that
descComp.getChildren()[i].setEnabled(false);
works, when I uncoment it, for all children...
I have a hunch that calling getChildren() on a composite returns you only the non-disposed children at the time you call it. So calling descComp.getChildren()[i].dispose(); is all messed up as your index is incrementing but your array is decreasing in size. Why don't you try:
for (Control control : descComp.getChildren()) {
control.dispose();
}
This way you get a static view of the children in the composite before you start disposing of each of them.
I've also switched the code to use the nicer J5 for-each syntax. If you are stuck on J1.4 then unfortunately you'll need to stick to the for(;;) loop:
Control[] children = descComp.getChildren();
for (int i = 0 ; i < children.length; i++) {
children[i].dispose();
}
When disposing children (or anything in an array) I use the for next loop but go through from end to start, not start to end. (And get the length before the loop or it changes.)
int i = length-1;i>=0;i--
otherwise you delete every other one.
Related
Good day, so I intend for my code to loop through my array and increment the row index of object by 1 position. I used timer task because I want the object to move forward after certain amount of time. This is the code I have tried. I have looked but I have struggled to find solution relevant to my problem. Would appreciate the help.
class cat_function extends TimerTask {
public void run() {
synchronized (game.board) {
for (int i = 0; i < game.board.length; i++) {
for (int k = 0; k < game.board[0].length; k++) {
if (game.board[i][k] instanceof cat) {
cat garfield = new cat(0, 0);
game.board[i][k] = garfield;
game.board[i][k + 1] = garfield;
}
}
}
}
}
}
Assuming:
game.board is defined as a Cat[][]
an empty cell's value is null
Then all you have to do is
if (game.board[i][k] instanceof cat) {
game.board[i][k + 1] = game.board[i][k]; // Put cat in new location
game.board[i][k] = null; // Remove cat from previous location
}
However, this code still has two problems
What do you do when you reach the edge of the board. You'll have to add logic to make it do something different so you don't fall of the edge.
There's no need to scan the entire game board every time just to find the Cat. Keep the cat's location (indexes) separately so you always know where it is and don't have to look for it.
If there can be more than one cat on the board you will also need logic to decide what happens if two cats "collide" when moving (i.e. you try to move a cat into a cell that already contains a cat).
Solving those problems is left as an exercise for you.
I have a list view with a hierarchy I theoretically have no knowledge of. I am attempting to accept a String array and create MobileElements for each string in it, but due to the way I've automated (PageFactory) defining my elements via annotations, they cannot use variables. I also don't know that it's valid or proper to define my annotations inside a method.
The code I've written, which obviously does not compile follows:
public void selectLocation(String[] location) {
List<MobileElement> locationsList = new ArrayList<>();
for(int i = 0; i < location.length; i++) {
#iOSFindBy(accessibility = location[i])
#AndroidFindBy(xpath = "//android.widget.TextView[#text='" + location[i] + "']")
locationsList.add(i);
}
for (int i = 0; i < location.length; i++) {
locationsList.get(i).click();
}
}
I'm assuming the proper way to do this is wholly different from the way I've implemented.
My list hierarchy is similar to the following; my end point could vary depending on the branch I go down:
Continent 1
City 1
Room 1
Room 2
City 2
Building 1
Room 1
Room 2
Building 2
Room 1
Room 2
I now look for a matching element. If I don't find it, I swipe further into the list. If the element doesn't exist I obviously run into problems, but not really an issue in my case since that’d be a failing test.
while (!driver.findElementById(currentLocation).isDisplayed()) {
driver.swipe(startX, startY, startX, endY, 100);
}
driver.findElementById(currentLocation).click();
Yes, I also realize .swipe() is deprecated, but it still works for me and I'd rather not rewrite all my code with TouchActions until necessary.
I ended up using the "FindsBys" functions to create an array of all matching elements. I then loop through those elements looking for a match to one of my strings.
#AndroidFindBys({#AndroidFindBy(xpath = "//android.widget.TextView")})
#iOSFindBys({#iOSFindBy(xpath = "//XCUIElementTypeStaticText")})
private List<MobileElement> locationsList;
...
public void selectLocation(String[] location)
{
for(int i = 0; i < locationsList.size(); i++)
for(int p = 0; p < location.length; p++) {
if (locationsList.get(i).getText().equals(location[p])) {
locationsList.get(i).click();
}
}
}
It's not foolproof (if you have duplicate strings at different levels of your hierarchy you may run into issues), but it works for my use-case and should be able to guide anyone looking for a stronger solution.
You can just loop over the elements themselves.
....
for(MobileElement location: locationsList) {
for(int p = 0; p < location.length; p++) {
if (location.getText().equals(location[p])) {
location.click();
}
}
}
I have multiple buttons containing some information.
Now I want that the information written on the buttons are appended when i press them i.e when i press the first button
- the information gets printed into text field
When I press second button
- the information written on button gets appended or added into the text field with the older information (data in button 1).
code for what I am trying is:
private void EActionPerformed(java.awt.event.ActionEventevt) {
String x = ans.getText();
for(int i = 0; i < x.length(); i++) {
ans.setText("H");
}
}
private void FActionPerformed(java.awt.event.ActionEvent evt) {
String x = ans.getText();
for(int i = 0; i > x.length(); i++) {
ans.setText("A");
System.out.println("completed");
}
}
Simply:
ans.setText(ans.getText() + newString);
There are a few ways to this, setText is one, but it's not particularly efficient (it's easier to type though), as you are creating additional temporary objects though the process
If you need to update the field often, you might consider using something more like...
Document doc = userNameField.getDocument();
doc.insertString(doc.getLength(), newString, null);
I am programming an AI for a chess-like game, based on two types of pieces on a 8 x 8 grid.
I want to build a kind of minmax tree, which represents each possible move in a game, played by white players in first, and by black players in second.
I have this generate() method which is call recursively. I need to be able to display about 8 levels of possible moves. Without optimization, this three has 8^8 leafs.
I implemented a simple system which determinate if a grid has actually ever been calculated and if its the case, system just points a child to the ever-calculated child reference.
I don't know if my explanations are clear, I will join a part of code that you should be able to understand.
The problem is that actually, I am able to generate about 3 or 4 levels of all possibilities. I am far of 8.
I would like to be able to calculate it in less than 5 seconds..
So guys, do you see a solution for optimize my algorithm ?
This is the generate function:
leftDiagonalMove(), rightDiagonalMove() and frontMove() return false if a move is illegal or move the piece in the grid and return true, if the move is legal.
clone() creates a new instance with the same properties of it's "parent" and backMove() just step back to last Move.
public void generate(Node root, boolean white, int index) {
Grid grid = root.getGrid();
Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE);
Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK);
Node node;
String serial = "";
// white loop
for (int i = 0; i < whitePieces.size() && white; i++) {
Piece wPiece = whitePieces.get(i);
if (grid.leftDiagonalMove(wPiece)) {
serial = grid.getSerial();
if(!allGrids.containsKey(serial)){
node = new Node(grid.clone());
node.setMove(grid.getLastMove());
root.addChild(node); // add modified grid
allGrids.put(serial, node);
//actualGrid.display();
if (index < 5 && grid.getPosition(wPiece).x > 0)
generate(node, !white, index + 1);
actualGrid.backMove(); // back step to initial grid
}
else{
root.addChild(allGrids.get(serial));
}
}
if (grid.frontMove(wPiece)) {
// same code as leftMove
}
if (grid.rightDiagonalMove(wPiece)) {
// same code as leftMove
}
}
// black loop
for (int i = 0; i < blackPieces.size() && !white; i++) {
Piece bPiece = blackPieces.get(i);
if (grid.leftDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.frontMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.rightDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
}
}
You need to use something called AlphaBeta pruning on your generated MinMax trees of moves. More on this here:
http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf
Basically you do one level of branches and then using pruning you eliminate bad branches early. Then from the non eliminated branches you calculate (for each) another level. You prune again until you reach a desired depth.
Here are a few more links for you to read up on minmax:
1. http://en.wikipedia.org/wiki/Minimax
2. MinMax trees - when Min can win in two steps
This one is on optimizing pruning for chess games:
1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2. http://en.wikipedia.org/wiki/Refutation_table#Related_techniques
I don't understand why you are using Stacks when you are doing random access to the elements. A a low level you would get an improvement by using a Piece[] array instead.
So I am stumped. Here is my collision check method`
public void checkCollision ()
{
for (int i = 0; i < bullets.size()-1; i ++)
{
for (int j = 0; j < enemiesLaunched.size()-1; j++)
{
Rectangle temp = enemiesLaunched.get(j).getRectangle();
Rectangle temp2 = bullets.get(i).getRectangle();
`
if (temp2.intersects (temp))
{
String str = bullets.get(i).getPath();
// since the bullets are selective, the following code is to check
// if the right bullets hit the right germs
if (str.equals("oil gland.png")) // bullet is from oil gland
{
if (enemiesLaunched.get(j).getInfo().equals("highAcid"))
{
enemiesLaunched.get(j).setVisible(false);
bullets.remove(i);
}
}
else if (str.equals ("sweat gland.png"))
{
if (enemiesLaunched.get(j).getInfo().equals("lysozome"))
{
enemiesLaunched.get(j).setVisible(false);
bullets.remove(i);
}
}
else
{
if (enemiesLaunched.get(j).getInfo().equals("mucus"))
{
enemiesLaunched.get(j).setVisible(false);
bullets.remove(i);
}
}
`
On my mac, it works exactly how I intended. However, on my PC, it does not. To make matters more baffling, I have implemented the same logic on games further along in the game, and it works just fine on both the mac and pc, any help would be greatly appreciated!
How are you doing your time delta, and what is the velocity on the two objects? If your time delta is sufficiently large enough, you might not detect the collision as the two objects could have pass right through each other between checks. Have a look here for an explaination.
What tears attention is size()-1 - sure? But bullets.remove(i); certainly should be followed by --i; as otherwise the for-incrementing would skip the next bullet.
Optimized it would be by keeping get(i) and get(j) in their own variables.
I'd rather use for-loops like this if possible to ensure I don't have some wrong indexes due to typos or something:
List<Enemy> enemies = new ArrayList<Enemy>;
for (Enemy enemy : enemies) {
...
}
For example with this loop:
for (int i = 0; i < enemies.size()-1; ++i)
you will always leave the last "enemy" untouched.
And then, to be sure I'm not screwing up my Lists and iterations I would keep references to objects that need to be removed and would remove them afterwards, because I'm not sure what happens when removeing items from a collection while iterating over the same collection. The behaviour might be collectiontype and implementation (of the collection) specific.