Recent

Author Topic: need help with calender  (Read 49872 times)

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #45 on: September 21, 2017, 02:30:10 pm »
what is that nil do in the bracket?
Calendar1DayChanged is an event procedure. You NEED to pass a parameter to it. Normally the program passes a Sender parameter (from which object/button/component this procedure was called from). But you don't use the Sender parameter in your Calendar1DayChanged so you can just pass nil to it.

If you did use Sender in the event-procedure you would need to check for nil, or pass another object as parameter (for example Sender of the caller procedure of Button2). But for now that's not needed.

A more clear and better approach would be to move the filling of the Listbox to a separate procedure which you call from Calendar1DayChanged AND Button2Click. That would be the best way to do it.

Something like this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Calendar1DayChanged(Sender: TObject);
  2. begin
  3.   FillListBox;
  4. end;
  5.  
  6. procedure TForm1.Button2Click(Sender: TObject);
  7. begin
  8.   // ...
  9.   // remove code
  10.   // ...
  11.  
  12.   FillListBox;
  13.  
  14. end;
The code in FillListBox would be the same as the code you know have in Calendar1DayChanged but the advantage is that you can call it in several places without misusing an event-procedure.

You would add a new class-procedure like this for the FillListBox procedure.
Code: Pascal  [Select][+][-]
  1.   private
  2.     { private declarations }
  3.     procedure FillListBox; // <--- add this in the class
  4. //...
  5. procedure TForm1.FillListBox;
  6. begin
  7.   //... that code from Calendar1DayChanged
  8. end;
« Last Edit: September 21, 2017, 02:35:42 pm by rvk »

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #46 on: September 22, 2017, 08:41:18 am »
Hi thank you so much

also what does that do?

PtrInt()


rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #47 on: September 22, 2017, 09:48:42 am »
If you look at the name of addObject you could already see that you can pass an object for every string in the listbox. So every string can have a unique object associated with it. But the procedure only accepts an TObject. An object is a pointer to a TForm, TButton or anything else that is a pointer to something (as long as it is an TObject descendant).

But you just want a simple Integer connected to the strings in the listbox. Because Integer and Pointer are basically the same idea (they are both just a number, only one points to a memory location and the other is just a number) we can "abuse" the pointer in listbox-items to hold a number. In that case you could have a Pointer with value 100. It won't point to a valid memory location but the pointer still has that value.

To fool the procedure to accept an Integer as a pointer we need to "cast" the integer to a pointer, which in turn we can pass as an TObject with another cast. You see that in the following line:
Code: Pascal  [Select][+][-]
  1. listbox1.items.addObject(info.Name, TObject(IntPtr(Cnt)));
We "convert/cast" Cnt to a Pointer with IntPtr. After that we do that again with TObject(pointer) and we can pass that to addObject. Casting is just a way to say to the compiler "Just assign the value of one item to the other discarding the fact that the are not the same type".

Now to use that TObject in the listbox again we need to do the reverse.
Code: Pascal  [Select][+][-]
  1. seek(goalsfile, PtrInt(ListBox1.Items.Objects[ListBox1.ItemIndex]));
So we take the Object connected to the string at ItemIndex (ListBox1.Items.Objects[ListBox1.ItemIndex]) and use PtrInt to cast that pointer back to an Integer. Basically the PtrInt does nothing. But because we cant do Integer = Pointer we need this cast to be able to assign the value of the pointer to the integer (Integer = PtrInt(pointer) ).


This is quite an extensive explanation. I could have just said the last line but I wanted you to have the background information on the addObject too. Hope it was clear enough. (I'm not officially a teacher  ::) )

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #48 on: September 22, 2017, 11:06:25 am »
Hi thank you for explaining so clearly :) i think i've learned lots of stuff from you since i met you:)

Hi can you tell me what i should do make a top 10 highscore board? i am gonna put info.score and info.name


rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #49 on: September 22, 2017, 11:12:11 am »
Hi can you tell me what i should do make a top 10 highscore board? i am gonna put info.score and info.name
Just put the records in a StringGrid and sort it according to score.

But seriously... You need to think about this yourself first. Not just ask for a whole design thought.
Design is also part of software development so you need to learn that too.

