Lazarus

Free Pascal => Beginners => Topic started by: waituntilthis on November 12, 2019, 11:00:35 am

Title: how to set part of a 2dimensional array(boolean) to true?
Post by: waituntilthis on November 12, 2019, 11:00:35 am
hi all,

I'm currently working on tetris and I've built 2 rasters. they are twodimensional arrays and are horizontal(x) 0..9 and vertical (y)0..19.
when a block hits the ground, it stays there and a new one spawns up top. problem is that I need my second raster (array -filled) to set those 'coordinates' to 1, so that blocks can detect where blocks are currently residing.

thing is, I'm very lost on how to tell my twodimensional array that filled[x,y] should be true. I only get illegal qualifiers.

here's my code....
Code: Pascal  [Select]
  1.  
  2.   private
  3.     blockwait, bottomcheck, movement, x, y: integer;
  4.     start, filled: boolean;
  5.     location: array[0..9, 0..19] of integer;
  6.   public
  7.  
  8.   end;
  9.  
  10. var
  11.   Form1: TForm1;
  12.   filled: array[0..9, 0..19] of boolean;
  13.  
  14. implementation      
  15. -------------------------------------------
  16.  
  17. procedure tform1.createblock();
  18. var
  19.   a,b:integer;
  20.   img : Timage;
  21. begin
  22.   x:=4;
  23.   y:=0;
  24.   img:= timage.create(application);
  25.   img.top:=y*50;
  26.   img.left:=x*50;
  27.   img.visible:=true;
  28.   img.picture:=fallingblock.picture;
  29.   img.stretch:=true;
  30.   img.width:=50;
  31.   img.height:=50;
  32.   img.enabled:=true;
  33.   img.transparent:=true;
  34.   img.Parent:=fallingblock.parent;
  35.   fallingblock:=img;
  36.   img.top:=a;
  37.   img.left:=b;
  38.   //i tried converting the coordinates from x, to img.left,to b, so that filled would hopefully stay in one place instead
  39.   //of moving around the field attached to a falling block.
  40.   filled[a,b]:=true;
  41. end;
  42.  
  43. ------------------------------
  44.  
  45. //if a block hits the bottom procedure createblock is called, I still have to write code for the falling block hitting a filled:=true but i'm currently stuck.
  46. procedure TForm1.blockfallingTimer(Sender: TObject);
  47. begin
  48. y:=y+1;
  49. fallingblock.top := 50 * y;
  50. if y>=19 then
  51. begin
  52.   y:=0;
  53.   createblock();
  54. end;
  55. end;
  56.  
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: Handoko on November 12, 2019, 11:36:22 am
Glad to find someone want to use Lazarus to create games.

I'm not here to answer your question, but I recommend you read my tutorial for snake game:
https://forum.lazarus.freepascal.org/index.php/topic,38136.15.html

Honesty, the tutorial in the link above is very long and boring. But if you follow it seriously to the end, you'll be sure to learn:

- Game loop
- User input detection
- Using array to represent the the game world
- Collision detection
- How to use TList (to replace array)
- Using buffer for keyboard input
- Using buffer to reduce flickering

Also if you are a beginner in Lazarus game programming, I recommend you to read the post in the link below, which has many useful examples:
https://forum.lazarus.freepascal.org/index.php/topic,43474.msg304278.html#msg304278
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: waituntilthis on November 12, 2019, 11:49:35 am
handoko thanks for your reply! will read it but i'm not sure that I can find my solution very efficiently that way, i'm quite new to free pascal :(
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: waituntilthis on November 12, 2019, 01:49:47 pm
THE SOLUTION for future readers;

I found out that I accidentally changed filled from a Boolean array to just a single Boolean. I wanted to make sure that my array was false for the entire raster and I used: Filled:=false;
after using filled:=false I got an error asking me to change filled to Boolean so I did just that in my private declaration: filled:boolean;. wich gave me illegal qualifiers w/o explanation. it's working now!
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: Thaddy on November 12, 2019, 01:53:11 pm
THE SOLUTION for future readers;

I found out that I accidentally changed filled from a Boolean array to just a single Boolean. I wanted to make sure that my array was false for the entire raster and I used: Filled:=false;
after using filled:=false I got an error asking me to change filled to Boolean so I did just that in my private declaration: filled:boolean;. wich gave me illegal qualifiers w/o explanation. it's working now!

You can use the Default() intrinsic to set a whole array to false... did you know that?
Example:
Code: Pascal  [Select]
  1. {$mode objfpc}{$H+}
  2. type
  3.   TMyArray = array[0..99, 0..99] of byte; // whatever dimension and type
  4. var
  5.   a:TMyArray;
  6. begin
  7.   a:= Default(TMyArray); // array is all zero'd. One liner.
  8. end.
Actually, for future readers, pay attention to a "slightly" more correct solution.  8-)
Use the language and know the language.
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: waituntilthis on November 12, 2019, 02:54:50 pm
no thaddy I didn't know that! thanks
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: Zvoni on November 12, 2019, 03:02:07 pm
It still doesn't solve his initial problem: how to set a part of an array to True

Found this here:
https://forum.lazarus.freepascal.org/index.php?topic=38602.0
Look at Post #3 (Reply-2)
Eugene shows a method to directly access an array-member via its pointer
Title: Re: how to set part of a 2dimensional array(boolean) to true?
Post by: Handoko on November 12, 2019, 03:54:45 pm
I haven't fully read the OP question. Was it a Tetris game? If yes, then the code OP showed us has many missing parts:

- Standard Tetris has 7 tetrominos
More info: https://en.wikipedia.org/wiki/Tetris#Gameplay (https://en.wikipedia.org/wiki/Tetris#Gameplay)
OP need to create a container to store all the tetromino data. It can be a list of TList of x/y points, a list of 2 dimensional array of Boolean, array[0..6] of TList, array[0..6] of 2 dimentional array of Boolean or whatever s/he feels convenient.

- Global variables
It should store the value of Current_Tetromino_Model and Current_Tetromino_Rotation

To check if the tetromino need to respawn:
If (Current_Tetromino_Y <= 0) or DetectCollision(Current_Tetromino_Model, Current_Tetromino_Rotation, Current_Tetromino_Position) then

And this how the DetectCollision works:
1. Get the tetromino data that stored previously in the container based on Current_Tetromino_Model
2. Rotate the data based on the Current_Tetromino_Rotation
3. Move the tetromino based on Current_Tetromino_Position
4. Compare the final result with the game world, if right below the each of the tetromino's blocks are empty then it Return := False; (which means it is not blocked)

And if you want each tetromino to has its own color, thing will become a bit more complicated.

Sorry to say, but I think creating a Tetris game is too hard for the OP. It is lots easier to create a snake game, which is much simpler.

Anyway, I remember a senior here Eny ever posted a Tetris game, he named it Petris. It was about 600 LOC, well written. You can try to search it if you want to see the source code.