Author Topic: BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3 and C++)  (Read 110051 times)

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #15 on: September 01, 2008, 06:41:03 PM »
Chapter 19: OOP 2   (Just a 'place holder' ... for now ...)


   1.      Create (md) a sub-directory in the project folder. Give it the name Chapt19_OOP2
   2.      Go (cd) to that new directory.
   3.      Using your text editor, create the following program file in that folder. Give the program file the name vectorClass1.hla
   4.      Compile the program and run it. Study the comments that are in the hla program, as well as the output that appears on the screen when you run the program.


 
Our first CLASS ACT ... and a lot of behind the scenes work ... to get the (little) facility (here) we desire ... but then ...we have gained considerable power for the next class act to use as a spring board ... and so on ...  i.e. if we have designed our class a little classy, thinking ahead about future objects that might build on this class?


program vectorClass1;

#include( "stdlib.hhf" )


type
    Vector:
        class   
            var
                x:    real32;
                y:    real32;
            procedure create;       
            procedure get_x; @returns( "st0" );
            procedure get_y; @returns( "st0" );
            method set_x( r:real32 );
            method set_y( r:real32 );
            method takeIn;       
            procedure display;
            procedure findLength; @returns( "st0" );       
            procedure findAngle; @returns( "st0" );               
        endclass;
       


const     
    radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
   
    zeroVector:    dword :=     1024;    // 1024..65535 are numbers ok to use for user exceptions
   
   
       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;



// Returns the length of a vector
// on the top of the FPU stack.

procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );         // now have x in st0
    fld( st0 );            // Duplicate x on TOS.
    fmulp();              // Compute x*x.
   
    fld( this.y );         // now have y in st0
    fld( st0 );            // Duplicate y.
    fmulp();              // Compute y*y.
   
    faddp();              // Compute x*x + y*y
    fsqrt();                // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.

procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0

            /*
            if( !al ) then         // consider ALSO as zero if (r < 1.0e-10)
           
                fabs();            // take positive value
                fld( 1.0e-10 );
                fcompp();
                fstsw( ax );
                sahf();
                setb( al );       // AL = true if ST1 < ST0.
            endif;
            */

            fstp( st0 );        // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );          // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        if( isZero( this.x ) ) then raise( zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
       
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );            // now have y in st0
        fld( this.x );            // now have x in st0, and y in st1
        fpatan();                // take arctan(st1/st0) and store in st1; pop stack
        fmulp( radTodeg );  // convert to degrees
       
    endif;
   
end findAngle;




static

    VMT( Vector );
   
    v1:            Vector;
    v2:            Vector;
   
    len:           real32;
    angle:        real32;   
   
   
   
begin vectorClass1;

    finit();     // initialize the FPU
   
    try
       
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end vectorClass1;



We commonly divide the above program up into three parts or modules, each in its own file: ( For simplicity here, we may put all 3 of these new files into our working directory ... so the compiler will know where to find them when it is compiling.)

   1. Our main program file, (let's rename it as test_vectorClass.hla). It will also have this line near its top ... #include( "vectorClass.hhf" )
   2. The header file itself, that includes any header files, any constants, macros, etc. that the class will use ... and declares the class prototypes ... we'll call it vectorClass.hhf
   3. The class definition itself, (let's name this file vectorClass.hla).  This file will ALSO have a line like this near its top: #include( "vectorClass.hhf" )


    * And we can THEN compile/assemble these files into one exeucutable file with this command line command: HLA   test_vectorClass   vectorClass

    * If all goes well, we will have the desired executable file with the name test_vectorClass.exe in the working folder. ( Also ... the files test_vectorClass.obj and vectorClass.obj )
    * If we make any changes to our test file, (or make a new program to use our vectorClass), but ... have not made any changes to our vectorClass, we don't need to assemble the vectorClass.hla file again into an obj file.
    * This is how we would make our new executable, if we just changed our test program and so need to re-compile it:

HLA   test_vectorClass   vectorClass.obj

    * Note the ending of obj on the last file above.  It hasn't changed ... so HLA can just link it in ... in the new executable of the new test file.


Well ... there are a few more fine details also needed ... like adding @external; after all the procedure / method prototypes in the header file ...

So here are these 3 FILES:




1. // File name is: test_vectorClass.hla //

program test_vectorClass;

#include( "vectorClass.hhf" )

static
    // VMT( Vector );     // moved to near the top of the file vectorClass.hla //
                                     //    ***  See ALSO the comments there!!!  ***   //
   
    v1:        Vector;
    v2:        Vector;
   
    len:        real32;
    angle:    real32;   
   
   
begin test_vectorClass;

    finit();     // initialize the FPU
   
    try
   
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( Vector.zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end test_vectorClass;




2. // File name is: vectorClass.hhf //

#include ( "stdlib.hhf" )


type
    Vector:
        class   

            const     
                radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
                zeroVector:    uns32 :=     1024;

            var
                x:    real32;
                y:    real32;

            procedure create; @external;   
            procedure get_x; @returns( "st0" ); @external;
            procedure get_y; @returns( "st0" ); @external;
            method set_x( r:real32 ); @external;
            method set_y( r:real32 ); @external;
            method takeIn; @external;       
            procedure display; @external;
            procedure findLength; @returns( "st0" ); @external;       
            procedure findAngle; @returns( "st0" );    @external;
           
        endclass;




3. // file name is: vectorClass.hla //

unit vectorClass;

#include( "vectorClass.hhf" )   


static
    VMT( Vector );    // MUST go here, ( and NOT in header file ) ...
                                // so as NOT to be defined twice when the
                                // "vectorClass.hhf" is ALSO included in the main program.


       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;


// Returns the length of a vector
// on the top of the FPU stack.
procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );      // now have x in st0
    fld( st0 );         // Duplicate x on TOS.
    fmulp();           // Compute x*x.
   
    fld( this.y );      // now have y in st0
    fld( st0 );         // Duplicate y.
    fmulp();           // Compute y*y.
   
    faddp();          // Compute x*x + y*y
    fsqrt();            // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.
procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0
            //
            //if( !al ) then        // consider ALSO as zero if (r < 1.0e-10)
            //
            //    fabs();            // take positive value
            //    fld( 1.0e-10 );
            //    fcompp();
            //    fstsw( ax );
            //    sahf();
            //    setb( al );       // AL = true if ST1 < ST0.
            //endif;
            //
            fstp( st0 );            // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );           // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        //assert( !isZero( this.x ) );
        if( isZero( this.x ) ) then raise( Vector.zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
     
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );                        // now have y in st0
        fld( this.x );                        // now have x in st0,  y in st1
        fpatan();                            // take arctan(st1/st0) and store in st1; pop stack
        fmulp( Vector.radTodeg );   // convert to degrees
       
    endif;
   
end findAngle;

end vectorClass;


Remember to compile/assemble like this (on the command line):

HLA    test_vectorClass   vectorClass

That way, the unit file gets compiled to an obj file and then both of the new .obj files ... test_vectorClass.obj   and   vectorClass.obj ... are liked together into the one executable file test_vectorClass.exe

Now we have three modules ... the main program file, the Class header file, and the Class definition file.  If we were to add another class to our program, we would then probably add two more files ... say ... otherClass.hhf ... otherClass.hla.  Of course, we would then have to #include( "otherClass.hhf" ) in our main program along with any other changes required TO USE this 2nd class. (Remember to also #include( "otherClass.hhf" ) inside and near the top of otherClass.hla.)

If there were no changes to our 1st class definition ... we could use a command line command to compile the project like this: (If there were, we could just add it to the top line,  and remove the -c ... to produce the exe file all in one step. )

HLA   -c   test_vectorClass   otherClass

Followed by this

HLA   test_vectorClass.obj   vectorClass.obj   otherClass.obj

Get the drift ...?


...
« Last Edit: September 02, 2008, 04:35:39 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #16 on: September 02, 2008, 04:28:09 AM »
Chapter 19: OOP 2 ....(Just a 'place holder' here ... for now.)


   1.      Create (md) a sub-directory in the project folder. Give it the name Chapt19_OOP2
   2.      Go (cd) to that new directory.
   3.      Using your text editor, create the following program file in that folder. Give the program file the name vectorClass1.hla
   4.      Compile the program and run it. Study the comments that are in the hla program, as well as the output that appears on the screen when you run the program.


 
Our first CLASS ACT ... and a lot of behind the scenes work ... to get the (little) facility (here) we desire ... but then ...we have gained considerable power for the next class act to use as a spring board ... and so on ...  i.e. if we have designed our class a little classy, thinking ahead about future objects that might build on this class?


program vectorClass1;

#include( "stdlib.hhf" )


type
    Vector:
        class   
            var
                x:    real32;
                y:    real32;
            procedure create;       
            procedure get_x; @returns( "st0" );
            procedure get_y; @returns( "st0" );
            method set_x( r:real32 );
            method set_y( r:real32 );
            method takeIn;       
            procedure display;
            procedure findLength; @returns( "st0" );       
            procedure findAngle; @returns( "st0" );               
        endclass;
       


const     
    radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
   
    zeroVector:    dword :=     1024;    // 1024..65535 are numbers ok to use for user exceptions
   
   
       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;



// Returns the length of a vector
// on the top of the FPU stack.

procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );         // now have x in st0
    fld( st0 );            // Duplicate x on TOS.
    fmulp();              // Compute x*x.
   
    fld( this.y );         // now have y in st0
    fld( st0 );            // Duplicate y.
    fmulp();              // Compute y*y.
   
    faddp();              // Compute x*x + y*y
    fsqrt();                // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.

procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0

            /*
            if( !al ) then         // consider ALSO as zero if (r < 1.0e-10)
           
                fabs();            // take positive value
                fld( 1.0e-10 );
                fcompp();
                fstsw( ax );
                sahf();
                setb( al );       // AL = true if ST1 < ST0.
            endif;
            */

            fstp( st0 );        // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );          // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        if( isZero( this.x ) ) then raise( zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
       
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );            // now have y in st0
        fld( this.x );            // now have x in st0, and y in st1
        fpatan();                // take arctan(st1/st0) and store in st1; pop stack
        fmulp( radTodeg );  // convert to degrees
       
    endif;
   
