22.03.2017, 14:38
(
Последний раз редактировалось LetsOWN[PL]; 22.03.2017 в 15:15.
)
Quote:
So I've made this little function, which was supposed to return a simplified name of the weatherID (https://sampwiki.blast.hk/wiki/WeatherID).
PHP код:
The problems:
I've also considered to use `strcmp` (checking the first characters of the weather) instead of `strfind()`. Any help/example/tutorial would be helpful. |
pawn Код:
new const _weathers[][] = { // id type +bits
"EXTRASUNNY_LA", // 0 Sunny 2
"SUNNY_LA", // 1 Sunny 4
"EXTRASUNNY_SMOG_LA", // 2 Sunny 6
"SUNNY_SMOG_LA", // 3 Sunny 8
"CLOUDY_LA", // 4 Cloudy 10
"SUNNY_SF", // 5 Sunny 12
"EXTRASUNNY_SF", // 6 Sunny 14
"CLOUDY_SF", // 7 Cloudy 16
"RAINY_SF", // 8 Rainy 18
"FOGGY_SF", // 9 Foggy 20
"SUNNY_VEGAS", // a Sunny 22
"EXTRASUNNY_VEGAS", // b Sunny 24
"CLOUDY_VEGAS", // c Cloudy 26
"EXTRASUNNY_COUNTRYSIDE", // d Sunny 28
"SUNNY_COUNTRYSIDE", // e Sounny 30
"CLOUDY_COUNTRYSIDE", // f Cloudy 32
"RAINY_COUNTRYSIDE", // 10 Rainy 1 + 2
"EXTRASUNNY_DESERT", // 11 Sunny 1 + 4
"SUNNY_DESERT" // 12 Sunny 1 + 6
};
#define WEATHER_TYPES (19) // Just a quantity of _weathers array
new const _flags[] = {
0x410e4100, 0x2
};
new const simplifiedNames[][] = {
"Sunny", "Cloudy", "Rainy", "Foggy"
};
GetWeatherSimplifiedNameFromID(weatherid) {
new output[10];
if(weatherid >= WEATHER_TYPES) {
format(output, 10, "Undefined");
} else {
new flagsCell = 0, wid = weatherid;
while(wid >>= 4) flagsCell++; // We divide by 16, because that's how many types we can handle in single flag (_flags) - cells are 32 bit wide. We use 2 bits per weather, thus 32/2.
weatherid %= 16;
weatherid *= 2;
weatherid = (_flags[flagsCell] >> weatherid) & 3;
format(output, 10, "%s", simplifiedNames[weatherid]);
}
return output;
}
pawn Код:
for(new i = 0; i < 22; i++) {
printf("GetWeat..FromId(%d): %s", i, GetWeatherSimplifiedNameFromID(i));
}
Код:
[15:24:45] GetWeat..FromId(0): Sunny [15:24:45] GetWeat..FromId(1): Sunny [15:24:45] GetWeat..FromId(2): Sunny [15:24:45] GetWeat..FromId(3): Sunny [15:24:45] GetWeat..FromId(4): Cloudy [15:24:45] GetWeat..FromId(5): Sunny [15:24:45] GetWeat..FromId(6): Sunny [15:24:45] GetWeat..FromId(7): Cloudy [15:24:45] GetWeat..FromId(8): Rainy [15:24:45] GetWeat..FromId(9): Foggy [15:24:45] GetWeat..FromId(10): Sunny [15:24:45] GetWeat..FromId(11): Sunny [15:24:45] GetWeat..FromId(12): Cloudy [15:24:45] GetWeat..FromId(13): Sunny [15:24:45] GetWeat..FromId(14): Sunny [15:24:45] GetWeat..FromId(15): Cloudy [15:24:45] GetWeat..FromId(16): Rainy [15:24:45] GetWeat..FromId(17): Sunny [15:24:45] GetWeat..FromId(18): Sunny [15:24:45] GetWeat..FromId(19): Undefined [15:24:45] GetWeat..FromId(20): Undefined [15:24:45] GetWeat..FromId(21): Undefined
Explanation
Okay, so first of all, I've decided to hardcode weather types, because:
1) It is easy to redefine it in language-free way (i.e. you don't have to worry what foggy means)
2) It is relatively easier and faster for the CPU to compare numbers than to compare strings.. But it is obvious.
What's going on in here?
We have 4 weather types: 1) sunny, 2) cloudy 3) rainy, 4) foggy.
We can memorize those as follows:
States | Sunny | Cloudy | Rainy | Foggy |
Decimal | 0 | 1 | 2 | 3 |
Binary | 0 | 1 | 10 | 11 |
Pawn's cells are 32 bit wide - in single cell we can save 32/2 = 16 states.
0x410e4100 (_flags[0]) is equal to
00 00 00 00 01 00 00 01 00 00 11 10 01 00 00 01 00 00 00 00
I hope you can clearly see what is going on in here. Especially, if you take a look at _weathers array.
However, keep in mind that those are in reversed order (thus read it from right to left). This is to avoid more complicated maths later on.
In general, this:
pawn Код:
new const _flags[] = {
0x410E4100, 0x2
};
pawn Код:
#define WEATHER_SUNNY (0)
#define WEATHER_CLOUDY (1)
#define WEATHER_RAINY (2)
#define WEATHER_FOGGY (3)
new const _weatherTypes[] = {
WEATHER_SUNNY, // EXTRASUNNY_LA
WEATHER_SUNNY, // SUNNY_LA
WEATHER_SUNNY // EXTRASUNNY_SMOG_LA
...
};
Method | Math | Result (in bits) | Bits that are acutally used | Bits waste(%) |
Using flags | 32*2 | 64 | 38 | 40 |
2nd method | 32*19 | 608 | 38 | 93 |
pawn Код:
while(wid >>= 4) flagsCell++;
weatherid %= 16;
weatherid *= 2;
weatherid = (_flags[flagsCell] >> weatherid) & 3;
2. We take weather modulo 16, so that our offset is always from 0 to 15 (because we can save 16 different 2-bit states in a cell. That would vary, if i.e. we would use more states -> more bits per single state)
3. We multiply it by 2 to get the offset (how many bits we have to shift to get our final answer)
4. We're shifting our flag by weatherid bits and ANDing with 3 (binary: 11), as we're interested in only those last 2 bits of our result.
Any questions - lemme know.
Greetings.
If I have made any mistake in the explanation above, please correct me. Thank You.