OSCommerce: HOW to get the Value in Shipping Cost? - oscommerce

OSCommerce:
In order total, I just need the variable of the shipping cost. I need condition like, if shipping cost is zero then..... else ....
Your help is really appreciated.

There are a couple of ways to get the selected shipping method cost during checkout. The first way is to grab the cost from the $order object, like this:
if ($order->info['shipping_cost'] <= 0) {
// do something
} else {
// do something else
}
If you need to get the shipping cost without the use of the $order object, you can use the $shipping $_SESSION variable. You can easily check the selected shipping method cost like this:
if ($shipping['cost'] <= 0) {
// do something
} else {
// do something else
}

Related

Algorithm correctness for Bank Kattis problem

This is the problem I am referring to. In quick summary:
Input: An integer time T; the time in minutes in which a bank closes and a set of pairs c and t that denotes the amount of cash (integer) this person carries and the time in minutes from now after which person leaves if not served. It takes one minute to serve a person and you must begin serving a person at time t at the latest.
Output: Maximum amount of money that can be collected within closing time.
My approach was this: place all the people in a map that maps money to time. I sort this map by money. I then make a queue-like structure where I take the person with the most money and place him/her as far back as possible. If the spot is occupied, then I move forward until I find a spot. If I can't then I just don't add the person.
Below is my helper function to determine whether or not I can insert a person.
// returns index where we can insert, otherwise -1
int canInsert(bool* queue, int timeToInsert) {
if (!queue[timeToInsert]) {
return timeToInsert;
} else {
int index = timeToInsert-1;
while (index >= 0) {
if (!queue[index]) {
return index;
} else {
index--;
}
}
return -1;
}
}
Here is the main driver function:
// moneyToTime is a map that maps a person's money to the time value
int Bank(int T, map<int, int> moneyToTime) {
int answer = 0;
bool queue[47] = {0};
for (map<int,int>::reverse_iterator i = moneyToTime.rbegin(); i != moneyToTime.rend(); i++) {
if (T > 0) {
// try to insert. If we can, then add to sum. Otherwise, don't.
int potentialIndex = canInsert(queue, i->second);
if (potentialIndex != -1) {
queue[potentialIndex] = 1;
answer += i->first;
T--;
}
} else {
break;
}
}
return answer;
}
Logically, this makes sense to me and it is passing almost all the test cases. There are a couple that are failing; I can not see what they are. The test case errors are in fact indicating wrong answer, as opposed to bad runtime errors. Can someone help me see the fallacy in my approach?
You don't show how you build the moneyToTime but anyway it looks like map<int, int> is a wrong type for that. Imagine you have many people with the same amount of money and different timings. How would you represent then in your moneyToTime?
If my theory is correct, an example like this should break your solution:
3 3
2000 2
2000 1
500 2
Obviously the best sum is 4000 = 2000 + 2000. I suspect you get only 2500.
I think the best sum for the TC is 4500,
3 3
2000 2
2000 1
500 2
{money, time}
{2000,0} | {2000,1} | {500,2}

Correct way to write only the first element of a c++ stl vector

I have a c++ code that at one part it stored some values of a measurement in a vector and this vector is a part of set of data schema which is serialized and then sent to a streamer.
There is new requirement that for a specific case I need just one value of the measurement which is always rewritten with the latest one, but I don't want to change the vector variable in order to keep the same schema. So I thought that for that case to rewrite each time the first element of the vector, something like this
vector<int> store_measurements;
int measurement = 10;
if (condition == "several_values")
{
store_measurements.pushback(measurement);
}
else
{
store_measurements.at(0) = measurement ;
}
It seems to work fine when the vector is not cleared, but I'd like to ask if this is the correct way to do that or there is a more preferable way to do it?
You can use the front() function.
vector<int> store_measurements;
int measurement = 10;
if (condition == "several_values")
{
store_measurements.push_back(measurement);
}
else
{
store_measurements.resize(1);
store_measurements.front() = measurement ;
}
Edit:
Based on the comments I added store_measurements.resize(1); before the assignment
I would probably use assign() which replaces all the values in the vector like this:
if (condition == "several_values")
{
store_measurements.push_back(measurement);
}
else
{
store_measurements.assign(1, measurement);
}

How to stop more than one being removed from an integer?

