PieceOfMind's Advanced Combat Odds

You know, these are the reasons why I'd like to see them as a mathematician. But would it really help the gameplay and tactics of various players? I don't see how.

Maybe I'm subtley trying to force the general player to learn a bit about how combat works. ;) I mean, it wouldn't bother me if the tool was a bit educational rather than strictly useful to only tactics. Maybe I just want to make some brains out there start hurtin. :lol:

Also, regarding number of hits... with units that can get more first strikes this could be useful anyway. If a defender is heavily damaged (let's say less than 50HP), seeing that it will take 3 hits to kil will give you some encouragement to take that D2 or D3 promotion.

By the way, I can appreciate that having dived into the details of combat and the various statistics involved, I've lost a little bit of the original point of how to use the numbers in gameplay. I said a few posts ago, when I choose the high detail setting at the moment and go try a number of combats, I'm a little overwhelmed, and I have to force myself to look at the right numbers. But I think part of the problem is I've sent so many units into combat with the standard calculator that I've gotten so used to it, I can't quickly comprehend other detail when it is given to me. Having said that, I wouldn't mind betting that if this tool becomes part of the standard mod I play (maybe BUG) then I will eventually not want to go back. Personally I consider the XP values to be the single most useful thing added so far. I'm already to the point where I hate using the odds display without XP in it. Knowing the XP you will gain before combat can be a great advantage if used with some imagination.
 
Maybe I'm subtley trying to force the general player to learn a bit about how combat works. ;) I mean, it wouldn't bother me if the tool was a bit educational rather than strictly useful to only tactics. Maybe I just want to make some brains out there start hurtin. :lol:

Hmm, teaching some people a bit about combat mechanics and mathematics. Ok, I'm convinced. :p

Personally I consider the XP values to be the single most useful thing added so far. I'm already to the point where I hate using the odds display without XP in it. Knowing the XP you will gain before combat can be a great advantage if used with some imagination.

Agreed.
 
You can get the real multiplication symbol using its Unicode XML entity: "×" without the quotes.

I'm having no success with this. It's coming up with a little box []. Do you know why that may be?

Also, do you know how I could use [ICON_BULLET] in my lines? It's used throught the display of modifiers below the combat odds, but CvGameTxtMgr is pulling text from CIV4GameTextInfos.xml, which is where the [ICON_BULLET]'s are.
 
I think it's a # sign not that odd thing you're quoting

&#x0D7

Here is an example: my current code:
Code:
szTempBuffer.Format(SETCOLR L"%d" ENDCOLR L"," SETCOLR L"%d" ENDCOLR L" HP x " SETCOLR L"%d" ENDCOLR L"," SETCOLR L"%d" ENDCOLR L" hits at %.1f%%. R=" SETCOLR L"%.2f" ENDCOLR,
                                            TEXT_COLOR("COLOR_POSITIVE_TEXT"), iDamageToDefender, TEXT_COLOR("COLOR_NEGATIVE_TEXT"), iDamageToAttacker,TEXT_COLOR("COLOR_POSITIVE_TEXT"),iNeededRoundsAttacker,
                                            TEXT_COLOR("COLOR_NEGATIVE_TEXT"), iNeededRoundsDefender,float(iAttackerOdds)*100.0f / float(GC.getDefineINT("COMBAT_DIE_SIDES")),TEXT_COLOR("COLOR_POSITIVE_TEXT"),CombatRatio);
                                            szString.append(NEWLINE);szString.append(szTempBuffer.GetCString());


Should I make the change like this?


Code:
szTempBuffer.Format(SETCOLR L"%d" ENDCOLR L"," SETCOLR L"%d" ENDCOLR L" HP [COLOR="Blue"]&#x0D7[/COLOR] " SETCOLR L"%d" ENDCOLR L"," SETCOLR L"%d" ENDCOLR L" hits at %.1f%%. R=" SETCOLR L"%.2f" ENDCOLR,
                                            TEXT_COLOR("COLOR_POSITIVE_TEXT"), iDamageToDefender, TEXT_COLOR("COLOR_NEGATIVE_TEXT"), iDamageToAttacker,TEXT_COLOR("COLOR_POSITIVE_TEXT"),iNeededRoundsAttacker,
                                            TEXT_COLOR("COLOR_NEGATIVE_TEXT"), iNeededRoundsDefender,float(iAttackerOdds)*100.0f / float(GC.getDefineINT("COMBAT_DIE_SIDES")),TEXT_COLOR("COLOR_POSITIVE_TEXT"),CombatRatio);
                                            szString.append(NEWLINE);szString.append(szTempBuffer.GetCString());

EDIT
I'm guessing the only thing I can do here is to send the &#x0D7 into an entry in one of the textinfos.xml files, and pull it from there?
 
Correct, you need to pass it through the XML entries. I'm surprised it doesn't work in C++ because it should still be XML. Also, I don't see a difference between the # I pasted and the one from Anomander Rake. What am I missing? I copied and pasted that from my XML file.

As for [ICON_BULLET] et al, those definitely have to come from the XML files. getText() replaces them with the appropriate Unicode character for the font glyph they represent. You can do this in C++, but you must look them up yourself:

Code:
szText.Format(L"[B][COLOR="Blue"]%c[/COLOR][/B] blah blah", [B][COLOR="Blue"]gDLL->getSymbolID(BULLET_CHAR)[/COLOR][/B]);
 
OK, This is very odd!

I am typing in the hash sign - but when it PieceOfMind is quoting, it is getting changed to an italicised double dagger sign.

 

Attachments

  • hash double dagger.JPG
    hash double dagger.JPG
    44.8 KB · Views: 439
. . . it is getting changed to an italicised double dagger sign.

The section symbol? §

In case that doesn't come through:

Are you saying that you see

&§x0D7;

&x0D7;​

? That's very bizarre. I can't think of a reason for it to replace just the # with § rather than the whole entity reference, but I see now that phpBB doesn't seem to handle "x" in XML entities as I had to use the decimal version to get the section symbol above.

BTW, in that screenshot you posted, all I see is the hash/pound (#) symbol--no section symbol. Am I missing something?
 
EmperorFool,
How do you want to go about adding in those bars?

I can give you the code or you can give me the code - whichever.

I ask because v0.3 is pretty much good to go now.
The mod now refers to two GlobalDefines values and two TextInfos values.

Also, how is this going to go into BUG or BAT? BUG and BAT don't really make DLL changes do they? I'm not sure - all I know is I merged my BAT with Better AI and it's the Better AI DLL in the BAT folder now...
 
EmperorFool,
How do you want to go about adding in those bars?

I need to make some graphics files for them. I hate doing graphics, but at least these won't require any artistic talent. :)

If you want to get the code ready, you could use = to represent 20 and - to represent the final block. That way you can get the modulo and remainder calcs done and add the text appropriately. Changing to the images will only require changing the text in the "" that you add. I.E. trivial at that point.

Also, how is this going to go into BUG or BAT?

I have been working on a BUG DLL (BULL) for a month or so now. We're releasing 3.6 this week without the DLL and then I'll release BULL with BUG 4.0 a couple/few weeks later. Some of the features in BULL will work without BUG, but I haven't decided yet if I want to maintain a separate non-BUG BULL release. I probably won't as it would take away from features I could add for little gain.

It's going to be hard enough maintaining other merged versions for the Unofficial Patch, BetterAI, Revolutions, etc.

Edit: If you could post the latest source code, that would help me insert the graphics.
 
Ok I'll be adding the source shortly. The only new code really is the new header file and a much longer block in CvGameTxtMgr.

I'll do this with the "=" and "-" in ready for the bars. Just one small thing.

With the step where I do the modulo 20 (I assume the operator symbol is just % ?), with a number lik 53.8%, how do I round it?

eg.
Code:
(float) prob = 0.538;
int iBlockValue = (int)(100.0f * prob) % 20;
As far as I know, this just truncates the number right? i.e. always rounding down.

With step sizes of 2% it would not be a great issue anyway, as rounding down is not going to look much different, or at least no one will be able to tell the difference with their eyes except maybe if two close numbers are different lengths eg. 49.98% and 50.02%.
 
Correct, casting to (int) truncates. You can round by adding 0.5 before casting.

Code:
int iBlockValue = ((int)(100.0 * prob + 0.5)) % 20;

BTW, you don't need "f" after 100.0 since the ".0" makes it a float.
 
BTW, you don't need "f" after 100.0 since the ".0" makes it a float.
Yeah I know. I think I just do it from habit, possibly for readibility. It makes me more confident I knew it was meant to be a float :)

EDIT
I think I need to be adding 1.0 - not 0.5 - if I'm doing modulo 20.
 
I think I need to be adding 1.0 - not 0.5 - if I'm doing modulo 20.

You add the 0.5, and the (int) cast drops the fraction. Then you do the modulo 20. If you add 1.0, 23.1 will round to 24 which we clearly don't want.

round(x) = floor(x + 0.5)​

Assuming you want

[0.5, 1.5) -> 1.0​
 
Oh, sorry my bad. I thought you were using 2% increments for the bars? Me mentioning the modulo 20 was a misnomer.

If it's 2% increments you want 1.0 not 0.5.
 
Here's how I would handle this normally, and you can decide if it's the way to go or not:

  1. Determine the integer % (round to the nearest int)
  2. Determine how many 20-pixel blocks are needed (integer division by 20)
  3. Draw this many 20-pixel blocks (0 to 5)
  4. Determine which ending block (modulo by 20)
  5. Draw this block
Yes, I said 2% per pixel originally, and we can do that. If we do that, then we just divide the value from #1 by 2 after adding 1.0. Let's change the block size to 10 then so that there are still a maximum of 5 blocks per line. If we then want to make prettier block graphics later, it only requires redoing 2 colors x (10 partial + 1 full) graphics.

Code:
int pixels = ((int) 100.0 * prob + 1.0)) / 2;
int fullBlocks = pixels / 10;
int lastBlock = pixels % 10;

