While loop keeps entering an infinite loop, in my project 9 application

classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|

While loop keeps entering an infinite loop, in my project 9 application

Obij
        Please I need some assistance on an issue. I am creating some functions for a TicTacToeGame Jack application and in one of the class files (the TicTacToeGame Class file), inside the inputPlayerLetter() function, I created a while loop, with the test condition being that the while loop should keep running as long as a local variable letter is not "X" or "O",  while the code block inside the while loop is supposed to request for a letter ("X" or "O") from the player and once the player inputs "X" or "O" as letter (via the readLine function), the test condition will then be false and the loop will stop running. Whereas if the player inputs a different letter other than "X" or "O", or their capital forms, the loop should keep requesting for the correct letter, until the correct letter is entered.
     However, the issue is that even when the correct letter and form is entered, the loop keeps running (even though its test condition should no longer be true), it will still continue requesting for the player to select either "X" or "O". i have modified the test condition in the for loop in various ways, but the infinite loop still results whenever i test the code. Below is a link showing the screenshot of the while loop, while in an infinite loop oin the VM emulator :
https://www.dropbox.com/s/0dveb9hthpmd7ew/screenshot%202020-01-28%2013.51.37.png?dl=0

     Below is the code for my TicTacToeGame Jack Application. There are two class files, the TicTacToeGame class file on top and the Main class file, situated at the bottom. Thanks.

/** Provides the methods and variables required to play the TicTacToeGame
 *
 */
 
class TicTacToeGame{
   
   /* function lets the player typer which letter they want to be */
   function Array inputPlayerLetter(){
       var String letter;
           var Array inputLetters;
           let letter= Keyboard.readLine("Do you want to be X or O? Please type in capital letters: ");
           
            while (~(letter = "X") | ~(letter = "O")){
              let letter= Keyboard.readLine("Do you want to be X or O? Please type in capital letters: ");
           }
           
           let inputLetters= Array.new(2);
           let inputLetters[0]= " ";
           let inputLetters[1]= " ";
           
           //The first element in the array is the player's letter, the second is the computer's letter
           if(letter= "X"){
              let inputLetters[0]= "X";
                  let inputLetters[1]= "O";
                  return inputLetters;
           }
           else {
              let inputLetters[0]= "O";
                  let inputLetters[1]= "X";
                  return inputLetters;
           }
   }
}

/** Tests the TicTacToeGame class */

class Main{
    function void main(){
           //var TicTacToeGame tTTGame;
           //let tTTGame= TicTacToeGame.new();
           do TicTacToeGame.inputPlayerLetter();
           return;
        }
}
     
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
When you execute the line

let letter = "X";

what is actually stored in the variable 'letter'?

Try the following

let letter1 = "X";
let letter2 = "X";

and then check to see if letter1 = letter2.

Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
Thanks for the response. i did as you suggested, I created a function testLetter(), (see below) that tested if two variables letter1 and letter2 , which were both assigned "X", were the same. The function was supposed to print True, if both were the same, but the test failed. Please what do you suggest I should do, to get the test to work?

function void testLetter(){
          var String letter1, letter2;
           let letter1= "X";
           let letter2= "X";
           if(letter1 = letter2){
                do Output.printString("True");
           }
           return;
   }
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
The key is to read up and figure out the answer to the first question:

When you execute the line

let letter = "X";

what is actually stored in the variable 'letter'?

Remember, every variable in Jack occupies exactly one word of memory and can therefore store a single 16-bit value. To make it more obvious, what gets stored in the variable 's' in the following statement:

let s = "This string contains a lot more information than can be stored in 16 bits";

Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
I checked the vm output for the function testLetter and I discovered that on lines 406 (the function testLetter itself starts from line 403) and 411, was the command: push constant 88. When I checked the Hack  character set, I discovered that 88 is the character code for "X". Which means that the 2 lines referred to pushing the character code for "X"  (for the command let letter1/letter2 = "X") onto the stack for processing. I also confirmed this by changing the commands to let letter1/letter2 = "O" and when i compiled the code, the vm output for both lines 406 and 411 was: push constant 79 and 79 is also the character code for "O" on the hack platform.