end findAngle;




static

    VMT( Vector );
   
    v1:            Vector;
    v2:            Vector;
   
    len:           real32;
    angle:        real32;   
   
   
   
begin vectorClass1;

    finit();     // initialize the FPU
   
    try
       
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end vectorClass1;



We commonly divide the above program up into three parts or modules, each in its own file: ( For simplicity here, we may put all 3 of these new files into our working directory ... so the compiler will know where to find them when it is compiling.)

   1. Our main program file, (let's rename it as test_vectorClass.hla). It will also have this line near its top ... #include( "vectorClass.hhf" )
   2. The header file itself, that includes any header files, any constants, macros, etc. that the class will use ... and declares the class prototypes ... we'll call it vectorClass.hhf
   3. The class definition itself, (let's name this file vectorClass.hla).  This file will ALSO have a line like this near its top: #include( "vectorClass.hhf" )


    * And we can THEN compile/assemble these files into one exeucutable file with this command line command: HLA   test_vectorClass   vectorClass

    * If all goes well, we will have the desired executable file with the name test_vectorClass.exe in the working folder. ( Also ... the files test_vectorClass.obj and vectorClass.obj )
    * If we make any changes to our test file, (or make a new program to use our vectorClass), but ... have not made any changes to our vectorClass, we don't need to assemble the vectorClass.hla file again into an obj file.
    * This is how we would make our new executable, if we just changed our test program and so need to re-compile it:

HLA   test_vectorClass   vectorClass.obj

    * Note the ending of obj on the last file above.  It hasn't changed ... so HLA can just link it in ... in the new executable of the new test file.


Well ... there are a few more fine details also needed ... like adding @external; after all the procedure / method prototypes in the header file ...

So here are these 3 FILES:




1. // File name is: test_vectorClass.hla //

program test_vectorClass;

#include( "vectorClass.hhf" )

static
    // VMT( Vector );     // moved to near the top of the file vectorClass.hla //
                                     //    ***  See ALSO the comments there!!!  ***   //
   
    v1:        Vector;
    v2:        Vector;
   
    len:        real32;
    angle:    real32;   
   
   
begin test_vectorClass;

    finit();     // initialize the FPU
   
    try
   
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( Vector.zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end test_vectorClass;




2. // File name is: vectorClass.hhf //

#include ( "stdlib.hhf" )


type
    Vector:
        class   

            const     
                radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
                zeroVector:    uns32 :=     1024;

            var
                x:    real32;
                y:    real32;

            procedure create; @external;   
            procedure get_x; @returns( "st0" ); @external;
            procedure get_y; @returns( "st0" ); @external;
            method set_x( r:real32 ); @external;
            method set_y( r:real32 ); @external;
            method takeIn; @external;       
            procedure display; @external;
            procedure findLength; @returns( "st0" ); @external;       
            procedure findAngle; @returns( "st0" );    @external;
           
        endclass;




3. // file name is: vectorClass.hla //

unit vectorClass;

#include( "vectorClass.hhf" )   


static
    VMT( Vector );    // MUST go here, ( and NOT in header file ) ...
                                // so as NOT to be defined twice when the
                                // "vectorClass.hhf" is ALSO included in the main program.


       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;


// Returns the length of a vector
// on the top of the FPU stack.
procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );      // now have x in st0
    fld( st0 );         // Duplicate x on TOS.
    fmulp();           // Compute x*x.
   
    fld( this.y );      // now have y in st0
    fld( st0 );         // Duplicate y.
    fmulp();           // Compute y*y.
   
    faddp();          // Compute x*x + y*y
    fsqrt();            // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.
procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0
            //
            //if( !al ) then        // consider ALSO as zero if (r < 1.0e-10)
            //
            //    fabs();            // take positive value
            //    fld( 1.0e-10 );
            //    fcompp();
            //    fstsw( ax );
            //    sahf();
            //    setb( al );       // AL = true if ST1 < ST0.
            //endif;
            //
            fstp( st0 );            // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );           // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        //assert( !isZero( this.x ) );
        if( isZero( this.x ) ) then raise( Vector.zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
     
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );                        // now have y in st0
        fld( this.x );                        // now have x in st0,  y in st1
        fpatan();                            // take arctan(st1/st0) and store in st1; pop stack
        fmulp( Vector.radTodeg );   // convert to degrees
       
    endif;
   
end findAngle;

end vectorClass;


Remember to compile/assemble like this (on the command line):

HLA    test_vectorClass   vectorClass

That way, the unit file gets compiled to an obj file and then both of the new .obj files ... test_vectorClass.obj   and   vectorClass.obj ... are liked together into the one executable file test_vectorClass.exe

Now we have three modules ... the main program file, the Class header file, and the Class definition file.  If we were to add another class to our program, we would then probably add two more files ... say ... otherClass.hhf ... otherClass.hla.  Of course, we would then have to #include( "otherClass.hhf" ) in our main program along with any other changes required TO USE this 2nd class. (Remember to also #include( "otherClass.hhf" ) inside and near the top of otherClass.hla.)

If there were no changes to our 1st class definition ... we could use a command line command to compile the project like this: (If there were, we could just add it to the top line,  and remove the -c ... to produce the exe file all in one step. )

HLA   -c   test_vectorClass   otherClass

Followed by this

HLA   test_vectorClass.obj   vectorClass.obj   otherClass.obj

Get the drift ...?



« Last Edit: September 02, 2008, 04:33:01 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #17 on: September 02, 2008, 04:31:58 AM »
Chapter 19: OOP 2 ... (Just reserving some contiguous space ... for now.)


   1.      Create (md) a sub-directory in the project folder. Give it the name Chapt19_OOP2
   2.      Go (cd) to that new directory.
   3.      Using your text editor, create the following program file in that folder. Give the program file the name vectorClass1.hla
   4.      Compile the program and run it. Study the comments that are in the hla program, as well as the output that appears on the screen when you run the program.


 
Our first CLASS ACT ... and a lot of behind the scenes work ... to get the (little) facility (here) we desire ... but then ...we have gained considerable power for the next class act to use as a spring board ... and so on ...  i.e. if we have designed our class a little classy, thinking ahead about future objects that might build on this class?


program vectorClass1;

#include( "stdlib.hhf" )


type
    Vector:
        class   
            var
                x:    real32;
                y:    real32;
            procedure create;       
            procedure get_x; @returns( "st0" );
            procedure get_y; @returns( "st0" );
            method set_x( r:real32 );
            method set_y( r:real32 );
            method takeIn;       
            procedure display;
            procedure findLength; @returns( "st0" );       
            procedure findAngle; @returns( "st0" );               
        endclass;
       


const     
    radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
   
    zeroVector:    dword :=     1024;    // 1024..65535 are numbers ok to use for user exceptions
   
   
       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;



// Returns the length of a vector
// on the top of the FPU stack.

procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );         // now have x in st0
    fld( st0 );            // Duplicate x on TOS.
    fmulp();              // Compute x*x.
   
    fld( this.y );         // now have y in st0
    fld( st0 );            // Duplicate y.
    fmulp();              // Compute y*y.
   
    faddp();              // Compute x*x + y*y
    fsqrt();                // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.

procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0

            /*
            if( !al ) then         // consider ALSO as zero if (r < 1.0e-10)
           
                fabs();            // take positive value
                fld( 1.0e-10 );
                fcompp();
                fstsw( ax );
                sahf();
                setb( al );       // AL = true if ST1 < ST0.
            endif;
            */

            fstp( st0 );        // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );          // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        if( isZero( this.x ) ) then raise( zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
       
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );            // now have y in st0
        fld( this.x );            // now have x in st0, and y in st1
        fpatan();                // take arctan(st1/st0) and store in st1; pop stack
        fmulp( radTodeg );  // convert to degrees
       
    endif;
   
end findAngle;




static

    VMT( Vector );
   
    v1:            Vector;
    v2:            Vector;
   
    len:           real32;
    angle:        real32;   
   
   
   
begin vectorClass1;

    finit();     // initialize the FPU
   
    try
       
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end vectorClass1;



