subtracting from a multi-dimensional list

0 views
Skip to first unread message

basil60

unread,
Dec 21, 2009, 7:28:23 PM12/21/09
to MOO Talk
I'm trying to subtract from a multi-dimensional list.
I got lots of help in a previous thread.

The list looks like this:
{{"Pepsi", #232, 10}, {"Coke", #263, 10}, {"Fanta", #264, 10}} and
it's called stuff _in.

I want to be able to say "deduct 1 from available Pepsi - so I used
this

"this.stuff_in[1][3] = this.stuff_in[1][3] - 1";

It didn't work, but sent my list crazy, returning errors like "Range
Errors" or "Type Mismatch errors".

Can anyone help with correct syntax please?

Basil

Paul Rayner

unread,
Dec 30, 2009, 6:51:54 PM12/30/09
to MOO Talk
Bump

Just wondering if anyone has had a chance to look at this and provide some advice.

I'm just tidying up my vending machine, and want to reduce the amount of Pepsi held in the list each time it's selected.


The list looks like this:
{{"Pepsi", #232, 10}, {"Coke", #263, 10}, {"Fanta", #264, 10}} and
it's called stuff _in.
I curently use  "this.stuff_in[1][3] = this.stuff_in[1][3] - 1"; which returns either a "Range

Errors" or "Type Mismatch errors".
So basically I need help with the syntax to reduce Pepsi by 1!!

I'll also need to create a refill verb. Assuming for now, I'll only let a wizard do it,  I used the syntax:

if (!(player.name in this.wiz))
"refill list;"

Is there a more elegant way to do that? Like a built in fucntion?

Cheers

and Happy New Year

Michael Taboada

unread,
Dec 30, 2009, 7:08:35 PM12/30/09
to moo-...@googlegroups.com
Well, there must be something wrong with your list.
Assuming the 10 is definitely a number, and not a string, and assuming that the list is {{whatever}, {whatever2}, {whatever3}} and not {"{whatever}, {whatever2}, {whatever3}"}, then you should have no problem.
Try typing ;<number of vending machine>.stuff_in and telling us what it says.
Also you can try ;<number>.stuff_in[1][3]; and ;<number>.stuff_in[1][3]-1; to see what happens.
It might also be helpful to post that here.
Happy newyears.
 
-Michael
 
AI5HF
 
Http://ai5hf.mtgames.org/
http://moo.mtgames.org/
"A world that contained something as amazing as that bumblebee was a world in which he wanted to live." -- Christopher Paolini, Brisingr
"The songs of the dead are the lamentations of the living." -- Christopher Paolini, Eldest
skype: lilmike2
msn: ai...@hotmail.com
gmail: ai5hf....@gmail.com
 
pc details:
Intel quad core q6700-2.66 GHz; 4 gb ddr2 duel channel ram; 500 gb harddrive; windows xp pro.

--

You received this message because you are subscribed to the Google Groups "MOO Talk" group.
To post to this group, send email to MOO-...@googlegroups.com.
To unsubscribe from this group, send email to MOO-talk+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/MOO-talk?hl=en.

Paul Rayner

unread,
Dec 30, 2009, 7:17:11 PM12/30/09
to moo-...@googlegroups.com
Outputs go like this:
#253.stuff_in
=> {"{{\"Pepsi\", #232, 5}, {\"Coke\", #263, 5}, {\"Fanta\", #264, 5}}"}
#253.stuff_in[1][3]
=> "\""
So there's the problem I guess. But I don't know why, other than I used the enCore editor, which apparently does some odd things at times. Apologies to the enCore people - it could be operator error.

I did follow Luke_jrs advice and use eval #253.stuff_in = {}
eval #253.stuff_in = {@#253.stuff_in, {"Pepsi", #211, 10}}
eval #253.stuff_in = {@#253.stuff_in, {"Coke", #251, 10}}
eval #253.stuff_in = {@#253.stuff_in, {"Fanta", #252, 10}}
to fix it at times.
Cheers

Paul Rayner

unread,
Dec 30, 2009, 7:30:05 PM12/30/09
to moo-...@googlegroups.com
So I used the eval lines - and ran #253.stuff_in[1][3]
and it returned 5. Perfect!

Then, when I run select drink_machine, and choose 1 (a pepsi)
I get the error:

#253:select, line 9:  Type mismatch
The full code for the select verb is:

 1: player:tell("For an icy cold drink - select from the following. Press 1 for Pepsi, 2 for Coke or 3 for Fanta");
 2: n = toint($command_utils:read("your selection"));
 3: "check to see if can is full, or if there are any cans left";
 4: if (#232.remaining < 100 && this.stuff_in[n][3] <= 0)
 5:   player:tell("Sorry, you're out of luck. Someone hasn't filled the drink machine. Try a little later");
 6: else
 7:   if (n == 1)
 8:     thing = $recycler:_create(this.stuff_in[n][2]);
 9:     thing.name = this.stuff_in[n][1];
10:     "thing.aliases = {thing.name}";
11:     player:tell("You've selected a Pepsi");
12:     thing:moveto(player);
13:     this.stuff_in[1][3] = this.stuff_in[1][3] - 1;
14:   elseif (n == 2)
15:     thing = $recycler:_create(this.stuff_in[n][2]);
16:     "set all the props";
17:     thing.name = this.stuff_in[n][1];
18:     "thing.aliases = {thing.name}";
19:     player:tell("You've selected a Coke");
20:     "move to player";
21:     thing:moveto(player);
22:   elseif (n == 3)
23:     thing = $recycler:_create(this.stuff_in[n][2]);
24:     thing.name = this.stuff_in[n][1];
25:     "thing.aliases = {thing.name}";
26:     player:tell("You've selected a Fanta");
27:     thing:moveto(player);
28:     "check to see if he entered valid input";
29:   else
30:     player:tell("Sorry, that's not a choice!");
31:   endif
32: endif

Thanks

Michael Taboada

unread,
Dec 30, 2009, 7:47:04 PM12/30/09
to moo-...@googlegroups.com
Try replacing n with 1 in line 9.

Michael Taboada

unread,
Dec 30, 2009, 7:51:07 PM12/30/09
to moo-...@googlegroups.com
Also, does it do the same thing in 2 and 3?
You could also try ;#253.stuff_in[1][1];
 
-Michael
 
AI5HF
 
Http://ai5hf.mtgames.org/
http://moo.mtgames.org/
"A world that contained something as amazing as that bumblebee was a world in which he wanted to live." -- Christopher Paolini, Brisingr
"The songs of the dead are the lamentations of the living." -- Christopher Paolini, Eldest
skype: lilmike2
msn: ai...@hotmail.com
gmail: ai5hf....@gmail.com
 
pc details:
Intel quad core q6700-2.66 GHz; 4 gb ddr2 duel channel ram; 500 gb harddrive; windows xp pro.
Sent: Wednesday, December 30, 2009 6:30 PM

Tyler Littlefield

unread,
Dec 30, 2009, 7:33:22 PM12/30/09
to moo-...@googlegroups.com
why do you have quotes around your array? it should look like: {{"pepsi",#x,10},{"mountain dew",#x,50}}

Tyler Littlefield

unread,
Dec 30, 2009, 7:35:20 PM12/30/09
to moo-...@googlegroups.com
Hello,
I can help you over msn if it'd be easier to troubleshoot this. If not, do something like: player:tell(tostr(thing)); and see what $recycler:_create is doing.
If you prefer the msn approach, my msn is just my email--feel free to add.

Paul Rayner

unread,
Dec 30, 2009, 8:38:47 PM12/30/09
to moo-...@googlegroups.com
I've been able to get it sort of working. Problems now are down to a "type mismatch" on line 12 - which on the select verb is:
 "thing:moveto(player)";
I commented it out to see if everything else works. Which it does!

@create $thing named drink_machine:drink_machine
@prop #253."stuff_in" {} rc
;;#253.("stuff_in") = {{"Pepsi", #232, 4}, {"Coke", #263, 5}, {"Fanta", #264, 5}}


@verb #253:"select" this none none rxd
@program #253:select

player:tell("For an icy cold drink - select from the following. Press 1 for Pepsi, 2 for Coke or 3 for Fanta");
n = toint($command_utils:read("your selection"));
"check to see if can is full, or if there are any cans left";
if ((#232.remaining < 100) || (this.stuff_in[n][3] <= 0))

  player:tell("Sorry, you're out of luck. Someone hasn't filled the drink machine. Try a little later");
else
  if (n == 1)

    thing = $recycler:_create(this.stuff_in[n][2]);
    "thing.name = this.stuff_in[1][1]";
    "thing.aliases = {thing.name}";

    player:tell("You've selected a Pepsi");
    "thing:moveto(player)";

    this.stuff_in[1][3] = this.stuff_in[1][3] - 1;
  elseif (n == 2)

    thing = $recycler:_create(this.stuff_in[n][2]);
    "set all the props";
    "thing.name = this.stuff_in[2][1]";
    "thing.aliases = {thing.name}";

    player:tell("You've selected a Coke");
    "move to player";
    "thing:moveto(player)";
  elseif (n == 3)

    thing = $recycler:_create(this.stuff_in[n][2]);
    "thing.name = this.stuff_in[3][1]";
    "thing.aliases = {thing.name}";

    player:tell("You've selected a Fanta");
    "thing:moveto(player)";

    "check to see if he entered valid input";
  else

    player:tell("Sorry, that's not a choice!");
  endif
endif
"Last modified Thu Dec 31 11:15:41 2009 EST by woger (#197).";
.

@verb #253:"test" this none none rxd
@program #253:test
player:tell(this.stuff_in[3][1]);
suspend(5);
player:tell(toliteral(this.stuff_in[1]));
"Last modified Mon Dec 21 15:22:58 2009 EST by woger (#197).";
.

@verb #253:"refill" this none none rxd
@program #253:refill
if (!(player.name in this.wiz))
  player:tell("You need to  Wizard to perfrom this action!");
else
  this.stuff_in = {{"Pepsi", #232, 5}, {"Coke", #263, 5}, {"Fanta", #264, 5}};
  player:tell("The drink machine has been refilled ready to go again.");
endif
"Last modified Thu Dec 31 11:28:51 2009 EST by woger (#197).";
.

Seth I. Rich

unread,
Dec 30, 2009, 10:27:05 PM12/30/09
to moo-talk
> I'll also need to create a refill verb.
> Assuming for now, I'll only let a wizard do it,  I used the syntax:
>
> if (!(player.name in this.wiz))

Check the player's .wizard property.  If it's 1, it's a wizard.  So just:

if (player.wizard) ...

Seth
--
Seth I. Rich - se...@briar.com
Rabbits on walls, no problem.

michael munson

unread,
Dec 31, 2009, 9:17:54 AM12/31/09
to moo-...@googlegroups.com
Paul, I see some problems with this verb.... see below as to how I would do it. The main problems are that it isn't very easy for someone to add new drinks.


 1:  names = $list_utils:slice(this.stuff_in, 1);
 2:  namesStr = "";
 3:  for x in [1..length(names)]
 4:    namesStr = tostr(namesStr, x, " for ", names[x], " ");
 5:  endfor
 6:  player:tell("For an icy cold drink - select from the following. Press ", namesStr);
 7:  selection = toint($command_utils:read("your selection"));
 8:  if (selection < 0 || selection > length(this.stuff_in))
 9:    return player:tell("Invalid selection, please select between 1 and ", length(this.stuff_in), ".");
10:  endif
11:  if (#232.remaining < 100 && this.stuff_in[selection][3] <= 0)
12:    player:tell("Sorry, you're out of luck. Someone hasn't filled the drink machine. Try a little later");
13:  else
14:    drinkObj = $recycler:_create(this.stuff_in[selection][2]);
15:    drinkObj.name = this.stuff_in[selection][2].name;
16:    drinkObj.aliases = this.stuff_in[selection][2].aliases;
17:    drinkObj.description = this.stuff_in[selection][2].description;
18:    drinkObj:moveto(player);
19:    if (drinkObj.location != player)
20:      player:tell("You can't carry the drink!");
21:      drinkObj:moveto(this.location);
22:    endif
23:    player:tell("You've selected a ", drinkObj.name, "!");
24:    this.stuff_in[selection][3] = this.stuff_in[selection][3] - 1;
25:  endif



Paul Rayner

unread,
Dec 31, 2009, 4:13:54 PM12/31/09
to moo-...@googlegroups.com
Certainly more elegant. I'm not sure of some of the commands or concepts you've used. Can i add comments and get you to tell me if I got it right?

Happy new Year

Michael Munson

unread,
Dec 31, 2009, 4:16:34 PM12/31/09
to moo-...@googlegroups.com
Sure, go ahead.

Regards,
Michael
iPhone 3G

Paul Rayner

unread,
Dec 31, 2009, 5:34:57 PM12/31/09
to moo-...@googlegroups.com
Thanks Michael - very slick in comparison to what I produced.
Does this look like a reasonable interpretation of what you've done?
There's just one question there in the comments:

 "get the 1st element from each item in the list";

 names = $list_utils:slice(this.stuff_in, 1);
 'ensure names is a string";
 namesStr = "";
 "check for each item in the list from 1 to the end in names";
 for x in [1..length(names)]
 "programatically produce 1 for Pepsi 2 for Coke 3 for Fanta";

 namesStr = tostr(namesStr, x, " for ", names[x], " ");
  endfor

    player:tell("For an icy cold drink - select from the following. Press ", namesStr);
  selection = toint($command_utils:read("your selection"));
  "check that the number they type is in range - 1 to the highest number in the list";

if (selection < 0 || selection > length(this.stuff_in))
  return player:tell("Invalid selection, please select between 1 and ", length(this.stuff_in), ".");
  endif

  if (#232.remaining < 100 && this.stuff_in[selection][3] <= 0)
    player:tell("Sorry, you're out of luck. Someone hasn't filled the drink machine. Try a little later");
  else
  "is Obj just explictly declaring drink as an Obj, like in actionscript where dataypes are strongly typed?";

    drinkObj = $recycler:_create(this.stuff_in[selection][2]);
   drinkObj.name = this.stuff_in[selection][2].name;
    drinkObj.aliases = this.stuff_in[selection][2].aliases;
    drinkObj.description = this.stuff_in[selection][2].description;
   drinkObj:moveto(player);
    if (drinkObj.location != player)

     player:tell("You can't carry the drink!");
      drinkObj:moveto(this.location);
    endif

    player:tell("You've selected a ", drinkObj.name, "!");
   this.stuff_in[selection][3] = this.stuff_in[selection][3] - 1;
  endif

Michael Taboada

unread,
Dec 31, 2009, 5:44:39 PM12/31/09
to moo-...@googlegroups.com
That's basically telling you more clearly what the variable is for such as namesStr for a string of names, feel free to use anythinhg you want, such as namesofdrinks.
Likewise with the obj, that's just saying this is the obj of the drink.
Again, you can feel free to use anything, but these make it a little more clear.
-Michael
 
AI5HF
 
Http://ai5hf.mtgames.org/
http://moo.mtgames.org/
"A world that contained something as amazing as that bumblebee was a world in which he wanted to live." -- Christopher Paolini, Brisingr
"The songs of the dead are the lamentations of the living." -- Christopher Paolini, Eldest
skype: lilmike2
msn: ai...@hotmail.com
gmail: ai5hf....@gmail.com
 
pc details:
Intel quad core q6700-2.66 GHz; 4 gb ddr2 duel channel ram; 500 gb harddrive; windows xp pro.
Sent: Thursday, December 31, 2009 4:34 PM

Paul Rayner

unread,
Dec 31, 2009, 5:46:05 PM12/31/09
to moo-...@googlegroups.com
Thanks Michael
awesome help
Ciao

michael munson

unread,
Dec 31, 2009, 7:40:53 PM12/31/09
to moo-...@googlegroups.com
Yes, thats just how I name variables sometimes.

Stephen Gigante

unread,
Dec 31, 2009, 9:12:15 PM12/31/09
to moo-...@googlegroups.com
In term of naming schemes, never set the following variables, as they are builtin variables.
STR=2
OBJ=1
LIST=4
INT=0
FLOAT=9

These variables are there for use with the typeof() builtin, and while they can be changed, I'd recommend not doing so. (Changing Caller or player is equally disadvised unless done for a clear reason.)

 -Stephen

Paul Rayner

unread,
Dec 31, 2009, 10:38:02 PM12/31/09
to moo-...@googlegroups.com
Thanks Stephen - but i'm not really sure what you mean. Any chance of a simple, practical example?

Stephen Gigante

unread,
Jan 10, 2010, 4:57:08 AM1/10/10
to moo-talk
Something along the lines of:

$SomeUtils:verbthatneedsalist

givenvalue = args[1];
if (typeof(givenvalue) != LIST)
  Givenvalue = {givenvalue};
endif
"Now that we have the list, we can work with it.";
.

If we were wanting something other than a LIST, a toint(givenvalue) could deal with it, but forcing a list must be done by putting the variable in brackets, and if it were already a list, that would end up with something like this,  {{#3,#9,#5621}}, Which will give the same E_TYPE as leaving a single value as not a list.

Hope that made more sense.

 - Stephen

Oh, and sorry about the delay in replying.
Reply all
Reply to author
Forward
0 new messages