This means the same digits were being stored in both letter1 and letter2 and if that is so, then how come the test for equality still fails?

Please could you give me more hints on how to go about solving this issue.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
Pushing the character code for 'X' onto the stack is not the same as storing the character code for 'X' in the variable 'letter'.

Your variable is of type String, which is a class.

What is always stored in a variable whose type is a class?
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
Sincerely, I don't know the answer to your question. Could you guide me on how I can find out?

Also, if we find out what is being stored there, I don't really have any way to change what is being stored there. Is that not another issue?
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
What does Chapter 9 have to say about variables, in particular object types?

Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
it said various things. For example. under Primitive types: 1. int: Non-negative 2's complement 16-bit integer,
2. boolean: true or false, 3. Char: Integer values representing characters. Under Class types: 1. OS types: String, Array, 2. User-defined: Fractions, List...;.

But i don't know exactly if it is what you 're referring to.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
We want to know about Strings, so let's see what the text has to say about Strings.

From Section 9.2.3:
Strings Strings are declared using a built-in class called String. The Jack compiler recognizes the syntax "xxx" and treats it as the contents of some String object.
So now we know that when we do

let letter = "X";

that "X" is treated as a String object. So how are objects treated?

Also from Section 9.2.3:

Object Types Every class defines an object type. As in Java, the declaration of an object variable only causes the creation of a reference variable (pointer). Memory for storing the object itself is allocated later, if and when the programmer actually constructs the object by calling a constructor. Figure 9.6 gives an example.
So what does Figure 9.6 tell us?

It shows some variables of a couple of classes being initialized in let statements and then says, very explicitly, that those variables hold the base addresses of the memory segments allocated to the two objects.

So, when you do a statement like

let letter = "X";

what does the value stored in the variable 'letter' represent?

Also note what else Figure 9.6 tells us.

If 'e' is an object variable and we do

let f = e;

then only the reference is copied, so 'f' and 'e' point to the exact same object -- change one and you change the other.


Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
I read what you wrote and I think the basics of it are: if letter is an object variable, then assigning a value to it, means that what is stored in letter is the base address in memory that contains the assigned value. Also, if you have two object variables, assigning one to the other means that they will both point to the same object.

But, forgive me, I 'm still stretching to see how the information can help me solve my issue, for instance, if you have two objects and you compare one to the other, shouldn't the compiler have a way to check if the values referenced by the two objects (that is the values in the two memory addresses contained in the two objects) are equal? That is, the compiler is not setting the pointers to be the same, like an assignment, but rather checking if the two values being pointed to, by the two pointers are equal? Isn't that my issue? And if it is, how can I use the information to resolve my issue?
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
      Also, inspired by what you wrote, I tried something, in the testLetter() function above, I assigned the letter1 variable "X", then assigned letter1 to letter2, instead of assigning "X" directly to letter2 and now ran the compiled code and this time, the comparison operator = (that tested the equality of the two variables) worked.
    Furthermore, I think my issue is some sort of bug, I don't know if there is anyway I can get another installation of the compiler, not the one I downloaded from the site, that I could try to see if it doesn't have this issue. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
It is not a bug. You still do not understand what is being stored there.

When you have "xxx" in your code, the compiler calls the String constructor that creates a String object that is allocated in the heap somewhere. What gets stored in the variable is what is returned by the constructor, which is the address at which the object is stored.

When you do

let letter1 = "X";
let letter2 = letter1;

They will compare as equal because they are the same object! The value at letter1 is the address where a String object is stored. You then copy that address and store the address in letter2. So you still have only a single String object and BOTH variables are pointing to it.

Do the following:

let letter1 = "This is a string";
let letter2 = letter1;

Now use the String methods to change one of the characters in letter1 to a $ and then print letter2.

What happens?
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
    letter2 printed exactly what was stored in letter1, including the alteration I made in letter1, after I assigned it to letter2. So in essence, they are pointing to the same object.