We commonly divide the above program up into three parts or modules, each in its own file: ( For simplicity here, we may put all 3 of these new files into our working directory ... so the compiler will know where to find them when it is compiling.)

   1. Our main program file, (let's rename it as test_vectorClass.hla). It will also have this line near its top ... #include( "vectorClass.hhf" )
   2. The header file itself, that includes any header files, any constants, macros, etc. that the class will use ... and declares the class prototypes ... we'll call it vectorClass.hhf
   3. The class definition itself, (let's name this file vectorClass.hla).  This file will ALSO have a line like this near its top: #include( "vectorClass.hhf" )


    * And we can THEN compile/assemble these files into one exeucutable file with this command line command: HLA   test_vectorClass   vectorClass

    * If all goes well, we will have the desired executable file with the name test_vectorClass.exe in the working folder. ( Also ... the files test_vectorClass.obj and vectorClass.obj )
    * If we make any changes to our test file, (or make a new program to use our vectorClass), but ... have not made any changes to our vectorClass, we don't need to assemble the vectorClass.hla file again into an obj file.
    * This is how we would make our new executable, if we just changed our test program and so need to re-compile it:

HLA   test_vectorClass   vectorClass.obj

    * Note the ending of obj on the last file above.  It hasn't changed ... so HLA can just link it in ... in the new executable of the new test file.


Well ... there are a few more fine details also needed ... like adding @external; after all the procedure / method prototypes in the header file ...

So here are these 3 FILES:




1. // File name is: test_vectorClass.hla //

program test_vectorClass;

#include( "vectorClass.hhf" )

static
    // VMT( Vector );     // moved to near the top of the file vectorClass.hla //
                                     //    ***  See ALSO the comments there!!!  ***   //
   
    v1:        Vector;
    v2:        Vector;
   
    len:        real32;
    angle:    real32;   
   
   
begin test_vectorClass;

    finit();     // initialize the FPU
   
    try
   
        v1.create();
        v1.takeIn();
        v1.findLength();
        fstp( len );
        stdout.puts( "The length of v1 " );
        v1.display();
        stdout.put( " is: ", len );
        v1.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v1 is: ", angle, nl nl  );
       
        v2.create();
        v2.takeIn();
        v2.findLength();
        fstp( len );
        stdout.put( "The length of v2 " );
        v2.display();
        stdout.put( " is: ", len );
        v2.findAngle();
        fstp( angle );
        stdout.put( nl "The angle of v2 is: ", angle, nl nl );
       
    exception( Vector.zeroVector );
            stdout.puts( nl nl "Zero vector has no defined direction. " nl );
           
    anyexception
        stdout.puts( nl nl "Some exception occured ... perhaps invalid data?" nl  );
   
    endtry;
   
end test_vectorClass;




2. // File name is: vectorClass.hhf //

#include ( "stdlib.hhf" )


type
    Vector:
        class   

            const     
                radTodeg:    real32:=    360 / ( 2 * 3.1415926535897932384626433833 );
                zeroVector:    uns32 :=     1024;

            var
                x:    real32;
                y:    real32;

            procedure create; @external;   
            procedure get_x; @returns( "st0" ); @external;
            procedure get_y; @returns( "st0" ); @external;
            method set_x( r:real32 ); @external;
            method set_y( r:real32 ); @external;
            method takeIn; @external;       
            procedure display; @external;
            procedure findLength; @returns( "st0" ); @external;       
            procedure findAngle; @returns( "st0" );    @external;
           
        endclass;




3. // file name is: vectorClass.hla //

unit vectorClass;

#include( "vectorClass.hhf" )   


static
    VMT( Vector );    // MUST go here, ( and NOT in header file ) ...
                                // so as NOT to be defined twice when the
                                // "vectorClass.hhf" is ALSO included in the main program.


       
procedure Vector.create; @nodisplay; @noframe;
begin create;

    push( eax );

    if( esi = 0 ) then
        mem.alloc( @size( Vector ) );
        mov( eax, esi );
    endif;
   
    mov( &Vector._VMT_, this._pVMT_ );

     pop( eax );
     ret();

end create;


procedure Vector.get_x; @nodisplay; @noframe; // @returns( "st0" );
begin get_x;
    fld( this.x );
    ret();
end get_x;

method Vector.set_x( r:real32 ); @nodisplay;
begin set_x;
    fld( r );
    fstp( this.x );
end set_x;


procedure Vector.get_y; @nodisplay; @noframe; // @returns( "st0" );
begin get_y;
    fld( this.y  );
    ret();
end get_y;

method Vector.set_y( r:real32 ); @nodisplay;
begin set_y;
    fld( r );
    fstp( this.y );
end set_y;


method Vector.takeIn; @nodisplay;
begin takeIn;
    stdout.puts( "Enter vector x,y : " );
    stdin.get( this.x, this.y  );
end takeIn;


procedure Vector.display; @nodisplay;
begin display;
    stdout.put( "(", this.x, ",", this.y, ")" );
end display;


// Returns the length of a vector
// on the top of the FPU stack.
procedure Vector.findLength; @nodisplay; // @returns( "st0" );
begin findLength;

    fld( this.x );      // now have x in st0
    fld( st0 );         // Duplicate x on TOS.
    fmulp();           // Compute x*x.
   
    fld( this.y );      // now have y in st0
    fld( st0 );         // Duplicate y.
    fmulp();           // Compute y*y.
   
    faddp();          // Compute x*x + y*y
    fsqrt();            // Compute sqrt( x*x + y*y ).
   
end findLength;



// Returns the angle of a vector in degrees cc, w.r.t.
// x --> zero degrees ... on the top of the FPU stack.
procedure Vector.findAngle; @nodisplay; // @returns( "st0" );

        procedure isZero( r:real32 ); @nodisplay; @returns( "al" );
        begin isZero;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            sete( al );            // Set AL to 1 if TOS = 0.0
            //
            //if( !al ) then        // consider ALSO as zero if (r < 1.0e-10)
            //
            //    fabs();            // take positive value
            //    fld( 1.0e-10 );
            //    fcompp();
            //    fstsw( ax );
            //    sahf();
            //    setb( al );       // AL = true if ST1 < ST0.
            //endif;
            //
            fstp( st0 );            // NOW ... pop ST0=r off the top of the stack.
       
        end isZero;
       
        procedure isPos( r:real32 ); @nodisplay; @returns( "al" );
        begin isPos;
       
            fld( r );
            // The  FTST instruction compares the value in ST0 against 0.0
            // Note that this instruction does not differentiate -0.0 from +0.0
            // If the value in ST0 is either of these values, ftst will set C 3
            // to denote equality. Note that this instruction does *NOT POP* st(0)
            // off the stack ...
            ftst();
            fstsw( ax );
            sahf();
            seta( al );            // Set AL to 1 if TOS > 0.0
            fstp( st0 );           // NOW ... pop ST0 off the top of the stack.
           
        end isPos;

begin findAngle;

    if( isZero( this.y ) ) then
   
        //assert( !isZero( this.x ) );
        if( isZero( this.x ) ) then raise( Vector.zeroVector );
        elseif( isPos( this.x ) ) then  fld( 0.0 );
        else fld( 180.0 );
        endif;
     
    elseif( isZero( this.x ) ) then
   
        if( isPos( this.y ) ) then fld( 90.0 );
        else fld( -90.0 );
        endif;
       
    else
        fld( this.y );                        // now have y in st0
        fld( this.x );                        // now have x in st0,  y in st1
        fpatan();                            // take arctan(st1/st0) and store in st1; pop stack
        fmulp( Vector.radTodeg );   // convert to degrees
       
    endif;
   
end findAngle;

end vectorClass;


Remember to compile/assemble like this (on the command line):

HLA    test_vectorClass   vectorClass

That way, the unit file gets compiled to an obj file and then both of the new .obj files ... test_vectorClass.obj   and   vectorClass.obj ... are liked together into the one executable file test_vectorClass.exe

Now we have three modules ... the main program file, the Class header file, and the Class definition file.  If we were to add another class to our program, we would then probably add two more files ... say ... otherClass.hhf ... otherClass.hla.  Of course, we would then have to #include( "otherClass.hhf" ) in our main program along with any other changes required TO USE this 2nd class. (Remember to also #include( "otherClass.hhf" ) inside and near the top of otherClass.hla.)

If there were no changes to our 1st class definition ... we could use a command line command to compile the project like this: (If there were, we could just add it to the top line,  and remove the -c ... to produce the exe file all in one step. )

HLA   -c   test_vectorClass   otherClass

Followed by this

HLA   test_vectorClass.obj   vectorClass.obj   otherClass.obj

Get the drift ...?





« Last Edit: September 02, 2008, 04:34:07 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #18 on: September 02, 2008, 04:43:05 AM »
Chapter 20: Shaping OPP ... (Just a 'place holder ... for now.)



In this (final) chapter (for now) ... I will attempted to give a little flavour of some of HLA's OPP capabilities.  These next two programs are updates and modifications to programs written by Randall Hyde, the author of HLA. (Updated to use the current console functions that work for both LINUX and MS Windows ...)

These two prgrams each are in a similar 3-file package.

    * To compile / assemble the first set of 3 files, use this command on the command line:  hla  ShapesDemo  Shapes
    * the files you will need in your working directory are:  shapesDemo.hla shapes.hhf and shapes.hla
    * Here are these first 3 files: ( The next three will follow.)





program shapesDemo;

// Modified from: AoA_Electronic\Volume4\Ch10

// This is a simple demonstration program that
// shows how to use the shape objects in the
// shape, rect, roundrect, and diamond classes.


#include( "stdlib.hhf" )
#includeonce( "shapes.hhf" )

type
    pShape: pointer to shape;
  

// Allocate storage for various shapes:

static
    aRect1: pointer to rect;
    aRect2: pointer to rect;
    aRect3: pointer to rect;
  
    aRrect1: pointer to roundrect;
    aRrect2: pointer to roundrect;
    aRrect3: pointer to roundrect;

    aDiamond1: pointer to diamond;
    aDiamond2: pointer to diamond;
    aDiamond3: pointer to diamond;

    // We'll create a list of generic objects
    // in the following array in order to demonstrate
    // virtual method calls and polymorphism.
      
    DrawList: pShape[9];
  
begin shapesDemo;

    console.cls();
  
    // Initialize various rectangle, roundrect, and diamond objects.
    // This code also stores pointers to each of these objects in
    // the DrawList array.
  
    mov( rect.create(), aRect1 ); mov( esi, DrawList[0*4] );
    mov( rect.create(), aRect2 ); mov( esi, DrawList[1*4] );
    mov( rect.create(), aRect3 ); mov( esi, DrawList[2*4] );
  
    mov( roundrect.create(), aRrect1 ); mov( esi, DrawList[3*4] );
    mov( roundrect.create(), aRrect2 ); mov( esi, DrawList[4*4] );
    mov( roundrect.create(), aRrect3 ); mov( esi, DrawList[5*4] );
  
    mov( diamond.create(), aDiamond1 ); mov( esi, DrawList[6*4] );
    mov( diamond.create(), aDiamond2 ); mov( esi, DrawList[7*4] );
    mov( diamond.create(), aDiamond3 ); mov( esi, DrawList[8*4] );
  

    // Size and position each of these objects:
  
    aRect1.resize( 7, 7 );
    aRect1.moveTo( 10, 10 );
  
    aRect2.resize( 10, 10 );
    aRect2.moveTo( 15, 15 );
  
    aRect3.resize( 23, 9 );
    aRect3.moveTo( 20, 12 );


    aRrect1.resize( 9, 9 );
    aRrect1.moveTo( 40, 10 );
    // aRrect1.fill( false );
  
    aRrect2.resize( 10, 10 );
    aRrect2.moveTo( 45, 15 );
  
    aRrect3.resize( 29, 7 );
    aRrect3.moveTo( 50, 16 );
    // aRrect3.fill( false );
  

    aDiamond1.resize( 8, 8 );
    aDiamond1.moveTo( 20, 0 );
  
    aDiamond2.resize( 10, 10 );
    aDiamond2.moveTo( 21, 1 );
  
    aDiamond3.resize( 14, 14 );
    aDiamond3.moveTo( 22, 2 );
  
  
    // Note for the real fun, draw all of the objects
    // on the screen using the following simple loop.
  
    for( mov( 0, ebx ); ebx < 9; inc( ebx )) do
  
        DrawList.draw[ ebx*4 ]();
      
    endfor;

    console.gotorc( 9, 25 );
    stdout.puts( "THE END!" );
    console.gotorc( 19, 53 );
    stdout.puts( "Press Enter to exit ..." );
    stdin.readLn();

end shapesDemo;




// file name is: shapes.hhf //

type

    // Generic shape class:
  
    shape: class

        const

            maxC:           uns32 := 80;
            maxR:           uns32 := 25;

        var
            C:                  uns32;
            R:                  uns32;
            width:            uns32;
            height:            uns32;
            fillShape:        boolean;

        procedure create; returns( "esi" ); @external;
        
        method draw; abstract;
        method fill( f:boolean ); @external;
        method moveTo( C:uns32; R:uns32 );  @external;
        method resize( width: uns32; height: uns32 );  @external;

    endclass;



    // Class for a rectangle shape
    //
    //       +------+
    //        |          |
    //       +------+
  
    rect: class inherits( shape )

        override procedure create;  @external;
        override method draw; @external;

    endclass;
  
  
  
    // Class for a rounded rectangle shape
    //
    //     --------
    //    /           \
    //   |             |
    //   \            /
    //    --------
  
    roundrect: class inherits( shape )
  
        override procedure create; @external;
        override method draw;  @external;
        
    endclass;
  
  
    // Class for a diamond shape
    //
    //        /\
    //       /  \
    //      \  /
    //       \/
  
    diamond: class inherits( shape )
  
        override procedure create; @external;
        override method resize;     @external;
        override method draw;  @external;
        
    endclass;
          



// continued on next page ....

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #19 on: September 02, 2008, 04:44:25 AM »
// continued from previous page ....



// file name is: shapes.hla //

unit Shapes;

#includeonce( "stdlib.hhf" )
#includeonce( "shapes.hhf" )


// Emit the virtual method tables for the classes:

static
    vmt( shape );
    vmt( rect );
    vmt( roundrect );
    vmt( diamond );



/*********************************************************************/

// Generic shape methods and procedures



// Constructor for the shape class.
//
//    Note: this should really be an abstract procedure, but since
//    HLA doesn't support abstract procedures we'll fake it by
//    raising an exception if somebody tries to call this proc.

procedure shape.create; @nodisplay; @noframe;
begin create;

    // This should really be an abstract procedure,
    // but such things don't exist, so we will fake it.

    raise( ex.ExecutedAbstract );

end create;


// Generic shape.fill method.
// This is an accessor function that sets the "fill" field
// to the value of the parameter.

method shape.fill( f:boolean ); @nodisplay;
begin fill;

    push( eax );
    mov( f, al );
    mov( al, this.fillShape );
    pop( eax );

end fill;

// Generic shape.moveTo method.
// Checks the coordinates passed as a parameter and
// then sets the (C,R) coordinates of the underlying
// shape object to these values.

method shape.moveTo( C:uns32; R:uns32 ); @nodisplay;
begin moveTo;

    push( eax );
    push( ebx );


    mov( C, eax );
    assert( eax < shape.maxC );
    mov( eax, this.C );

    mov( R, eax );
    assert( eax < shape.maxR );
    mov( eax, this.R );

    pop( ebx );
    pop( eax );

end moveTo;


// Generic shape.resize method.
// Sets the width and height fields of the underlying object
// to the values passed as parameters.
//
// Note: Ignores resize request if the size is less than 2x2.

method shape.resize( width:uns32; height:uns32 ); @nodisplay;
begin resize;

    push( eax );
    assert( width <= shape.maxC );
    assert( height <= shape.maxR );

    if( width > 2 ) then
   
        if( height > 2 ) then
   
            mov( width, eax );
            mov( eax, this.width );
           
       
            mov( height, eax );
            mov( eax, this.height );
       
        endif;
               
    endif;
    pop( eax );

end resize;


/*******************/
/*                 */
/* rect's methods: */
/*                 */
/*******************/


// Constructor for the rectangle class:

procedure rect.create; @nodisplay; @noframe;
begin create;

    push( eax );

    // If called as rect.create, then allocate a new object
    // on the heap and return the pointer in ESI.
   
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
   
    // Initialize the pointer to the VMT:
   
    mov( &rect._VMT_, this._pVMT_ );

    // Initialize fields to create a non-filled unit square.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );
    mov( eax, this.height );
    mov( eax, this.width );

    pop( eax );
    ret();

end create;


// Here's the method to draw a text-based square on the display.

method rect.draw; @nodisplay;
static
    horz: str.strvar( shape.maxC ); // Holds "+------...--+"
    spcs: str.strvar( shape.maxC );    // Holds "      ...    " for fills.

begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
   
    // Initialize the horz and spcs strings to speed up
    // drawing our rectangle.
   
    mov( this.width, ebx );
    str.setstr( '-', horz, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
    mov( horz, eax );
    mov( '+', (type char [eax]));
    mov( '+', (type char [eax+ebx-1]));
   
    // If the fillShape field contains true, then we
    // need to fill in the characters inside the rectangle.
    // If this is false, we don't want to overwrite the
    // text in the center of the rectangle.  The following
    // code initializes spcs to all spaces or the empty string
    // to accomplish this.
   
    if( this.fillShape ) then
                           
        sub( 2, ebx );
        str.setstr( ' ', spcs, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
       
    else
   
        str.cpy( "", spcs );
       
    endif;
   
    // Okay, position the cursor and draw
    // our rectangle.
   
    console.gotorc( this.R, this.C );
    stdout.puts( horz );    // Draws top horz line.
   
    // For each row except the top and bottom rows,
    // draw "|" characters on the left and right
    // hand sides and the fill characters (if fillShape
    // is true) inbetween them.
   
    mov( this.R, ecx );
    mov( ecx, ebx );
    add( this.height, ebx );
    inc( ecx );
    dec( ebx );
    while( ecx < ebx) do
   
        console.gotorc( ecx, this.C );
        stdout.putc( '|' );
        stdout.puts( spcs );
        mov( this.C, edx );
        add( this.width, edx );
        dec( edx );
        console.gotorc( ecx, edx );
        stdout.putc( '|' );
        inc( ecx );
               
    endwhile;
   
    // Draw the bottom horz bar:
   
    console.gotorc( ecx, this.C );
    stdout.puts( horz );

    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;



/************************ /
/*                                             */
/*      roundrect's methods:       */
/*                                             */
/************************/


// This is the constructor for the roundrect class.
// See the comments in rect.create for details
// (since this is just a clone of that code with
//  minor changes here and there).

procedure roundrect.create; @nodisplay; @noframe;
begin create;

    push( eax );
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
    mov( &roundrect._VMT_, this._pVMT_ );

    // Initialize fields to create a non-filled unit square.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );
    mov( eax, this.height );
    mov( eax, this.width );

    pop( eax );
    ret();

end create;



// Here is the draw method for the roundrect object.
// Note: if the object is less than 5x4 in size,
// this code calls rect.draw to draw a rectangle
// since roundrects smaller than 5x4 don't look good.
//
//    Typical roundrect:
//
//         --------
//        /           \
//       |             |
//       \            /
//         --------

method roundrect.draw; @nodisplay;
static
    horz:        str.strvar( shape.maxC );
    spcs:        str.strvar( shape.maxC );

begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
   
    if
    ( #{
        cmp( this.width, 5 );
        jb true;
        cmp( this.height, 4 );
        jae false;
    }#) then
   
        // If it's too small to draw an effective
        // roundrect, then draw it as a rectangle.
   
        call( rect._VMT_[ @offset( rect.draw ) ] );
   
    else

        // Okay, it's big enough, draw it as a rounded
        // rectangle object.  Begin by initializing the
        // horz string with a set of dashes with spaces
        // at either end.
           
        mov( this.width, ebx );
        sub( 4, ebx );
        str.setstr( '-', horz, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
        if( this.fillShape ) then
                               
            add( 2, ebx );
            str.setstr( ' ', spcs, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
           
        else
       
            str.cpy( "", spcs );
           
        endif;
       
        // Okay, draw the top line.
       
        mov( this.C, eax );
        add( 2, eax );
        console.gotorc( this.R, eax );
        stdout.puts( horz );
       
        // Now draw the second line and the
        // as "/" and "\" with optional spaces
        // inbetween (if fillShape is true).
       
        mov( this.R, ecx );
        inc( ecx );
        console.gotorc( ecx, eax );
        stdout.puts( spcs );
       
        console.gotorc( ecx, this.C );
        stdout.puts( " /" );
       
        add( this.width, eax );
        sub( 4, eax );                    // Sub 4 because we added two above.
        console.gotorc( ecx, eax );
        stdout.puts( "\ " );
       
       
        // Okay, now draw the bottom line:
       
        mov( this.C, eax );
        add( 2, eax );
        mov( this.R, ecx );
        add( this.height, ecx );
        dec( ecx );
        console.gotorc( ecx, eax );
        stdout.puts( horz );
       
        // And draw the second from the bottom
        // line as "\" and "/" with optional
        // spaces inbetween (depending on fillShape)
       
        dec( ecx );
        console.gotorc( ecx, this.C );
        stdout.puts( spcs );
       
        console.gotorc( ecx, this.C );
        stdout.puts( " \" );
       
        mov( this.C, eax );
        add( this.width, eax );
        sub( 2, eax );                    // Sub 4 because we added two above.
        console.gotorc( ecx, eax );
        stdout.puts( "/ " );
       
        // Finally, draw all the lines inbetween the
        // top two and bottom two lines.
       
        mov( this.R, ecx );
        mov( this.height, ebx );
        add( ecx, ebx );
        add( 2, ecx );
        sub( 2, ebx );
        mov( this.C, eax);
        add( this.width, eax );
        dec( eax );
           
        while( ecx < ebx) do
       
            console.gotorc( ecx, this.C );
            stdout.putc( '|' );
            stdout.puts( spcs );
            console.gotorc( ecx, eax );
            stdout.putc( '|' );
            inc( ecx );
                   
        endwhile;

    endif;

    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;



/*********************/
/*                                      */
/*     Diamond's methods   */
/*                                      */
/*********************/

// Constructor for a diamond shape.
// See pertinent comments for the rect constructor
// for more details.

procedure diamond.create; @nodisplay; @noframe;
begin create;

    push( eax );
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
    mov( &diamond._VMT_, this._pVMT_ );

    // Initialize fields to create a 2x2 diamond.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );                        // Minimum diamond size is 2x2.
    mov( eax, this.height );
    mov( eax, this.width );

    pop( eax );
    ret();

end create;


// We have to overload the resize method for diamonds
// (unlike the other objects) because diamond shapes
// have to be symmetrical.  That is, the width and
// the height have to be the same.  This code enforces
// this restriction by setting both parameters to the
// minimum of the width/height parameters and then it
// calls shape.resize to do the dirty work.

method diamond.resize( width:uns32; height:uns32 ); @nodisplay;
begin resize;

    // Diamonds are symmetrical shapes, so the width and
    // height must be the same.  Force that here:
   
    push( eax );
    mov( width, eax );
    if( eax > height ) then
       
        mov( height, eax );
       
    endif;
   
    // Call the shape.resize method to do the actual work:
   
    push( eax );    // Pass the minimum value as the width.
    push( eax );    // Also pass the minimum value as the height.
    call( shape._VMT_[ @offset( shape.resize ) ] );
   
    pop( eax );
   
end resize;


// Here's the code to draw the diamond.

method diamond.draw; @nodisplay;
var
    startR: uns32;
    endR:  uns32;
    startC: uns32;
    endC:  uns32;

begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
   
    if
    (#{
        cmp( this.width, 2 );
        jb true;
        cmp( this.height, 2 );
        jae false;
    }#) then
   
        // Special cases for small diamonds.
        // Resizing prevents most of these from ever appearing.
        // However, if someone pokes around directly in the
        // width and height fields this code will save us:
       
            cmp( this.width, 1 );
            ja D2x1;
            cmp( this.height, 1 );
            ja D1x2;
       
            // At this point we must have a 1x1 diamond

            console.gotorc( this.R, this.C );
            stdout.putc( '+' );
            jmp    SmallDiamondDone;

        D2x1:               

            // Okay, we have a 2x1 (WxH) diamond here:

            console.gotorc( this.R, this.C );
            stdout.puts( "<>" );
            jmp SmallDiamondDone;

        D1x2:

            // We have a 1x2 (WxH) diamond here:

            mov( this.R, eax );
            console.gotorc( eax, this.C );
            stdout.putc( '^' );                           
 
            inc( eax );                               
     
            console.gotorc( eax, this.C );
            stdout.putc( 'V' );

        SmallDiamondDone:
                                               
 
    else

        // Okay, we're drawing a reasonable sized diamond.
        // There is still a minor problem.  The best looking
        // diamonds always have a width and height that is an
        // even integer.  We need to do something special if
        // the height or width is odd.
        //
        //   Odd         Odd
        //  Height        Width
        //                  .      <- That's a period
        //     /\              / \
        //    <  >          \ /
        //     \/               '      <- That's an apostrophe
        //
        //            Both
        //              .
        //             / \   
        //           <   >
        //             \ /                           
        //              '
        //
        // Step one: determine if we have an odd width.  If so,
        // output the period and quote at the appropriate points.
 
        mov( this.width, eax );
        mov( this.R, ecx );
        test( 1, al );
        if( @nz ) then

            shr( 1, eax );
            add( this.C, eax );
            console.gotorc( ecx, eax );
            stdout.putc( '.' );
            inc( ecx );
            mov( ecx, startR );

            add( this.height, ecx );
            sub( 2, ecx );
            console.gotorc( ecx, eax );
            stdout.putc( '''' );
            dec( ecx );
            mov( ecx, endR );
           
        else
       
            mov( this.R, eax );
            mov( eax, startR );
            add( this.height, eax );
            dec( eax );
            mov( eax, endR );

        endif;
       
        // Step two: determine if we have an odd height.  If so,
        // output the less than and greater than symbols at the
        // appropriate spots (in the center of the diamond).
       
        mov( this.height, eax );
        mov( this.C, ecx );
        test( 1, al );
        if( @nz ) then
       
            shr( 1, eax );
            add( this.R, eax );
            console.gotorc( eax, ecx );
            stdout.putc( '<' );
            inc( ecx );
            mov( ecx, startC );
           
            // Write spaces across the center if fillShape is true.
           
            if( this.fillShape ) then
           
                lea( ebx, [ecx+1] );
                mov( this.C, edx );
                add( this.width, edx );
                dec( edx );
                while( ebx < edx ) do
               
                    stdout.putc( ' ' );
                    inc( ebx );
                   
                endwhile;
               
            endif;
           
            add( this.width, ecx );
            sub( 2, ecx );
            console.gotorc( eax, ecx );
            stdout.putc( '>' );
            dec( ecx );
            mov( ecx, endC );
           
        else
       
            mov( this.C, eax );
            mov( eax, startC );
            add( this.width, eax );
            dec( eax );
            mov( eax, endC );
           
        endif;
       
        // Step three: fill in the sides of the diamond
        //
        //      /\             '
        //     /  \    O    / \       (or something inbetween these two).
        //     \  /    R  <   >
        //      \/            \ /
        //                     '
        // We've already drawn the points if there was an odd height
        // or width, now we've just got to fill in the sides with
        // "/" and "\" characters.
        //
        // Compute the middle two (or three) lines beginning with
        // the "/" (decY) and "\" (incY) symbols:
        //
        // decY = (( startR + endR - 1 ) and $FFFE )/2
        // incY = ( startR + endR )/2 + 1
       
        mov( startR, eax );
        add( endR, eax );
        mov( eax, ebx );
        dec( eax );
        and( $FFFF_FFFE, eax ); // Force value to be even.
        shr( 1, eax );
       
        shr( 1, ebx );
        inc( ebx );
       
       
        // Fill in pairs of rows as long as we don't hit the bottom/top
        // of the diamond:
       
        while( (type int32 eax) >= (type int32 startR) ) do
       
            // Draw the sides on the upper half of the diamond:
           
            mov( startC, ecx );
            mov( endC, edx );
            console.gotorc( eax, ecx );
            stdout.putc( '/' );
            if( this.fillShape ) then
           
                inc( ecx );
                while( ecx < edx ) do
               
                    stdout.putc( ' ' );
                    inc( ecx );
                   
                endwhile;
               
            endif;
            console.gotorc( eax, edx );
            stdout.putc( '\' );
       
            // Draw the sides on the lower half of the diamond:
           
            mov( startC, ecx );
            mov( endC, edx );
            console.gotorc( ebx, ecx );
            stdout.putc( '\' );
            if( this.fillShape ) then
           
                inc( ecx );
                while( ecx < edx ) do
               
                    stdout.putc( ' ' );
                    inc( ecx );
                   
                endwhile;
               
            endif;
            console.gotorc( ebx, edx );
            stdout.putc( '/' );
           
            inc( ebx );
            dec( eax );
            inc( startC );
            dec( endC );
               
        endwhile;

    endif;


    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;


end Shapes;




Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #20 on: September 02, 2008, 04:47:27 AM »
// 3rd page of chapter 20 continues here ...


The next 3-file modificatin ... adds colour, ( the compile command is just as for the 3-files above ) : hla  Shapes2Demo  Shapes2




program shapes2Demo;

// Modified from: AoA_Electronic\Volume4\Ch10

// colour choices added to shapes ...

// This is a simple demonstration program that
// shows how to use the shape objects in the
// shape, rect, roundrect, and diamond classes.


#include( "stdlib.hhf" )
#includeonce( "shapes2.hhf" )

type
    pShape: pointer to shape;
  

// Allocate storage for various shapes:

static
    aRect1: pointer to rect;
    aRect2: pointer to rect;
    aRect3: pointer to rect;
  
    aRrect1: pointer to roundrect;
    aRrect2: pointer to roundrect;
    aRrect3: pointer to roundrect;

    aDiamond1: pointer to diamond;
    aDiamond2: pointer to diamond;
    aDiamond3: pointer to diamond;

    // We'll create a list of generic objects
    // in the following array in order to demonstrate
    // virtual method calls and polymorphism.
      
    DrawList: pShape[9];
  
begin shapes2Demo;

    console.cls();
  
    // Initialize various rectangle, roundrect, and diamond objects.
    // This code also stores pointers to each of these objects in
    // the DrawList array.
  
    mov( rect.create(), aRect1 ); mov( esi, DrawList[0*4] );
    mov( rect.create(), aRect2 ); mov( esi, DrawList[1*4] );
    mov( rect.create(), aRect3 ); mov( esi, DrawList[2*4] );
  
    mov( roundrect.create(), aRrect1 ); mov( esi, DrawList[3*4] );
    mov( roundrect.create(), aRrect2 ); mov( esi, DrawList[4*4] );
    mov( roundrect.create(), aRrect3 ); mov( esi, DrawList[5*4] );
  
    mov( diamond.create(), aDiamond1 ); mov( esi, DrawList[6*4] );
    mov( diamond.create(), aDiamond2 ); mov( esi, DrawList[7*4] );
    mov( diamond.create(), aDiamond3 ); mov( esi, DrawList[8*4] );
  

    // Size and position each of these objects:
  
/*
    console.black:=      0;
     console.red:=        1;
     console.green:=     2;
     console.yellow:=   3;
     console.blue:=       4;
     console.magenta:= 5;
     console.cyan:=       6;
     console.white:=      7;
*/

    aRect1.resize( 7, 7 );
    aRect1.moveTo( 10, 10 );
    aRect1.fill( true, console.blue, console.green );
  
    aRect2.resize( 10, 10 );
    aRect2.moveTo( 15, 15 );
    aRect2.fill( true, console.white, console.magenta );
  
    aRect3.resize( 23, 9 );
    aRect3.moveTo( 20, 12 );


    aRrect1.resize( 9, 9 );
    aRrect1.moveTo( 40, 10 );
    aRrect1.fill( true, console.green, console.yellow );
  
    aRrect2.resize( 10, 10 );
    aRrect2.moveTo( 45, 15 );
    aRrect2.fill( true, console.yellow, console.blue );
  
    aRrect3.resize( 29, 7 );
    aRrect3.moveTo( 50, 16 );
    // aRrect3.fill( false );
  

    aDiamond1.resize( 8, 8 );
    aDiamond1.moveTo( 20, 0 );
    aDiamond1.fill( true, console.magenta, console.green );
  
    aDiamond2.resize( 10, 10 );
    aDiamond2.moveTo( 21, 1 );
    aDiamond2.fill( true, console.blue, console.yellow );
  
    aDiamond3.resize( 14, 14 );
    aDiamond3.moveTo( 22, 2 );
    aDiamond3.fill( true, console.white, console.red );
  
  
    // Now ... for the real fun, draw all of the objects
    // on the screen using the following simple loop.
  
    for(  mov( 0, ebx ); ebx < 9; inc( ebx )  ) do
  
        DrawList.draw[ ebx*4 ]();
      
    endfor;

    console.gotorc( 9, 25 );
    stdout.puts( "THE END!" );
    console.gotorc( 19, 53 );
    stdout.puts( "Press Enter to exit ..." );
    stdin.readLn();

end shapes2Demo;
          




// file name is shapes2.hhf //

type

    // Generic shape class:
  
    shape: class

        const

            maxC:          uns32 := 80;
            maxR:          uns32 := 25;

        var
            C:                  uns32;
            R:                  uns32;
            width:            uns32;
            height:            uns32;
            fillShape:        boolean;
            textCol:          uns32;
            backCol:        uns32;

        procedure create; returns( "esi" ); @external;
      
        method draw; @abstract;
        method fill( f:boolean; t:uns32; b:uns32 ); @external;
        method moveTo( C:uns32; R:uns32 );  @external;
        method resize( width: uns32; height: uns32 );  @external;

    endclass;



    // Class for a rectangle shape
    //
    //    +------+
    //     |           |
    //     +------+
  
    rect: class inherits( shape )

        override procedure create;  @external;
        override method draw; @external;

    endclass;
  
  
  
    // Class for a rounded rectangle shape
    //
    //     --------
    //    /            \
    //    |            |
    //    \            /
    //     --------
  
    roundrect: class inherits( shape )
  
        override procedure create; @external;
        override method draw;  @external;
      
    endclass;
  
  
    // Class for a diamond shape
    //
    //         /\
    //        /  \
    //        \  /
    //         \/
  
    diamond: class inherits( shape )
  
        override procedure create; @external;
        override method resize;     @external;
        override method draw;  @external;
      
    endclass;




// continues on next page ...

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #21 on: September 02, 2008, 04:51:40 AM »
// The 4th page of Chapter 20 continues here ... and on the next page also ...


// file name is: shapes2.hla //

unit Shapes;

#includeonce( "stdlib.hhf" )
#includeonce( "shapes2.hhf" )


// Emit the virtual method tables for the classes:

static
    vmt( shape );
    vmt( rect );
    vmt( roundrect );
    vmt( diamond );


/*********************************************************************/

// Generic shape methods and procedures


// Constructor for the shape class.
//
//    Note: this should really be an abstract procedure, but since
//    HLA doesn't support abstract procedures we'll fake it by
//    raising an exception if somebody tries to call this proc.

procedure shape.create; @nodisplay; @noframe;
begin create;

    // This should really be an abstract procedure,
    // but such things don't exist, so we will fake it.

    raise( ex.ExecutedAbstract );

end create;


// Generic shape.fill method.
// This is an accessor function that sets the "fill" field
// to the value of the parameter.

method shape.fill( f:boolean; t:uns32; b:uns32 ); @nodisplay;
begin fill;

    push( eax );
    mov( f, al );
    mov( al, this.fillShape );
    mov( t, eax );
    mov( eax, this.textCol );
    mov( b, eax );
    mov( eax, this.backCol );
    pop( eax );

end fill;

// Generic shape.moveTo method.
// Checks the coordinates passed as a parameter and
// then sets the (C,R) coordinates of the underlying
// shape object to these values.

method shape.moveTo( C:uns32; R:uns32 ); @nodisplay;
begin moveTo;

    push( eax );
    push( ebx );

    mov( C, eax );
    assert( eax < shape.maxC );
    mov( eax, this.C );

    mov( R, eax );
    assert( eax < shape.maxR );
    mov( eax, this.R );

    pop( ebx );
    pop( eax );

end moveTo;


// Generic shape.resize method.
// Sets the width and height fields of the underlying object
// to the values passed as parameters.
//
// Note: Ignores resize request if the size is less than 2x2.

method shape.resize( width:uns32; height:uns32 ); @nodisplay;
begin resize;

    push( eax );
    assert( width <= shape.maxC );
    assert( height <= shape.maxR );

    if( width > 2 ) then
  
        if( height > 2 ) then
  
            mov( width, eax );
            mov( eax, this.width );
          
      
            mov( height, eax );
            mov( eax, this.height );
      
        endif;
              
    endif;
    pop( eax );

end resize;


/*******************/
/*                                  */
/*    rect's methods:        */
/*                                  */
/*******************/


// Constructor for the rectangle class:

procedure rect.create; @nodisplay; @noframe;
begin create;

    push( eax );

    // If called as rect.create, then allocate a new object
    // on the heap and return the pointer in ESI.
  
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
  
    // Initialize the pointer to the VMT:
  
    mov( &rect._VMT_, this._pVMT_ );

    // Initialize fields to create a non-filled unit square.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );
    mov( eax, this.height );
    mov( eax, this.width );

    mov( console.blue, this.textCol );    // make these defaults
    mov( console.cyan, this.backCol );

    pop( eax );
    ret();

end create;


// Here's the method to draw a text-based square on the display.

method rect.draw; @nodisplay;
static
    horz: str.strvar( shape.maxC );     // Holds "+------...--+"
    spcs: str.strvar( shape.maxC );    // Holds "      ...    " for fills.

  
begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
  
    // Initialize the horz and spcs strings to speed up
    // drawing our rectangle.

  
    mov( this.width, ebx );
    str.setstr( '-', horz, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
    mov( horz, eax );
    mov( '+', (type char [eax]));
    mov( '+', (type char [eax+ebx-1]));
  
    // If the fillShape field contains true, then we
    // need to fill in the characters inside the rectangle.
    // If this is false, we don't want to overwrite the
    // text in the center of the rectangle.  The following
    // code initializes spcs to all spaces or the empty string
    // to accomplish this.
  
    if( this.fillShape ) then
                          
        sub( 2, ebx );
        str.setstr( ' ', spcs, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
        console.setAttrs( this.textCol, this.backCol );
      
    else
  
        str.cpy( "", spcs );
      
    endif;
  
    // Okay, position the cursor and draw
    // our rectangle.
  
    console.gotorc( this.R, this.C );
    stdout.puts( horz );    // Draws top horz line.
  
    // For each row except the top and bottom rows,
    // draw "|" characters on the left and right
    // hand sides and the fill characters (if fillShape
    // is true) inbetween them.
  
    mov( this.R, ecx );
    mov( ecx, ebx );
    add( this.height, ebx );
    inc( ecx );
    dec( ebx );
    while( ecx < ebx) do
  
        console.gotorc( ecx, this.C );
        stdout.putc( '|' );
        stdout.puts( spcs );
        mov( this.C, edx );
        add( this.width, edx );
        dec( edx );
        console.gotorc( ecx, edx );
        stdout.putc( '|' );
        inc( ecx );
              
    endwhile;
  
    // Draw the bottom horz bar:
  
    console.gotorc( ecx, this.C );
    stdout.puts( horz );

    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;


/************************/
/*                                            */
/*         roundrect's methods:    */
/*                                            */
/************************/

// This is the constructor for the roundrect class.
// See the comments in rect.create for details
// (since this is just a clone of that code with
//  minor changes here and there).

procedure roundrect.create; @nodisplay; @noframe;
begin create;

    push( eax );
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
    mov( &roundrect._VMT_, this._pVMT_ );

    // Initialize fields to create a non-filled unit square.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );
    mov( eax, this.height );
    mov( eax, this.width );

    mov( console.blue, this.textCol );    // set as defaults
    mov( console.cyan, this.backCol );

    pop( eax );
    ret();

end create;



// Here is the draw method for the roundrect object.
// Note: if the object is less than 5x4 in size,
// this code calls rect.draw to draw a rectangle
// since roundrects smaller than 5x4 don't look good.
//
//    Typical roundrect:
//
//         --------
//        /            \
//        |             |
//        \            /
//         --------

method roundrect.draw; @nodisplay;
static
    horz:        str.strvar( shape.maxC );
    spcs:        str.strvar( shape.maxC );

begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
  
    if
    ( #{
        cmp( this.width, 5 );
        jb true;
        cmp( this.height, 4 );
        jae false;
    }#) then
  
        // If it's too small to draw an effective
        // roundrect, then draw it as a rectangle.
  
        call( rect._VMT_[ @offset( rect.draw ) ] );
  
    else

        // Okay, it's big enough, draw it as a rounded
        // rectangle object.  Begin by initializing the
        // horz string with a set of dashes with spaces
        // at either end.
          
        mov( this.width, ebx );
        sub( 4, ebx );
        str.setstr( '-', horz, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
        if( this.fillShape ) then
                              
            add( 2, ebx );
            str.setstr( ' ', spcs, ebx ); // If using HLA version 1.101or later reverse the order of last two variables
            console.setAttrs( this.textCol, this.backCol );
          
        else
      
            str.cpy( "", spcs );
          
        endif;
      
        // Okay, draw the top line.
      
        mov( this.C, eax );
        add( 2, eax );
        console.gotorc( this.R, eax );
        stdout.puts( horz );
      
        // Now draw the second line and the
        // as "/" and "\" with optional spaces
        // inbetween (if fillShape is true).
      
        mov( this.R, ecx );
        inc( ecx );
        console.gotorc( ecx, eax );
        stdout.puts( spcs );
      
        console.gotorc( ecx, this.C );
        stdout.puts( " /" );
      
        add( this.width, eax );
        sub( 4, eax );         // Sub 4 because we added two above.
        console.gotorc( ecx, eax );
        stdout.puts( "\ " );
      
      
        // Okay, now draw the bottom line:
      
        mov( this.C, eax );
        add( 2, eax );
        mov( this.R, ecx );
        add( this.height, ecx );
        dec( ecx );
        console.gotorc( ecx, eax );
        stdout.puts( horz );
      
        // And draw the second from the bottom
        // line as "\" and "/" with optional
        // spaces inbetween (depending on fillShape)
      
        dec( ecx );
        console.gotorc( ecx, this.C );
        stdout.puts( spcs );
      
        console.gotorc( ecx, this.C );
        stdout.puts( " \" );
      
        mov( this.C, eax );
        add( this.width, eax );
        sub( 2, eax );               // Sub 4 because we added two above.
        console.gotorc( ecx, eax );
        stdout.puts( "/ " );
      
        // Finally, draw all the lines inbetween the
        // top two and bottom two lines.
      
        mov( this.R, ecx );
        mov( this.height, ebx );
        add( ecx, ebx );
        add( 2, ecx );
        sub( 2, ebx );
        mov( this.C, eax);
        add( this.width, eax );
        dec( eax );
          
        while( ecx < ebx) do
      
            console.gotorc( ecx, this.C );
            stdout.putc( '|' );
            stdout.puts( spcs );
            console.gotorc( ecx, eax );
            stdout.putc( '|' );
            inc( ecx );
                  
        endwhile;

    endif;

    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;


/*********************/
/*                                      */
/*     Diamond's methods   */
/*                                      */
/*********************/


// Constructor for a diamond shape.
// See pertinent comments for the rect constructor
// for more details.

procedure diamond.create; @nodisplay; @noframe;
begin create;

    push( eax );
    if( esi = NULL ) then

        mov( malloc( @size( rect ) ), esi );

    endif;
    mov( &diamond._VMT_, this._pVMT_ );

    // Initialize fields to create a 2x2 diamond.

    sub( eax, eax );

    mov( eax, this.C );
    mov( eax, this.R );
    inc( eax );
    mov( al, this.fillShape );    // Sets fillShape to true.
    inc( eax );                        // Minimum diamond size is 2x2.
    mov( eax, this.height );
    mov( eax, this.width );

    mov( console.blue, this.textCol );    // set as defaults
    mov( console.cyan, this.backCol );

    pop( eax );
    ret();

end create;


Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #22 on: September 02, 2008, 04:53:35 AM »
// ... splice this page with the previous ... of chapter 20.



// We have to overload the resize method for diamonds
// (unlike the other objects) because diamond shapes
// have to be symmetrical.  That is, the width and
// the height have to be the same.  This code enforces
// this restriction by setting both parameters to the
// minimum of the width/height parameters and then it
// calls shape.resize to do the dirty work.

method diamond.resize( width:uns32; height:uns32 ); @nodisplay;
begin resize;

    // Diamonds are symmetrical shapes, so the width and
    // height must be the same.  Force that here:
  
    push( eax );
    mov( width, eax );
    if( eax > height ) then
      
        mov( height, eax );
      
    endif;
  
    // Call the shape.resize method to do the actual work:
  
    push( eax );    // Pass the minimum value as the width.
    push( eax );    // Also pass the minimum value as the height.
    call( shape._VMT_[ @offset( shape.resize ) ] );
  
    pop( eax );
  
end resize;


// Here's the code to draw the diamond.

method diamond.draw; @nodisplay;
var
    startR: uns32;
    endR:    uns32;
    startC:    uns32;
    endC:    uns32;

begin draw;

    push( eax );
    push( ebx );
    push( ecx );
    push( edx );
  
    if
    (#{
        cmp( this.width, 2 );
        jb true;
        cmp( this.height, 2 );
        jae false;
    }#) then
  
        // Special cases for small diamonds.
        // Resizing prevents most of these from ever appearing.
        // However, if someone pokes around directly in the
        // width and height fields this code will save us:
      
            cmp( this.width, 1 );
            ja D2x1;
            cmp( this.height, 1 );
            ja D1x2;
      
            // At this point we must have a 1x1 diamond

            console.gotorc( this.R, this.C );
            stdout.putc( '+' );
            jmp    SmallDiamondDone;

        D2x1:              

            // Okay, we have a 2x1 (WxH) diamond here:

            console.gotorc( this.R, this.C );
            stdout.puts( "<>" );
            jmp SmallDiamondDone;

        D1x2:

            // We have a 1x2 (WxH) diamond here:

            mov( this.R, eax );
            console.gotorc( eax, this.C );
            stdout.putc( '^' );                          

            inc( eax );                              
    
            console.gotorc( eax, this.C );
            stdout.putc( 'V' );

        SmallDiamondDone:
              
                                                
    else

        // Okay, we're drawing a reasonable sized diamond.
        // There is still a minor problem.  The best looking
        // diamonds always have a width and height that is an
        // even integer.  We need to do something special if
        // the height or width is odd.
        //
        //   Odd         Odd
        //  Height      Width
        //                      .    <- That's a period
        //     /\              / \
        //   <  >           \ /
        //     \/               '      <- That's an apostrophe
        //
        //            Both
        //              .
        //             / \  
        //           <   >
        //             \ /                          
        //              '
        //
        // Step one: determine if we have an odd width.  If so,
        // output the period and quote at the appropriate points.
 
        mov( this.width, eax );
        mov( this.R, ecx );
        test( 1, al );
        if( @nz ) then

            shr( 1, eax );
            add( this.C, eax );
            console.gotorc( ecx, eax );
            stdout.putc( '.' );
            inc( ecx );
            mov( ecx, startR );

            add( this.height, ecx );
            sub( 2, ecx );
            console.gotorc( ecx, eax );
            stdout.putc( '''' );
            dec( ecx );
            mov( ecx, endR );
          
        else
      
            mov( this.R, eax );
            mov( eax, startR );
            add( this.height, eax );
            dec( eax );
            mov( eax, endR );

        endif;
      
        // Step two: determine if we have an odd height.  If so,
        // output the less than and greater than symbols at the
        // appropriate spots (in the center of the diamond).
      
        mov( this.height, eax );
        mov( this.C, ecx );
        test( 1, al );
        if( @nz ) then
      
            shr( 1, eax );
            add( this.R, eax );
            console.gotorc( eax, ecx );
            stdout.putc( '<' );
            inc( ecx );
            mov( ecx, startC );
          
            // Write spaces across the center if fillShape is true.
          
            if( this.fillShape ) then
              
                console.setAttrs( this.textCol, this.backCol );
          
                lea( ebx, [ecx+1] );
                mov( this.C, edx );
                add( this.width, edx );
                dec( edx );
                while( ebx < edx ) do
              
                    stdout.putc( ' ' );
                    inc( ebx );
                  
                endwhile;
              
            endif;
          
            add( this.width, ecx );
            sub( 2, ecx );
            console.gotorc( eax, ecx );
            stdout.putc( '>' );
            dec( ecx );
            mov( ecx, endC );
          
        else
      
            mov( this.C, eax );
            mov( eax, startC );
            add( this.width, eax );
            dec( eax );
            mov( eax, endC );
          
        endif;
      
        // Step three: fill in the sides of the diamond
        //
        //      /\             '
        //     /  \   O     / \       (or something inbetween these two).
        //     \  /    R   <   >
        //      \/            \ /
        //                     '
        // We've already drawn the points if there was an odd height
        // or width, now we've just got to fill in the sides with
        // "/" and "\" characters.
        //
        // Compute the middle two (or three) lines beginning with
        // the "/" (decY) and "\" (incY) symbols:
        //
        // decY = (( startR + endR - 1 ) and $FFFE )/2
        // incY = ( startR + endR )/2 + 1
      
        mov( startR, eax );
        add( endR, eax );
        mov( eax, ebx );
        dec( eax );
        and( $FFFF_FFFE, eax ); // Force value to be even.
        shr( 1, eax );
      
        shr( 1, ebx );
        inc( ebx );
      
      
        // Fill in pairs of rows as long as we don't hit the bottom/top
        // of the diamond:
      
        while( (type int32 eax) >= (type int32 startR) ) do
      
            // Draw the sides on the upper half of the diamond:
          
            mov( startC, ecx );
            mov( endC, edx );
            console.gotorc( eax, ecx );
            stdout.putc( '/' );
            if( this.fillShape ) then

                console.setAttrs( this.textCol, this.backCol );
          
                inc( ecx );
                while( ecx < edx ) do
              
                    stdout.putc( ' ' );
                    inc( ecx );
                  
                endwhile;
              
            endif;
            console.gotorc( eax, edx );
            stdout.putc( '\' );
      
            // Draw the sides on the lower half of the diamond:
          
            mov( startC, ecx );
            mov( endC, edx );
            console.gotorc( ebx, ecx );
            stdout.putc( '\' );
            if( this.fillShape ) then

                console.setAttrs( this.textCol, this.backCol );
          
                inc( ecx );
                while( ecx < edx ) do
              
                    stdout.putc( ' ' );
                    inc( ecx );
                  
                endwhile;
              
            endif;
            console.gotorc( ebx, edx );
            stdout.putc( '/' );
          
            inc( ebx );
            dec( eax );
            inc( startC );
            dec( endC );
              
        endwhile;

    endif;


    pop( edx );
    pop( ecx );
    pop( ebx );
    pop( eax );

end draw;

end Shapes;




This is a big chapter to swallow ...take it in little steps.

We started off with little steps like mov( 3, eax ); add(  7, eax ); mov( eax, my_u32 ) ...

We have built up from primitive machine level instructions to some very sophisticated coding tools ... like OOP ...

After we, (mostly Randall here), put these last two shapes programs together ... With just the following 3 simple lines, we can put a very large number of distinct and precisely designed objects on the screen ... in almost instantaneous succession.

Recall this simple loop ...

// Now ... for the real fun, draw all of the objects
// on the screen using the following simple loop.
  
    for( mov( 0, ebx ); ebx < 9; inc( ebx ) ) do
  
        DrawList.draw[ ebx*4 ]();
      
    endfor;


You may do well to read as much of Randy's material as possible if you are keen on being a Computer Scientist. I have already provided several links to HLA/Randy. But here is a good place to start:  http://webster.cs.ucr.edu/

Google for others too.  Also, take a look at C and C++. There are many free compilers, e-texts and tutorials.  Here is a free tutorial for C   http://mindview.net/CDs/ThinkingInC/beta3  ... and a free DEV C/C++ compiler at http://www.bloodshed.net/

Same is true for Python. (Google for it or try here:  http://www.python.org/~guido/  )  Also... take a look at HTML ... Hyper Text Markup Language ... the language of the WWW ... and see some of the more uptodate modifications. Try here:  http://www.w3schools.com/


Remember the process, putting little things together ... until we end up with some amazingly big and powerful packages.  But this one thing ... should be obvious ... but it is not so obvious today ...

Here it is.

It took somebody ... (many somebodies to put it all <the first computer> together.) ...

And so ... In the beginning God created the heavens and the earth ... it didn't just all happen by itself.

Even a beginner can see that it took a lot of intelligence, work, material ... to put together the first CPU ... and it took materials, energy, planning, work, design, purpose, language, coding, decoding ...etc ...to get it to do anything purposeful ... get the drift ... And look at all the work, planning, thinking ... since then to get to OOP ... and INTEL and LINUX !!!


Shalom shalom,


David

P.S.  Take a further look at Chapter 17 ... and the program there.  It is just a little French and English intro to the good news of our Creator ... and soon coming King of Kings. Try this link too ... http://sites.google.com/site/andeveryeyeshallseehim/

Yes ... it may NOT be that much longer until this most awesome event transpires:

    * Behold, he cometh with clouds;
    * and every eye shall see him,
    * and they also which pierced him:
    * and all kindreds of the earth shall wail because of him.
    * Even so,
    * Amen.
    * (Revelation 1:7)

« Last Edit: November 23, 2009, 05:53:58 PM by David »

Offline admin

  • Administrator
  • Sr. Member
  • *****
  • Posts: 296
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python)
« Reply #23 on: September 03, 2008, 08:28:22 AM »
Thanks David,
Great job.

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3.0.1)
« Reply #24 on: November 23, 2009, 05:51:06 PM »
Update:

You might want to also see this new thread at ...

http://developers-heaven.net/forum/index.php/topic,127.0.html

regarding ...

BEGINNING COMPUTER PROGRAMMING (using C++ or C)

And also these new web links at ...

http://sites.google.com/site/andeveryeyeshallseehim/

http://secureServices.ca

Shalom.

David



Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3.1)
« Reply #25 on: January 19, 2010, 08:41:26 AM »
Addendum:

Code: [Select]
# guessIt6.py

'''
    This cleaned up version is crash proof for non integer input ...
    and validates that integer input is in the user specified range
'''

#globals ...

prompt1 = 'THE COMPUTER will roll the dice AFTER YOU ENTER a number ...'
prompt2 = 'Enter your guess in range 2..12 : '

def getValidInt( prompt, low, high ):
    ''' This function returns an int in the range [low, ..., high] '''
    done = False
    num = 0
    while not done:
        try:
            num = int(input(prompt))
            if num < low or num > high:
                raise
            done = True
        except:
            print('Valid range is ', low, '..', high, sep='')
    return num

def playgame( cC, pC ):
    '''
    cC is for computer cents, pC for player cents ... Note: Function
    playgame is the main game ... the values of cCents and pCents
    get updated, and the new values are returned.
    '''
    import random
    print( prompt1 )
    userNum = getValidInt( prompt2, 2, 12 )
   
    # get two random numbers 1..6 for each die
    die1 = random.randrange( 1, 7 ) # returns random num 1..6 in die1
    die2 = random.randrange( 1, 7 )
    sumdie = die1 + die2

    if sumdie == userNum:
        print("MATCH!")    # report
        pC = pC + userNum  # player wins                           
        cC = cC - userNum  # computer loses
    else:
        print("NO match!") # report failure
        pC = pC - userNum  # player loses
        cC = cC + userNum  # computer wins
       
    print("You entered", userNum, "and the computer rolled", \
          die1, "and", die2, "or", sumdie)
    return cC, pC


### Main program begins here ###

cCents = getValidInt('Computer stakes 100..1000 (cents) : ', 100, 1000)
cStake = cCents

pCents = getValidInt('Player stakes 100..1000 (cents) : ', 100, 1000)
pStake = pCents

done = False
numGames = 0
while not done:
    numGames = numGames +1
    print('Game nunber', numGames, '...')
    cCents, pCents = playgame( cCents, pCents )
    done = pCents <= 0 or cCents <= 0
    if not done:
        reply = input( '\nPlay again (y/n) ? ' )
        done = reply in 'Nono' and reply != ''

# don't allow, (i.e. correct for), 'in-hole' situations ...
if pCents < 0:               # player in hole
    cCents = cCents + pCents # i.e. decrease computer balance
    pCents = 0               # so now can up balance of player to zero
else:
    if cCents < 0:          # computer in hole
        pCents = pCents + cCents # decrease player balance
        cCents = 0          # so now can up balance of computer to zero

print('\nAfter', numGames, 'games, the computer has', cCents, 'cents', \
      '\nand the player has', pCents, 'cents')

cWins = cCents - cStake # calculate the computer winnings
pWins = pCents - pStake # calculate the player winnings


if( cWins > 0 ): # computer wins
    print('The computer wins', cWins, 'and the player loses', -pWins)
else: # computer loses
    print('The player wins', pWins, 'and the computer loses', -cWins)


« Last Edit: January 19, 2010, 09:05:12 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 647
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3.1 and C++)
« Reply #26 on: January 09, 2013, 02:57:17 AM »
Below, please find the Python Demo Programs linked to the new thread ...

Beginning Calculus


To go to Beginning Calculus, click here ...

http://developers-heaven.net/forum/index.php?topic=2601.0


This first demo is an 'updated version' of Archimedes method to calculate the value for the constant pi

Select/Copy the following program, coded in the Python computer language, and paste that code into a Text Editor like Notepad ... then 'SaveAs' that file with file name calPi.py
Making sure that you have a 3.x version of the freely available Python Interpreter installed on your PC, you can then 'click on' i.e. 'run' that .py file you just saved.

Note: Python program file names end with .py

Update: moved to ...

http://developers-heaven.net/forum/index.php?topic=2602.0

« Last Edit: January 14, 2013, 01:15:39 AM by David »