How would you design a highscore board.
First think about how you want to present it to the user and then think about what components you can use for that.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #50 on: September 22, 2017, 12:31:09 pm »
Okay thank you

Can you please tell me if i am on the right track, but i don't know what to do next

please find the attachment

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #51 on: September 22, 2017, 12:49:09 pm »
Can you please tell me if i am on the right track, but i don't know what to do next
I can add a score but if I add another then it just adds it to the top. If the score is highest then it should push the previous score down (which it doesn't now).

You are on the right track with the StringGrid and rank-array.
But I would remove the writing of the file during the program run.
I would read the rank-array at startup and write it at program shutdown (OnClose or OnDestroy).

In that case you only have to deal with keeping the rank-array correct.

Make a procedure AddRank(Name: String; Score: Integer); (which you can call in Button1Click) in which you add the name in the rank procedure in the right spot. If that spot is 3 for example, you need to move 4-9 to 5-10 to make room for spot 3. After that you can fill in spot 3 and refresh the StringGrid to reflect the rank-array.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #52 on: September 22, 2017, 02:34:15 pm »
Code: Pascal  [Select][+][-]
  1. procedure AddRank;
  2. begin
  3.  for x:= 1 to 10 do
  4.  if strtoint(edit2.text) = rank[x].score then
  5.  begin
  6.    for i:= x+1 to 10 do
  7.    rank[i].score:=rank[i+1];
  8.  end;
  9. end;          

hi i compiled this but the error message said identifier not found 'edit2' and
Can you please tell me if i am on the right track, but i don't know what to do next
I can add a score but if I add another then it just adds it to the top. If the score is highest then it should push the previous score down (which it doesn't now).

You are on the right track with the StringGrid and rank-array.
But I would remove the writing of the file during the program run.
I would read the rank-array at startup and write it at program shutdown (OnClose or OnDestroy).

In that case you only have to deal with keeping the rank-array correct.

Make a procedure AddRank(Name: String; Score: Integer); (which you can call in Button1Click) in which you add the name in the rank procedure in the right spot. If that spot is 3 for example, you need to move 4-9 to 5-10 to make room for spot 3. After that you can fill in spot 3 and refresh the StringGrid to reflect the rank-array.


AddRank(Name: String; Score: Integer); i did this first but it said name and score were not found so i just deleted and just put Addrank.

also what do you mean by
Code: Pascal  [Select][+][-]
  1. But I would remove the writing of the file during the program run.
  2. I would read the rank-array at startup and write it at program shutdown (OnClose or OnDestroy).

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #53 on: September 22, 2017, 02:51:07 pm »
hi i compiled this but the error message said identifier not found 'edit2' and
Now your procedure AddRank is a "standalone" procedure and does not "belong" to Form1. So you can't access the variable in Form1 directly. You can put Form1.Edit2.Text but that's not really the correct way to do it.

You can either make AddRank procedure part of the TForm1 class (making it a procedure within that class). After that you can, just like the other events, access Edit2.Text directly.

The other way is like I showed you... with the parameters.
So
Code: Pascal  [Select][+][-]
  1. procedure AddRank(Name: String; Score: Integer);
  2. begin
  3.   // here you can use Name and Score as variables
  4. end;
In that case you can call this procedure like this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   AddRank(Edit1.Text, StrToIntDef(Edit2.Text, 0)); // <--- like this
  4.   for i:=1 to 9 do
  5.   begin
  6.     sgdata.Cells[1,i]:=rank[i].name;
  7.     sgdata.cells[2,i]:=inttostr(rank[i].score);
  8.   end;
  9. end;

also what do you mean by
Quote
But I would remove the writing of the file during the program run.
I would read the rank-array at startup and write it at program shutdown (OnClose or OnDestroy).
Don't write to your file during your programs run. So don't write to the file in Button1Click etc.
Just read the rank array from file in FormCreate
and write the rank array to file in FormClose;

If your program crashes you loose the changes but it's much easier this way.

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #54 on: September 22, 2017, 03:07:20 pm »
Code: Pascal  [Select][+][-]
  1. procedure Tform1.AddRank(Namee: String; Score: Integer);
  2. begin
  3.  for x:= 1 to 10 do
  4.  begin
  5.   if score = rank[x].score then
  6.   begin
  7.     for i:= x+1 to 10 do
  8.     rank[i].score:=rank[i+1].score;
  9.     rank[i].name:=rank[i+1].name;
  10.  
  11.      reset(highscorefile);
  12.  seek(highscorefile, filesize(highscorefile));
  13.  write(highscorefile, info);
  14.  closefile(highscorefile);
  15.  
  16.   end;
  17.  end;
  18. end;

hi is this code wrong? it still just adds it to the top.

and also if don't write to the file in Button1Click, is the updated rank will be shown on the tstringgrid?

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #55 on: September 22, 2017, 03:16:35 pm »
hi is this code wrong? it still just adds it to the top.
If it doesn't add the high score to the top then yes, this code is wrong :)


I notice fout problems with your AddRank.
1) First do proper indentation. After that you can spot the first error yourself. Try it. Post your properly indented code if you can't find it.
2) You move every score UP instead of down. You do rank[i] := rank[i+1]. That will move everything up one position. You want the opposite.
3) You don't assign the Namee and Score after moving everything down.
4) You check for score = rank[x].score. But you want to check if score is HIGHER than the rank[x].score.


