Fargesia wrote ...

2019/8/7

# 2D Array

Fargesia

2019/8/7

Hi! I'm working on an IA in chess game and I need to memorise every possible move. For this I figured a good way was to create a 2D Array (if possible) or something like that, every line represents a possible move and each element in this line is an x or y position of the move. To make it clear here's an example: Line 1 : {{oldXLocation; oldYLocation; newXLocation; newYLocation;}, Line 2 : {oldXLocation; oldYLocation; newXLocation; newYLocation;}, Line 3 : {oldXLocation; oldYLocation; newXLocation; newYLocation;}, Line 4 : {oldXLocation; oldYLocation; newXLocation; newYLocation;}, Line 5 : {oldXLocation; oldYLocation; newXLocation; newYLocation;}}; The problem is that I can't know how many lines I'll need as every turn the number of possible moves changes and I also need to get the number of lines the list have at the moment... How can I do this? Thank you very much!
danpost

2019/8/7

Arrays are static in length. That is, once you create one, its length cannot change. Therefore, if you are to use your 2D array as defined above, it must be large enough for the maximum number of moves. If you need to know the number of lines, you can either count the non-null elements on the fly or use an int variable that is properly maintains to the list size. As possible alternatives to the 2D array, you can use a List object whose size is variable or (and I say this, knowing you are working on a chess game) you can use a simple String object concatenating the moves as 4-character strings (or more, if extra data is to be saved with the move -- like what piece is captured and the type of move (standard, en passant, castling king or queen-side, or type of promotion)). In fact, I am currently in the process of re-coding my ChessWorld scenario which I seem to have lost the code to. I am using an 8-character string for each move (two are parsing characters). The character sequence used is: (1) from x-coordinate; (2) from y-coordinate; (3) to x-coordinate; (4) to y-coordinate; (5) ':' (colon; as parsing character); (6) captured piece (as one of the characters in " PNBRQK"); (7) move type (as one of the characcters in ".<>&QRBN"); (8) ';' (semi-colon; as parsing character); In (7), the representation of characters are as follows: ('.') a period for a normal (nothing special) move; ('<') a less-than symbol for queen-side castling; ('>') a greater-than symbol for king-side castling; ('&') for an en passant move; ('Q', 'R', 'B', or 'N') for piece promoted to; This system saves all information that is needed to be known about a move such that if given the last move, the previous position can be ascertained with no ambiguity.
Fargesia

2019/8/7

So instead of a 2D array I should use a list of String? Looks fine to me but how do I declare the string automatically? Like I have to give it a name wich can't be used twice if you get what I mean... Could you show me how that would look? I see the principle but I don't see how to do it.
Super_Hippo

2019/8/7

The list of strings only has one name. Example:
```//creating it
private ArrayList<String> moves = new ArrayList<String>(0);

Short question here: Is the captured piece relevant to prevent ambiguity?
Fargesia

2019/8/7

Ok yeah seems logic thanks About the question I don't get what you mean (sorry I'm french as you could guess). Could you repeat it like in other words?
Fargesia

2019/8/7

Another question, I've never really used String until now, how do you insert an int variable into the String? Like I have a J variable wich equals 7 for example, how do I insert this into the String? This would just insert j as a letter: moves.add("j"); Basic stuff but I never used it, thanks for your help!
danpost

2019/8/7

Fargesia wrote...
So instead of a 2D array I should use a list of String?
I never mentioned a "list of String". I meant just one simple String object with all the moves listed within it. For example, the first two games moves (1. e4; e5;) might be listed in a string as: "4143: .;4644: .;". The subsequent moves would be added to the end of the string by concatenation. Possible moves for the player at turn can be listed exactly the same way.
danpost

2019/8/7

Super_Hippo wrote...
Short question here: Is the captured piece relevant to prevent ambiguity?
Well, it is not immediately apparent. If any type of take back feature to be implemented, it would be quite helpful. Taking back a move may be implemented for a number of reasons.
Fargesia

2019/8/7

Ok but to begin with the IA I want it to pick a random possible move, how do pick a random move within one String? If I want let's say the IA to pick the 20th possible move, how do I pick this precise move in one String?
danpost

2019/8/7

Fargesia wrote...
Ok but to begin with the IA I want it to pick a random possible move, how do pick a random move within one String?
```int rand = Greenfoot.getRandomNumber(moves.length()/8);
String move = moves.substring(rand*8, rand*8+8);```
If I want let's say the IA to pick the 20th possible move, how do I pick this precise move in one String?
You would need to know there were at least 20 moves in the list to begin with:
`if (moves.length()/8 >= 20) move = moves.substring(20*8, 20*8+8); // move variable must be previously defined`
Though, I do not know why you would use a specific value (20) like this unless it was randomly generated to begin with. Then, it would just revert back to the above.
Super_Hippo

2019/8/8

danpost wrote...
Well, it is not immediately apparent. If any type of take back feature to be implemented, it would be quite helpful. Taking back a move may be implemented for a number of reasons.
Ah, I see. That makes sense.
Fargesia

2019/8/8

Hey guys, I was quickly doing the menus and I got an error I don't understand why. I added those Objects in the world code:
```addObject(new unJoueur(), 300, 200);
It's just to set one or two players, and here are the code from those Objects:
```public class unJoueur extends Actor
{
/**
* Act - do whatever the unJoueur wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
GreenfootImage image = new GreenfootImage("1joueur.png");
image.scale(344, 100);
setImage(image);

if(Greenfoot.mouseClicked(this)){
Plateau.fini=0;
Plateau.unJoueur=1;
getWorld().removeObjects(getWorld().getObjects(unJoueur.class));
getWorld().removeObjects(getWorld().getObjects(deuxJoueurs.class));
}
}
}```
```public class deuxJoueurs extends Actor
{
/**
* Act - do whatever the deuxJoueurs wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
GreenfootImage image = new GreenfootImage("2joueurs.png");
image.scale(344, 100);
setImage(image);

if(Greenfoot.mouseClicked(this)){
Plateau.fini=0;
getWorld().removeObjects(getWorld().getObjects(unJoueur.class));
getWorld().removeObjects(getWorld().getObjects(deuxJoueurs.class));
}
}
}```
But in the unJoueur code I can't remove the deuxJoueurs Object, I got a null Pointer exception error... Why is that? I declared both of them the same way at the same place.
Fargesia

2019/8/8

I mean the code of the two is litteraly the same except that in one I change one more variable. And I don't add those Objects or remove them anywhere else.
Fargesia

2019/8/8

I also tried just copy and past the one that works in the other one (just keepin the name of the class "unJoueur" but the rest was exactly the same. Still didn't work...
Super_Hippo

2019/8/8

Swap lines 16 and 17 in the unJoueur class. Or replace the class code with this:
```    public unJoueur()
{
GreenfootImage image = new GreenfootImage("1joueur.png");
image.scale(344, 100);
setImage(image);
}

public void act()
{
if (Greenfoot.mouseClicked(this))
{
Plateau.fini=0;
Plateau.unJoueur=1;
getWorld().removeObjects(getWorld().getObjects(deuxJoueurs.class));
getWorld().removeObject(this);
}
}```