Wednesday, May 04, 2016

LearnJavaByTurnBasedGame - chapter 2

Learn Java By a Turn-Based Game

By Andrea Valente – andrea270872@gmail.com – andval.net


[CHAPTER 2] First challenge: find out how the original game works

Here I am in the same position as a scientist in front of an unknown gadget or phenomenon. I know that Rust Bucket works, I can play with it, but do I understand how it works?
I don’t want to just play, I want to be able to re-make the game. So I need to understand how to re-create it without a computer. If I can do that, make the game a board game, I can surely teach my computer to hold the board and the pieces for me later on. And I also need to identify the rules of the game so that I perfectly simulate a game in the board game version.
With a game like Rust Bucket as the starting point, the board game version is going to be relatively easy because all works in steps already. The same exercise would be more complex for say a game like Super Mario Bros. (by Nintendo), but as for the LEGO super robots, start simple then redesign until satisfied! Also a great analysis already exists at the Rust Bucket Wiki (http://nitrome.wikia.com/wiki/Endless_Mode_(Rust_Bucket) ), so I know how to call the pieces of the game.
Another trick to simplify is to think only to a portion of the game, for example focus on a single line. Even like this many interesting things can happen in the game, and it makes my life easier when defining my Oxidized Pot board game.


Cutting a single line out of a level in Rust Bucket

Good, the next question is: how can I reason about the board game? I need to be able to quickly sketch a situation and find out the consequences. For example I can imagine that the player’s character (aka the hero) being near the exit with a pot to block the way, so that the only think the player needs to do to win is to smash the pot and walk into the exit… but how can I visualize/sketch this situation? (also considering that I am very VERY poor at drawing?!)


I can make up a notation and write the level down!

And because I want to have a quick way to scribble these single-line “levels” down, I will abbreviate the notation to something like:
WEHPEX
In this way a sequence of characters (in programming that is called a string) is my representation of the situation in which the game is. And to reason about moves in the game, I can just write down a sequence of strings, like this:

WEHPEX
Then the player moves right
WEHEEX
Pot brakes. Player moves right again
WEEHEX
Right
WEEEHX
Right
WEEEEH
Player wins
This is great: I have a notation to think about that is the situation of the game (in programming terms the state) and I can also quickly reason on a sequence of situations, as they might progress while I play my board game. 
I can now express rules about what the game should and should not do. For example: when the hero ‘H’ moves he leaves an empty space on is old position. But if the ‘H’ wants to move on a character ‘P’ in my string, which represents a pot, the pot breaks and ‘H’ does not actually move for that turn. I need to have a representation for the state of the game before I can express rules.
Now I can now use a Java program to print the situation my board game is in and I can print sequences on the screen to give the impression that the situation is changing over time. I open NetBeans and create a Java project, call it “Oxidized Pot” and write the following: 


So it works. It is not interactive (the program does not ask for my input, it just prints the same stuff each time I run it), but it produces a sequence of snapshots of my game, and that’s a start.
What does the code mean? I basically need to tell Java:

output something
on the screen, where output should be a suitable Java a command; the something part is changeable, so that I can tell Java to output a text followed by a different text, for example:
                                output WEHPEX
and then
                                output WEHEEX
In Java the output instruction is:
             System.out.println( something );
So to output the 2 pieces of text as above I have to write:
             System.out.println( "WEHPEX" );
             System.out.println( "WEHEEX" );
Placing on System.out.println instruction after the other has the effect that the first is executed first and the second… after that. The way the output instruction is written follows Java’s syntax: typically a command will have a name (that should be written always in the same way, for Java to understand which command I’m referring to) and some changeable part, usually written between brackets. In this case the changeable part is a piece of text and in Java’s syntax that is a sequence of characters (letters or numbers) written between 2 quotes. Usually Java commands end with a semi-column ; character, to help Java understand where each command ends and where the next one might start.

For some reasons (what I will discuss later, when the needs arises) in Java I cannot just write my commands without adding something before and after them. This is why when I create a project in NetBeans, the IDE kindly writes for me something like:
             public class OxidizedPot{
                public static void main(String[] args){
before the place where I will write my commands, and then it adds something like this:
                }
             }
after. For now I will just regard this as a given fact, the same way that I don't need to have any deeper understanding of why LEGO bricks have specific sizes and come only in certain shapes. It will become clearer as I progress and I have better grasp of the relations among my commands and general Java programming.
It is useful to notice however that whatever these 2 lines mean, the have balanced curly brackets: when a { opens, there is always one that closes, like this } . This suggests that somehow my code is sandwiched in between curly brackets. A piece of code written in between an open and closed curly bracket is called a block in Java. My program consists of a class block that contains a main block, that contains in turn my actual commands to output some text. And the most important thing I need to remember for now is that whatever command I write inside the main block will be executed by Java.

In my OxidizedPot_v0 project I also use a very important feature of programming languages: I declare and use variables. It is very much like giving a name to something, to simplify talking about it. For instance I might want to say: "Look at the male black cat that is currently in a basket near the window and tell me if it is asleep." And later: "Look at the male black cat that is currently in a basket near the window and tell me if it has a collar". If many of my questions involve that cat, it would be more convenient to give it a name, even a made-up one, and use that to speed-up our conversation:
"See that male black cat that is currently in a basket near the window? Let's call it Bob.
Can you tell me if Bob is asleep?
Can you tell me if Bob has a collar?"

Later I might change my mind and decide to call "Bob" a different cat, and it would still make sense to ask you to check if Bob (whichever cat it is at that moment) is sleeping or not.

In Java terms, a variable has a name (here it would be Bob), a value (in this case the description of the specific cat I want to talk about) and a type, usually the same as the type of its value (in the cat example Bob is a cat-type variable, and its value is a cat-type animal). I can always replace a value with a variable in my Java commands, provided the type of the variable matches that of the value. So if it is correct to write a command like this:
         System.out.println( "WEHPEX" );
then it is also correct to replace the text (a value of type String, in Java) with a String-type variable:
    aaa = "WEHPEX";
    System.out.println( aaa );
and in this case Java will not output the text "aaa" but the value of the variable aaa, which is set to the string "WEHPEX" by the command:
    aaa = "WEHPEX";
which means: please Java, give the variable aaa the value expressed by the string “WEHPEX”. This is called assigning a value to a variable.
Just to make my life more annoying, Java requires that I declare a variable before I use it, so I have to specify that aaa is not a number or another type of variable, but actually a String-type variable, that will be able to have a String-type value. In Java I do this in the following way:
       String aaa;
which declares a variable with name aaa, of type String. The name of the variable is of course up to me, the programmer, and it will in most cases be more meaningful than aaa. Putting it all together, I can declare a variable, then put a value in it, output its value, change the value to a new one and output that one as well:
       String aaa;
       aaa = "WEHPEX";
       System.out.println( aaa );
       aaa = "WEHEEX";
       System.out.println( aaa );
I must remember to declare my variable exactly once: in fact I cannot use a variable that I did not declare, but when a variable is declared its type is fixed and Java will not allow me to change it later in the program, so re-declaring a variable is also considered an error by Java. After all if Bob is supposed to be a cat, I can use the name for different cats, but if I suddenly decide that Bob is a tractor our conversation will rapidly become very confused. So: declaration must be done exactly once for each variable, however putting a value in the variable (aka assigning a value) can be done as many times as needed. 
Another way to think about a variable is as a box that can contain different things at different times. Also, in Java I can define as many variables as I need, and the values of these variables are stored in the memory of my computer. Of course the more boxes I use, the more space they will take up in the memory (but no worries, modern computers have very large memories).

Apart from strings, in Java I can work with numbers. For example I can declare a variable of type int (which stands for integer or whole numbers) and use it to perform calculations (like finding out the area of a square, given how long its side is):
          int side;
          side = 10;
          int square;
          square = side * side;
          System.out.println( square );
this program makes Java put the whole number 10 in the variable side, then Java computes the result of 10 times 10 and places the result in the variable square. Finally, Java outputs 100, which is the final value of my variable square. In this case I chose my variable names to help me read the code. Even if I did not use int-type variables in project OxidizedPot_v0, I will need both numbers and strings in the development of my game Oxidized Pot.

[Alternative ways]
Perhaps the notation I am using to represent the state of my OP game is not visually very pleasing. I could have done it in a different way, like shown in project OxidizedPot_v0_1. I also renamed the variables to show that they can be totally arbitrary.

 [Exercises]
1. Starting from this situation (game state):
           WEEHPEPPEXEW
write down the sequence of states until the player victory. Then change the code of project OxidizedPot_v0 so that it writes all the steps you found.

2. Starting from this situation (game state):
          WPXEEPPHEPW
write down a sequence of states in which the player breaks as many pots as possible before finally reaching the X and winning. Change the code of project OxidizedPot_v0 so that it writes all the steps you found.

3. Perhaps the idea I had to change the notation in project OxidizedPot_v0_1 was not that good after all. Find another notation to represent the state of the game, one that is readable and better looking for you, and change the code to in project OxidizedPot_v0_1 to print the sequence of states according to your notation.

4. Change the code in project OxidizedPot_v0 so that the program still prints the same sequence of strings, but using only 1 variable.


No comments:

Post a Comment