Quote
and also if don't write to the file in Button1Click, is the updated rank will be shown on the tstringgrid?
Like I said... remove the entire reading and writing of the records.
You can even make the reading and writing easier because you can write THE ENTIRE ARRAY directly to disk. You don't need to write each record separately. You can just do Read(goalfile, rank) and Write(goalfile, rank). (just change the filetype to file of rankarray)

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #56 on: September 22, 2017, 03:49:02 pm »
Code: Pascal  [Select][+][-]
  1. procedure Tform1.AddRank(Namee: String; Score: Integer);
  2. begin
  3.  for x:= 1 to 10 do
  4.  begin
  5.   if score > rank[x].score then
  6.   begin
  7.     for i:= x to 10 do
  8.     begin
  9.      rank[i].score:=rank[i+1].score;
  10.      rank[i].name:=rank[i+1].name;
  11.     end;
  12.     score:=rank[x].score;
  13.     namee:=rank[x].name;
  14.  
  15.     reset(highscorefile);
  16.     seek(highscorefile, filesize(highscorefile));
  17.     write(highscorefile, info);
  18.     closefile(highscorefile);
  19.   end;
  20.  end;
  21. end;          

it is still wrong right? what else should i do?
also isn't it rank := rank[i+1] because i want them to rank down. for example if they were 4-9 i want them to be 5-10 by adding 1.

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #57 on: September 22, 2017, 04:22:19 pm »
it is still wrong right? what else should i do?
also isn't it rank[i] := rank[i+1] because i want them to rank down. for example if they were 4-9 i want them to be 5-10 by adding 1.
Your rank[1] is the highest score.
So if you have a new score what do you do to move rank[1] to the second position???
If you answer that you see why it's going wrong.

Also... you nog have x := 1 to 10.
Inside it you keep doing score > rank.
But if you found a place to put the new score you shouldn't loop any further.

So actually... you just need the loop to get the position for the new score. Nothing more.
So
Code: Pascal  [Select][+][-]
  1. x := 1;
  2. while (x <= 10) and rank[x].score >= score do inc(x);
  3. if x <= 10 then // are we still below 10?, so we broke out the previous loop with score > rank[x].score
  4. begin
  5.   // now move everything from x onward one down and put score on rank[x]
  6. end;

shs

  • Sr. Member
  • ****
  • Posts: 310
Re: need help with calender
« Reply #58 on: September 22, 2017, 04:34:58 pm »

[/quote]
Your rank[1] is the highest score.
So if you have a new score what do you do to move rank[1] to the second position???
If you answer that you see why it's going
[/quote]

You have to make it to rank[2] so you do rank[1+1] right?

rvk

  • Hero Member
  • *****
  • Posts: 6171
Re: need help with calender
« Reply #59 on: September 22, 2017, 04:36:53 pm »
You have to make it to rank[2] so you do rank[1+1] right?
Yes, so what would you write to make the value of rank[1] go to rank[1+1] (or rank[2]) ?
And how would you do that in a for loop for everything below that 1?

 

TinyPortal © 2005-2018