• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Helped needed for writing to files.

BlueSnoodDude

New member
Joined
Dec 6, 2020
Messages
5
So I'm working on a project to make random level designs for games in Monkey X.
The method I'm using is creating an external .txt document which contains values and looks something like the following:

22222222222222222222
27777777777777777772
27777777777777777772
27777777777777777772
27777777727777777772
27777777777777777772
27777771777777777772
27777777777777777772
27777777777277777772
27777777777777777772
27727777777777777772
27777777777777777772
27777777777277777772
27777777777777777772
22222222222222222222

This will then read into Monkey X and it will translate each of these numbers to an allotted sprite.
This all works just fine.

However, I wish for it to randomly generate these files and I have an algorithm designed to make randomly generated files of this structure.
The issue is its not writing correctly, I don't quite know the issue but I assume that its down to it not putting the values in the correct format (as shown above) to be read.


Is anyone able to see the issue:
1607266987484.png


1607267022531.png
That is the syntax error I'm having, it says "array index out of range" so I'm assuming that the new randomly generated file isn't formatted correctly.



I'm stumped. I'd be grateful if anyone knows of any solutions. :)
 
I should probably add, I created Method Write() after Method Load() so I know that method load is working correctly due to it loading a demo .txt file I created.
 
Arrays are zero based. There for your for loops are actually counting 15 and 20 items, you are trying to access the array with data_item[y][x..x+1] when data_item[y][x] is all you would need.
 
Arrays are zero based. There for your for loops are actually counting 15 and 20 items, you are trying to access the array with data_item[y][x..x+1] when data_item[y][x] is all you would need.
This didn't appear to solve the issue. I now have "Character index out of range" after changing [x..x+1] to just [x]
 
1608140099609.png


Shouldn't that be

Cerberus:
level_file.WriteString("~n")

according to how you split the file into lines again?

1608140224818.png
 
I've just knocked up a test program using the code from the image supplied. Line endings are not the issue. It would help to know how the predefined level file that works is being used is constructed.

Is it a pure human readable text, or encode integer with newline termination. If it's the latter, then the data needs to be read in exactly as was written. Plus I take it that the tiles array is predefined and filled out ready for use?
 
Last edited:
I you are trying to produce the layout exactly like the one you have in your first post, then this is how you should do it.

Cerberus:
Method Write:Void()
        Local item:Int
        Local level_file:FileStream
   
        level_file = FileStream.Open("cerberus://data/one.txt", "w")

         For Local j:=0 Until 14
             For Local i:=0 Until 19
                 item = Rnd(8)
                 level_file.WriteString(String.FromChar(item))
             Next
             level_file.WriteString("~n")
         Next
         level_file.Close()
    End

Edit: Don't forget you will not need [x..x+1] and make sure the the data you write out matches the array you will be loading into.
 
Last edited:
What if you change the two "Until"'s at the top into "To"?
"Until" stops 1 step before "to" stops. So you write less data than you are reading I think?
 
Here's an actual working example.
Cerberus:
Strict

Import mojo
Import brl.filestream

Function Main:Int()
    New MojoApp
    Return 0
End

Class MojoApp Extends App

    Field tiles:Int[][]

    Method OnCreate:Int()
        SetUpdateRate 0
 
        ' Initialise the tiles array ready to take the file data
        ' Normal arrays would be coded as tiles[row][column] as it make life easier to deal with arrays, which are basically arrays within arrays.
        ' But as the data is going to To tiles[column][row], then the array needs to reflect this.
        tiles=tiles.Resize(20)                    ' Resize the total number of columns that should be used
        For Local i:=0 Until tiles.Length()
            tiles[i] = tiles[i].Resize(16)        ' For each column, resize how many rows there are.
        Next
 
        ' Printing the length of the tiles variable will only show the total number of rows.
        ' To get the number of rows, you have to specify the column index.
        Print "Array dimentions: "+ tiles.Length()+"x"+tiles[0].Length()
 
        Write()
        Load()
 
        Return 0
    End

    Method OnUpdate:Int()
        If KeyHit(KEY_ESCAPE) Then EndApp
        Return 0
    End

    Method OnRender:Int()
        Cls
 
        ' Display the level
        For Local y:Int = 0 Until 15
            For Local x:Int = 0 Until 20
                 DrawText(tiles[x][y], x*13, y*12)
            Next
        Next
 
        Return 0
    End

    Method Write:Void()
        Local item:Int
        Local level_file:FileStream
        Local level_data:String
 
        level_file = FileStream.Open("cerberus://data/one.txt", "w")

         ' Write out the data exactly as you are going to read it back.
         For Local row:=0 To 14
             For Local col:=0 To 19
                 item = Rnd(8)    ' NOTE: The compiler should be smart enough to work out that the number needed has to cast to a integer
                 level_file.WriteString(String.FromChar(item))    ' Convert the integer number into a character
             Next
     
             level_file.WriteString("~n") ' termination of columns
         Next
 
         level_file.Close()
    End

    Method Load:Void()
        Local level_file:FileStream
        Local level_data:String
        Local data_item:String[]
 
        level_file = FileStream.Open("cerberus://data/one.txt", "r")
        level_data = level_file.ReadString()
        level_file.Close
 
        data_item = level_data.Split("~n")
 
        For Local y:Int = 0 To 14
            For Local x:Int = 0 To 19
                 tiles[x][y]=Int(data_item[y][x])
            Next
        Next
    End

End
Take note that if you open the file one.txt in any editor, Then the text will not make any sense because the character codes will be in the range of 0 to 8. If you want them in human readable form, then you have to add 48 to the value as you write to the file and subtract 48 as you read them back in, or use:
Int(String.FromChar(data_item[y][x]))
to read the data back to a integer.
 
Last edited:
Yeah (sorry for absence over Xmas break), the current file its reading has been hardcoded by me, however the general idea was that the program would write this file, then later it could be read back. I already have the code working for reading the hardcoded files (it reads them and then based on the number it reads it draws a sprite in that place.


Its basically an over glorified maze game - where instead of a maze it divides the screen into a grid and then places sprites down where numbers appear in the grid.
 
Back
Top Bottom