for (int iI = 0; iI < fullBlocks; ++iI)
{
    szBuffer.append(L"=");
}
for (int iI = 0; iI < lastBlock; ++iI)
{
    szBuffer.append(L"-");
}
 
What do you think of these bars? I kept them simple (no tick marks this time) and added rounding at the corners and highlighting/shadowing, just like the research bar (same colors). If you like them, I'll make the red versions.

  • Left End: 1 pixel wide
  • Right End: 1 pixel wide
  • Middles: 1-10 pixels
The bars below represent these probabilities:

  • 70%
  • 44%
  • 8%
  • 0%
Given how short the first one is, I say we should make it 1%/pixel. Thoughts?

Edit: I added the green bar images if you get antsy. :) Here's what the code to insert them looks like:

Code:
int pixels = (int) 100.0 * prob + 0.5);  // 1% per pixel
int fullBlocks = pixels / 10;
int lastBlock = pixels % 10;
CvWString szTempBuffer;

szBuffer.append(L"<img=Art/ACO/green_bar_left_end.dds>");
for (int iI = 0; iI < fullBlocks; ++iI)
{
    szBuffer.append(L"<img=Art/ACO/green_bar_10.dds>");
}
if (lastBlock > 0)
{
    szTempBuffer.Format(L"<img=Art/ACO/green_bar_%d.dds>", lastBlock);
    szBuffer.append(szTempBuffer);
}
szBuffer.append(L"<img=Art/ACO/green_bar_right_end.dds>");