I know the title may seem fairly confusing, was just unsure on how to ask this...
So, I'm working on a basic sample game (not going to be a complete game or anything), where you can move around and are chased by an enemy character that attacks you. The problem is that when the attack function is called, instead of only removing one heart/hitpoint, they continue to be 'spam removed'. Here's what I'm working with...
void Enemy::attackPlayer()
{
if (distance < 50)
{
Player::health--;
return;
}
}
Pretty simple, right? Well the problem is that I need some way of I guess 'sleeping' the single function so that instead of continuing to remove health, it stops after one, then after let's say, 3 seconds, allows another attack to occur.
I think you can create two global time variables that are passed to your attack function. startTime is initiated once you call your attack function (outside). endTime is initiated right after removing one health from player (inside your function). Then you simply add a if statement before the distance if statement to check the delta time between these two and if they are more than 3 seconds then do the rest to remove another health.
You could probably have the Enemy class contain a method like:
bool canAttack(){
if(attackTimer >= 3000){
attackTimer = 0;
return true;
}
return false;
}
Then you could modify your damage condition to be something like:
if (distance < 50 && canAttack())
Of course, you would have to add a timer to the Enemy class and have it start and stop based on proximity to the player.
I'm sure there is a better way to handle this--also, this depends a bit on the implementation of the rest of your code. If you are using something like SFML, there is a built-in event system that would make this a bit easier to handle. Hopefully this helps a bit!
After taking some of the answers you guys gave me into consideration and messing around with some things by myself, I've came up with a pretty simple solution:
int Enemy::attackTime = 0;
And then...
void Enemy::attackPlayer()
{
if (distance > 60)
return;
if (time(0) > attackTime)
{
attackTime = time(0) + 3;
Player::health--;
}
}
I guess, player won't get another attacked from any enemy for 3 seconds. However, enemy can attack to another player if exist. Thus, this timer variable is keep into Player class. If I am correct, I think this code will work.
class Player
{
private:
uint32_t last_attack_timer;
...
public:
void set_last_attack_timer(uint32_t timer){this->last_attack_timer = timer;};
uint32_t get_last_attack_timer(void){return last_attack_timer;};
...
}
void Enemy::attackPlayer()
{
uint32_t timer = time(0);
if (distance < 50 && timer-Player::get_last_attack_timer>3000)
{
Player::health--;
Player::set_last_attack_timer(timer(0));
return;
}
}

Is there a way to make a function do something different the second time a number appears?

Im trying to make a small program about the method in which the amount of money awarded to players at the end of a game is decided. So far I have used a RNG to simulate what happens in a round of the game but have gotten stuck. I want to find out how to design my code in order for it to do something different the second time the same number is generated from the RNG.
while (active==1)
{
random=rand()%11+1;
if (random==11)
{
bomb=1;
}
}
Thanks for any responses :)
Keep a map of (number, count) pairs:
std::unordered_map<int, std::size_t> number_frequencies;
while (active) {
int number = random_number();
++number_frequencies[number];
if (number_frequencies[number] == 2) {
// do something
} else {
// do something else
}
}
First of all, for clarity, apply the following:
Define MAX to whatever maximum value you want to have (e.g., 11)
Use random between 0 and MAX-1 (instead of between 1 and MAX)
Then, you can try to adjust the following piece of code to your requirements:
#define MAX 11
...
int count[MAX] = {0};
while (active == 1)
{
random = rand()%MAX;
count[random]++;
...
}
The count array indicates the number of times that each random value was generated.
So at each iteration, you can use count[random] in order to choose what action to take.

Checking lists and running handlers

I find myself writing code that looks like this a lot:
set<int> affected_items;
while (string code = GetKeyCodeFromSomewhere())
{
if (code == "some constant" || code == "some other constant") {
affected_items.insert(some_constant_id);
} else if (code == "yet another constant" || code == "the constant I didn't mention yet") {
affected_items.insert(some_other_constant_id);
} // else if etc...
}
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++)
{
switch(*it)
{
case some_constant_id:
RunSomeFunction(with, these, params);
break;
case some_other_constant_id:
RunSomeOtherFunction(with, these, other, params);
break;
// etc...
}
}
The reason I end up writing this code is that I need to only run the functions in the second loop once even if I've received multiple key codes that might cause them to run.
This just doesn't seem like the best way to do it. Is there a neater way?
One approach is to maintain a map from strings to booleans. The main logic can start with something like:
if(done[code])
continue;
done[code] = true;
Then you can perform the appropriate action as soon as you identify the code.
Another approach is to store something executable (object, function pointer, whatever) into a sort of "to do list." For example:
while (string code = GetKeyCodeFromSomewhere())
{
todo[code] = codefor[code];
}
Initialize codefor to contain the appropriate function pointer, or object subclassed from a common base class, for each code value. If the same code shows up more than once, the appropriate entry in todo will just get overwritten with the same value that it already had. At the end, iterate over todo and run all of its members.
Since you don't seem to care about the actual values in the set you could replace it with setting bits in an int. You can also replace the linear time search logic with log time search logic. Here's the final code:
// Ahead of time you build a static map from your strings to bit values.
std::map< std::string, int > codesToValues;
codesToValues[ "some constant" ] = 1;
codesToValues[ "some other constant" ] = 1;
codesToValues[ "yet another constant" ] = 2;
codesToValues[ "the constant I didn't mention yet" ] = 2;
// When you want to do your work
int affected_items = 0;
while (string code = GetKeyCodeFromSomewhere())
affected_items |= codesToValues[ code ];
if( affected_items & 1 )
RunSomeFunction(with, these, params);
if( affected_items & 2 )
RunSomeOtherFunction(with, these, other, params);
// etc...
Its certainly not neater, but you could maintain a set of flags that say whether you've called that specific function or not. That way you avoid having to save things off in a set, you just have the flags.
Since there is (presumably from the way it is written), a fixed at compile time number of different if/else blocks, you can do this pretty easily with a bitset.
Obviously, it will depend on the specific circumstances, but it might be better to have the functions that you call keep track of whether they've already been run and exit early if required.