But how will that knowledge resolve my issue? In my case (the initial inputPlayerLetter function), the variable and the String constant are not pointing to the same object, but rather the variable is pointing to an object, whose value is same as the String constant.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
Hello,

I am still stuck with the same issue since yesterday and I am still hoping for any suggestion that can help me resolve my issue, especially since you insist that it is not a bug. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
In reply to this post by Obij
Obij wrote
letter2 printed exactly what was stored in letter1, including the alteration I made in letter1, after I assigned it to letter2. So in essence, they are pointing to the same object.

But how will that knowledge resolve my issue? In my case (the initial inputPlayerLetter function), the variable and the String constant are not pointing to the same object, but rather the variable is pointing to an object, whose value is same as the String constant.
But what is it that you are comparing?

Let's walk through an example in excruciating detail -- a level of detail that you need to learn how to work at.

What happens when you do:

let letter1 = "X";

"X" becomes a call to the String constructor, which calls Memory.alloc() to get enough memory to store a String object containing one character. The details of that object are hidden in the implementation of the String class, but it probably requests two or three words of memory in addition to the number of characters in the string in order to store the current length of the string and possible the maximum length. If it does, it will put those up front and then start storing the string data after that. So let's say that it calls alloc(3) and alloc() returns 2424, which is the base address of the memory block that was allocated. Let's say that the String library places the current length of the string at the base address, the max length of the string at the next address, and the string itself after that. So we would have

Address Contents
   2424      1 // The current length of the string
   2425      1 // The max length of the string
   2426     88 // The ASCII code for 'X'

Since letter1 is a variable of object type, the value that actually gets stored in that variable is the base address of the object, so

letter1 = 2424

Now you do

let letter2 = "X";

This same process is repeated and a different String object is created, say at address 2448, and now we have

letter2 = 2448

The CONTENTS of these two String objects is the same, but they are DIFFERENT objects stored at different memory locations. If you then check to see if they are equal by doing

if (letter1 = letter2)

the test will fail because you are checking if 2424 is equal to 2448 and they aren't. When you test for equality between to object variables, you are checking to see if they are the SAME object -- which is very different from checking to see if they are two different objects that happen to have identical content.


retto store the
Let's use an analogy.

Take two
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
Okay, I see your point, when I use the comparison operator = on 2 object variables in jack, I am actually testing to see if their base addresses are equal and since they one was not assigned to the other, the test will fail. To make it even, clearer I changed letter1 and letter2 to int variables and then assigned 9 to the two variables and when I tested them, the test passed. Which is in line with what the text said about primitive types, the actual data are stored in the primitive type variables.

So my question, how do you now test for equality between what the two objects refer to or point at? Instead of their base addresses? In other languages, like Java for example, you can do that.( In fact, in Java as I recall you cannot use the "==" operator to test for equality between two object variables, but a method, which is the equals() method.) How can you do so in Jack, as I have looked at the String API and there doesn't seem to be any method that does this. Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

WBahn
Administrator
You do just what you do in Java.

If you have a class TicTacToe which represents a tic-tac-toe board at some stage of play and you have two instances and want to see if they are equal, then you have to write your own equals() method.

You just do the same thing here.

In Chapter 12 you will implement all of the libraries, so you can add an equals(String s1) to the String class if you want.

In the meantime, you are free to implement a function in your Jack code, perhaps called

boolean areStringsEqual(String s1, String s2)

that does what you want.
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Lozminda
In reply to this post by Obij
Hi
I'm gonna put my foot in my mouth here, wouldn't using characters rather than strings here be useful ? As you're only using 'X' and 'O' ?

Would save all the hassle with String....

Lozminda
Reply | Threaded
Open this post in threaded view
|

Re: While loop keeps entering an infinite loop, in my project 9 application

Obij
In reply to this post by WBahn
Thanks. I resolved it by implementing such a function that tests whether two string letters are equal, by converting the string letters to characters and now testing the characters using the = comparison operator.
12