Entraides et échanges autour de la technologie Scol - Informations and exchanges on the Scol technology
Vous pouvez changer la langue de l'interface une fois inscrit - You can change the language once registered
You are not logged in.
I would like to iterate through a list of the type:
[[I myobject_sctruct] r1]
for each tuple, I want to change a particular field of the myobject_struct, such for example, myproperty (which is an Interger)
would this work?
psuedo code:
function iterate_list(list_to_iterate) =
let list_to_iterate -> [first_element rest_of_elements] in
//open let brace
(
if (first_element == nil) then
(
//I'm done
0;
)
else
(
let first_element-> [Interger_ID object_I_want] in
//open let brace
(
set object_I_want.myproperty=5;
//rest of code, etc
set list_to_iterate = rest_of_elements;
iterate_list list_to_iterate;
//close let brace
);
//return 0 and close if then else brace
0;
);
//close let brace
);
0;;
In other words, can I treat each tuple in a list of tuples as a list as well?
thx!
-h
Last edited by hebdemnobad (18-Dec-2013 15:40:32)
Offline
No.
Your first IF must be done on the list, not on the first element. Indeed, the first element can be nil without the list is nil itself.
In pseudo-code, you should write something like this :
function ITERATE_LIST (LIST)=
if LIST == NIL then
A_VALUE // i'm done
else
let hd LIST -> [INTEGER STRUCTURE] in // hd gets the first element
(
set STRUCTURE.PROPERTY = 5;
...
ITERATE_LIST tl LIST // tl gets the next of the list
);;
The function must be recurive. It is not easy to understand.
Your function loops on the entire list.
At each loop, the first element is processed and we continue the loop with the next of the list.
Until the last element which it is always nil : we exit.
If you want, you can post your function. Otherwise, i can give you the result. ;-)
Offline
thx I will work on that Iri
Offline
If any, to understand the recursive functions, you can read this page on Wikipedia about this :
https://en.wikipedia.org/wiki/Recursion … science%29 you'll find some explanations and examples
Offline
fwiw this works, although Iri your code is more compact so I'll be using the hd and tl method
//make a list of tuples, each containing an integer and string
typeof wordlist= [[I S]r1];;
fun iterate_list(list_to_iterate) =
let list_to_iterate -> [first_element rest_of_elements] in
//open let brace
(
if (list_to_iterate == nil) then
(
//I'm done
_fooS "I'm done";
0;
)
else
(
//break down the first element into its parts, which are an interger and a string
let first_element-> [Interger_ID object_I_want] in
//open let brace
(
_fooS object_I_want;
//chop off first element of list and shrink it down by one element
set list_to_iterate = rest_of_elements;
//repeat function on shrunken list
iterate_list list_to_iterate;
//close let brace
);
//return 0 and close if then else brace
0;
);
//close let brace
);
0;;
fun main()=
_showconsole;
//"when harry and john met sally"...I think its the name of an american play or movie, I forget which
set wordlist= [1 "harry"]:: [ 3 "john"]::[8 "sally"] :: nil;
iterate_list wordlist;;
Last edited by hebdemnobad (18-Dec-2013 20:39:47)
Offline
Your code is wrong.
- Put " let list_to_iterate -> [first_element rest_of_elements] in " in the ELSE block.
- The function must be return a value only when the list is nil. So, you should remove all others 0. if you keep them, the function could enter in the too long (or too short) loop and get an undefined result.
PS : ""when harry and john met sally", There is not a John in this story ! Just Harry and Sally.
In french, the title is "Quand Harry rencontre Sally"
Offline
Your code is wrong.
- Put " let list_to_iterate -> [first_element rest_of_elements] in " in the ELSE block.
- The function must be return a value only when the list is nil. So, you should remove all others 0. if you keep them, the function could enter in the too long (or too short) loop and get an undefined result.PS : ""when harry and john met sally", There is not a John in this story ! Just Harry and Sally.
In french, the title is "Quand Harry rencontre Sally"
too bad for Sally, in any case try it out the code works.
but I'm going to follow your example in any case
Offline
fun iterate_list (list_to_iterate)=
if (list_to_iterate == nil) then
(
//I'm done
_fooS "I'm done";
0;
)
else
let list_to_iterate -> [first_element rest_of_elements] in
//break down the first element into its parts, which are an interger and a string
let first_element-> [Interger_ID object_I_want] in
//open let brace
(
_fooS object_I_want;
//chop off first element of list and shrink it down by one element
set list_to_iterate = rest_of_elements;
//repeat function on shrunken list
iterate_list list_to_iterate;
//close let brace
);;
another suggestion :
fun iterate_list (list_to_iterate)=
if list_to_iterate == nil then
(
_fooS "I'm done";
0
)
else
let hd list_to_iterate -> [Interger_ID object_I_want] in // first element with hd
(
_fooS object_I_want;
iterate_list tl list_to_iterate; //repeat function on shrunken list *** with tl
);;
Offline
fun iterate_list (list_to_iterate)= if (list_to_iterate == nil) then ( //I'm done _fooS "I'm done"; 0; ) else let list_to_iterate -> [first_element rest_of_elements] in //break down the first element into its parts, which are an interger and a string let first_element-> [Interger_ID object_I_want] in //open let brace ( _fooS object_I_want; //chop off first element of list and shrink it down by one element set list_to_iterate = rest_of_elements; //repeat function on shrunken list iterate_list list_to_iterate; //close let brace );;
another suggestion :
fun iterate_list (list_to_iterate)= if list_to_iterate == nil then ( _fooS "I'm done"; 0 ) else let hd list_to_iterate -> [Interger_ID object_I_want] in // first element with hd ( _fooS object_I_want; iterate_list tl list_to_iterate; //repeat function on shrunken list *** with tl );;
Thx. I think I'm become a list master.
Offline
fun iterate_list (list_to_iterate)= if (list_to_iterate == nil) then ( //I'm done _fooS "I'm done"; 0; ) else let list_to_iterate -> [first_element rest_of_elements] in //break down the first element into its parts, which are an interger and a string let first_element-> [Interger_ID object_I_want] in //open let brace ( _fooS object_I_want; //chop off first element of list and shrink it down by one element set list_to_iterate = rest_of_elements; //repeat function on shrunken list iterate_list list_to_iterate; //close let brace );;
another suggestion :
fun iterate_list (list_to_iterate)= if list_to_iterate == nil then ( _fooS "I'm done"; 0 ) else let hd list_to_iterate -> [Interger_ID object_I_want] in // first element with hd ( _fooS object_I_want; iterate_list tl list_to_iterate; //repeat function on shrunken list *** with tl );;
Thx. I think I'm becoming a list master.
Last edited by hebdemnobad (19-Dec-2013 18:18:54)
Offline
thx for your help Iri, here is the finished code block using your method. I have to add the rotation test too, but it's all working.
//see if a particular remote bot in the list [[I Remote_bot]r1] has changed position. if it has, set the old position to the new one
//otherwise, don't update.
// the old position list_to iterate is the structure [[I Remote_bot]r1], remote_bot_id is I, new_remote_bot_position is [F F F]
// and new_remote_bot_rotation is [F F F F]
fun scan_through_bot_list_and_set_values(list_to_iterate, remote_bot_id, new_remote_bot_position, new_remote_bot_rotation) =
if (list_to_iterate == nil) then
(
//do nothing
0;
)
else
(
let hd list_to_iterate -> [id remote_bot] in // hd gets the first element
(
if (id== remote_bot_id) then
(
if ((vectorEqualF remote_bot.Remote_bot_old_position new_remote_bot_position)==1) then
(
let remote_bot.Remote_bot_new_position -> [px py pz] in
let new_remote_bot_position -> [npx npy npz] in
//open let brace
(
if (((absf (px-.npx)) >. 0.21)|| ((absf (py-. npy)) >. 0.21) || ((absf (pz-. npz)) >. 0.21) ) then
(
_ADDcompText ongoing_chat_textfield strcatn "\n":: "the remote bot y position is" :: (ftoa py):: "and x position is ":: (ftoa px):: "and z position is":: (ftoa pz):: "\n" :: nil hacker_font [0x00FFFF 0 0 0xFFFF00] CT_END;
//update contents of chat interface
_PAINTcontainer hacker_window_object_container; 0;
set remote_bot.Remote_bot_new_position = new_remote_bot_position;
//close let braces
0;
)else
(
_ADDcompText ongoing_chat_textfield strcatn "\n"::"no significant change"::"\n"::nil hacker_font [0x00FFFF 0 0 0xFFFF00] CT_END;
//update contents of chat interface
_PAINTcontainer hacker_window_object_container; 0;
0;
);
0;
);
)
else
(
//do nothing and close if then else brace
0;
);
)
else
(
//return 0 and close if then else brace
0;
);
//shrink list_to_iterate
set list_to_iterate = tl list_to_iterate;
scan_through_bot_list_and_set_values list_to_iterate remote_bot_id new_remote_bot_position new_remote_bot_rotation;
//return 0 and close let brace
0;
);
//return 0 and close if then else brace
0;
);
0;;
Last edited by hebdemnobad (20-Dec-2013 16:18:43)
Offline
There are a lot of braces but if they are an help for you, it's good use
what I am trying to do is have the vm check if the values have changed enough with a new message from the server. if the values haven't changed much, then the vm won't upate the remote_bot properties and os3d won't undertake any setposition and setorientation operations. that's my reasoning in terms of optimization. if figure the less that goes on with ogre, the better, no?
Offline
The better way to optimise is on the number of client messages.
The test on position is not sufficient.
A client should send it's position on regular time, but don't send a position he already sent, actually the user item position value.
You just have to check if the position has change before to set or not the new user item value.
So other clients won't get a set position message, but they will have the last correct position.
So for example :
In the render scene event, you check the last time call, if the last call is > to 30 ms and the position is different than the last position you can set the user item position.
Then others clients get the new user position value.
You make the interpolation between the positions.
This way you will be able the test and optimze by changing the 30ms interval of set positions.
Offline
The better way to optimise is on the number of client messages.
The test on position is not sufficient.A client should send it's position on regular time, but don't send a position he already sent, actually the user item position value.
You just have to check if the position has change before to set or not the new user item value.
So other clients won't get a set position message, but they will have the last correct position.So for example :
In the render scene event, you check the last time call, if the last call is > to 30 ms and the position is different than the last position you can set the user item position.Then others clients get the new user position value.
You make the interpolation between the positions.This way you will be able the test and optimze by changing the 30ms interval of set positions.
I totally forgot this...yes each client will do the position and rotation tests before sending a message to the server.
As for the user item method, is it easier on the server than the message method that I use? I think I will do that eventually, but first I will finish with the message method and a list of remote_bots, along with interpolation (for which I will need some help).
-h
Offline