-Request- Script to choose cheapest TPS drink

mandybrigwell

New member
I've been trying to write a script that checks the cost of all six tiny plastic sword drinks, then overdrinks one for me. Ideally, I'll like to run through an array of the six drinks finding their costs, then find the largest one and drink it. I don't seem to be able to do that - I've read the bits about maps, including 'A Noobs Guide to Maps', but I'm getting nowhere. I've trawled through a variety of scripts looking for parts where maps are defined, and I still don't seem to be able to work it out. Rest assured I've not given up after two minutes and registered an account for an easy ride - I really am completely stuck.

You'll see how stuck I am when I reveal that I've resorted to the following, totally inelegant hash-job, which won't even drink the thing at the end because I seem to be passing back a string instead of an item or something, so putting overdrink(1, drink) doesn't work. Any help at all would be greatly, greatly appreciated.

Code:
void main() {
	int cherryCost = mall_price($item[cherry]);
	int jumboOliveCost = mall_price($item[jumbo olive]);
	int limeCost = mall_price($item[lime]);
	int dirtyMartiniCost = mall_price($item[dry martini]) + jumboOliveCost;
	int vesperCost = mall_price($item[dry vodka martini]) + jumboOliveCost;
	int sangriaDelDiabloCost = mall_price($item[sangria]) + cherryCost;
	int cherryBombCost = mall_price($item[old-fashioned]) + cherryCost;
	int bodyslamCost = mall_price($item[tequila with training wheels]) + limeCost;
	int grogtiniCost = mall_price($item[grog]) + limeCost;
	int currentCost = dirtyMartiniCost;
	string drink = "Dirty Martini";
	if (vesperCost <= dirtyMartiniCost) {
		currentCost = vesperCost;
		drink = "Vesper";
	}
	if (sangriaDelDiabloCost <= vesperCost) {
		currentCost = sangriaDelDiabloCost;
		drink = "Sangria Del Diablo";
	}
	if (cherryBombCost <= sangriaDelDiabloCost) {
		currentCost = cherryBombCost;
		drink = "Cherry Bomb";
	}
	if (bodyslamCost <= cherryBombCost) {
		currentCost = bodyslamCost;
		drink = "Bodyslam";
	}
	if (grogtiniCost <= bodyslamCost) {
		currentCost = grogtiniCost;
		drink = "Grogtini";
	}
print ("Buy a " + drink + " for " + currentCost);
}
 

heeheehee

Developer
Staff member
Simplest change to your code:
Code:
item drink = $item[dirty martini];
...
drink = $item[vesper];
...

In testing an option using map literals with records, I discovered a bug with map literals (apparently it doesn't properly initialize records, so much as just store the name? it's bizarre), so that's fun.
 

AlbinoRhino

Active member
To elaborate, overdrink() requires the Data Types int & $item[]. You are giving it int & $string[].

Another simple change that would work would be to use:

overdrink(1, drink.to_item())
 
Last edited:

mandybrigwell

New member
Thank you for your help so far - that's really useful. Can anyone help me with creating an array of the drinks and their ingredients? I want to make an list of drinks of the form costOfDrink[nameOfDrink, ingredient1, ingredient2], so I try:

Code:
int[item, item, item] drinksCost;
which I think makes a map called drinksCost, which I then try to fill using:

Code:
drinksCost[$item[vesper]] = [$item[jumbo olive], $item[dry vodka martini]] = 0;
This fails with 'Internal error (testing.ash, line 3)', and I have no idea why, and reading and re-reading 'A Noob's Guide to Maps' isn't getting me any further, so I never even get to try:

Code:
print(drinksCost[0]);
to see what happens. I'm mystified...
 

Veracity

Developer
Staff member
In testing an option using map literals with records, I discovered a bug with map literals (apparently it doesn't properly initialize records, so much as just store the name? it's bizarre), so that's fun.
Gonna work up a fix? ;)
 

AlbinoRhino

Active member
Your map assignments should look more like this:

drinksCost[$item[vesper], $item[jumbo olive], $item[dry vodka martini]] = 0;
 

mandybrigwell

New member
Your map assignments should look more like this:

drinksCost[$item[vesper], $item[jumbo olive], $item[dry vodka martini]] = 0;

Yes! Thank you - I'm getting there… or, at least, somewhere!

Code:
int[item] drinksCost;
drinksCost[$item[vesper]] = mall_price($item[jumbo olive]) + mall_price($item[dry vodka martini]);
drinksCost[$item[dirty martini]] = mall_price($item[jumbo olive]) + mall_price($item[dry martini]);

foreach thisDrink in drinksCost {
	print( count(drinksCost) + " items in itemCost, and " + thisDrink + " is " + drinksCost[thisDrink]); 
}
 

xKiv

Active member
Code:
drinksCost[$item[vesper]] = [$item[jumbo olive], $item[dry vodka martini]] = 0;

How is that not a syntax error anyway?

(As a tangent, does assignment of a map into a map slice work in ASH, assuming correct types? Example:
int [string,string,int] a1;
int [string,int] a;
// fill in some values into a1 and a
a1['key'] = a;
)
 

mandybrigwell

New member
Code:
drinksCost[$item[vesper]] = [$item[jumbo olive], $item[dry vodka martini]] = 0;

How is that not a syntax error anyway?

(As a tangent, does assignment of a map into a map slice work in ASH, assuming correct types? Example:
int [string,string,int] a1;
int [string,int] a;
// fill in some values into a1 and a
a1['key'] = a;
)

It's not quite as elegant as I'd like, but I've ended up with this, which seems to work:

Code:
void main() {

if (my_inebriety() < inebriety_limit() || my_adventures() > 5) {
	abort("You're not ready to overdrink!");
	} else {
		int[item] drinksCost;
		drinksCost[$item[vesper]] = mall_price($item[jumbo olive]) + mall_price($item[dry vodka martini]);
		drinksCost[$item[dirty martini]] = mall_price($item[jumbo olive]) + mall_price($item[dry martini]);
		drinksCost[$item[sangria del diablo]] = mall_price($item[cherry]) + mall_price($item[sangria]);
		drinksCost[$item[cherry bomb]] = mall_price($item[cherry]) + mall_price($item[old-fashioned]);
		drinksCost[$item[bodyslam]] = mall_price($item[lime]) + mall_price($item[tequila with training wheels]);
		drinksCost[$item[grogtini]] = mall_price($item[lime]) + mall_price($item[grog]);
		foreach thisDrink in drinksCost {
			print("A " + thisDrink + " is " + drinksCost[thisDrink]); 
		}
		item chosenDrink = $item[vesper];
		int cost = drinksCost[$item[vesper]];
		foreach thisDrink in drinksCost {
			if (drinksCost[thisDrink] <= cost) {
				cost = drinksCost[thisDrink];
				chosenDrink = thisDrink;
			}
		}
		print ("We should drink 1 " + chosenDrink + " for " + cost);
		overdrink(1,chosenDrink);
	}
}
 

heeheehee

Developer
Staff member
Well, the ridiculously overengineered solution, which I can now suggest because of Veracity's efforts to simplify syntax for map initialization (and to fix records in map literals), looks something like this:
PHP:
record TpsDrink {
	item drink;
	item booze;
	item fruit;
};

TpsDrink[int] drinks {
  0: new TpsDrink($item[vesper], $item[jumbo olive], $item[dry vodka martini]),
  1: new TpsDrink($item[dirty martini], $item[jumbo olive], $item[dry martini]),
  2: new TpsDrink($item[sangria del diablo], $item[cherry], $item[sangria]),
  3: new TpsDrink($item[cherry bomb], $item[cherry], $item[old-fashioned]),
  4: new TpsDrink($item[bodyslam], $item[lime], $item[tequila with training wheels]),
  5: new TpsDrink($item[grogtini], $item[lime], $item[grog]),
};

int price(TpsDrink value) {
	return mall_price(value.booze) + mall_price(value.fruit);
}

void main() {
    sort drinks by price(value);
    print("We should drink 1 " + drinks[0].drink + " for " + price(drinks[0]));
    overdrink(1, drinks[0].drink);
}
 
Last edited:
Top