Put the images into Assets/Art/ACO.
 
I haven't had a chance to put the images in yet, but from your post they look really good. I agree that they are a tad short so 1% per pixel will probably be best.

Remember that rarely will any value be over about 50%. Most of the time they're around about 10 to 20% and often under 10%. Only when a battle is fairly lopsided does a value reach like 70% or so. Also when a unit is very injured and will only take 1 or 2 hits to kill they could look unnaturally large. I think this is satisfactory though, as it will make it more obvious that combat is very biased when a unit is heavily injured.

Ok this is version 0.3 finished, since you requrested the newest code a bit earlier. The changes with the bars will be the main addition for v0.4. I'm also at the moment a bit distracted by the strange way combat is fudged with when it comes to free wins vs. barbs. I'm thinking I am going to alter the calculator to accurately reflect the odds vs. barbs at levels where these free wins are important. From what I have seen so far, it appears that when you still have not used up all your free kills yet, the barbs can have a maximum combat round probability of winning of 10%. This is so far skewed that the odds of beating a barb at such odds are pretty much 99%.

Anyway, the point is, this barb-related feature may go into v0.4 as well.

The newest addition to v0.3 was specific to the Everything detail level. Now the CombatRatio is given and the nearby R values that would change the XP are shown. This means you can see precisely if you are about to go over one of the thresholds, and perhaps it can be used to avoid taking a promotion one would otherwise take.
 
Top Bottom