Matrix Games Forums

Forums  Register  Login  Photo Gallery  Member List  Search  Calendars  FAQ 

My Profile  Inbox  Address Book  My Subscription  My Forums  Log Out

Even rolls?

 
View related threads: (in this forum | in all forums)

Logged in as: Guest
Users viewing this topic: none
  Printable Version
All Forums >> [New Releases from Matrix Games] >> Conflict of Heroes Series >> Even rolls? Page: [1]
Login
Message << Older Topic   Newer Topic >>
Even rolls? - 5/13/2012 4:36:05 AM   
Ocean1

 

Posts: 27
Joined: 7/29/2009
Status: offline
A question, which I hope you'd feel ok answering if it is the case: Are the rolls and chances for kill or hit rolls the same for the AI as for the human player? The first couple of games it seemed ok, but now it just seems the AI hits me a heck of a lot more than I hit it. I am playing on the default difficulty level. Maybe it's just that I am being reckless or using bad tactics, but I thought I'd ask. I know that in some past computer war games I've played, the AI was given a slight advantage - to make it "smarter" and more of a challenge.. Either way.. it's a good game.
Post #: 1
RE: Even rolls? - 5/13/2012 1:34:42 PM   
Joram

 

Posts: 3198
Joined: 7/15/2005
Status: offline
I'm pretty certain there are no advantages given to the AI dice. You can also always use the dice cam feature in SP.

(in reply to Ocean1)
Post #: 2
RE: Even rolls? - 5/13/2012 3:18:02 PM   
Erik Rutins

 

Posts: 37503
Joined: 3/28/2000
From: Vermont, USA
Status: offline
No, the AI always uses the same dice as you.

However, as you increase in difficulty, for each level above Easy it gets 25% more CAPs and an increased chance of higher unit quality. The combination of those two can lead to better combat results, but you should see when it uses its CAPs to boost combat rolls. Also, above Normal it gets 1 extra AP per unit.

Regards,

- Erik


_____________________________

Erik Rutins
CEO, Matrix Games LLC




For official support, please use our Help Desk: http://www.matrixgames.com/helpdesk/

Freedom is not Free.

(in reply to Joram)
Post #: 3
RE: Even rolls? - 5/13/2012 4:25:04 PM   
ericbabe


Posts: 11927
Joined: 3/23/2005
Status: offline
Here is the code for a unit attacking another unit, and the code for generating the results of an attack:

private void AttackPiece(GameTime gameTime, Context context, int apCost, Piece targetPiece, Random rand, int attackNo)
{
CohPiece attacker = ThisPiece;
CohPiece defender = targetPiece as CohPiece;
Player attackerPlayer = context.PlayerManager[attacker.PlayerName];
Player defenderPlayer = context.PlayerManager[defender.PlayerName];

if (attacker == null || defender == null)
return;

// attack strength
String modfDesc = "";
bool frontal;
int att;
int def;
GetAttackStats(context, targetPiece, apCost, out frontal, out att, out def, ref modfDesc, false);

// reveal attacker
attacker.Hider.Unhide();

// AI player can modify attack roll with caps now
// omitted...

// get attack roll
int roll1, roll2;
int baseRoll = MakeAttackRoll(context.GameScene.HexGame, rand, context.PlayerManager[attacker.PlayerName], out roll1, out roll2);
int modfRoll = baseRoll + att;

// zero roll bonus
context.NextRollBonus = 0;

// notify for attack
String msg = "";
if (modfRoll >= def)
{
// unhide the defender
defender.Hider.Unhide();

msg = String.Format(modfRoll != baseRoll ?
Resources.CohAttacker_AttackPiece__0__rolls__4__modified_by__2__and_hits__1__whose_defense_is__3__ :
Resources.CohAttacker_AttackPiece__0__rolls__4__and_hits__1__whose_defense_is__3__,
attacker.GetName(), defender.GetName(), modfRoll - baseRoll, def, baseRoll);
}
else
{
if (defender.Hider.Hidden)
{
if (attackNo == 0)
msg = String.Format(/*ss.Get*/(Resources.CohAttacker_AttackLocation__0__does_not_reveal_any_units___1__), attacker.GetName(), baseRoll);
}
else
{
msg = String.Format(modfRoll != baseRoll ?
Resources.CohAttacker_AttackPiece__0__rolls__4__modified_by__2__and_misses__1__whose_defense_is__3__ :
Resources.CohAttacker_AttackPiece__0__rolls__4__and_misses__1__whose_defense_is__3__,
attacker.GetName(), defender.GetName(), modfRoll - baseRoll, def, baseRoll);
}

}

// add modifiers to message
if (!defender.Hider.Hidden)
{
msg += @" (";
msg += modfDesc;
msg += @")";
}

CombatSubject.Report(msg, modfRoll >= def ? ReportColors.HitColor : ReportColors.Standard);

if (!defender.Hider.Hidden)
{
// is piece hidden damage revealed?
if (defender.GetDamage() != null &&
defender.HiddenDamage &&
(defender.GetDamage().FlankDefense != 0 ||
defender.GetDamage().FlankDefenseIsArmored != 0 ||
defender.GetDamage().FrontDefense != 0 ||
defender.GetDamage().FlankDefenseIsArmored != 0))
{
defender.HiddenDamage = false;
CombatSubject.Report(String.Format(/*ss.Get*/(Resources.CohAttacker_AttackPiece__0__damage_is_revealed___1_), defender.GetName(), defender.GetDamage().Name));

}
if (attacker.GetDamage() != null &&
attacker.HiddenDamage &&
(attacker.GetDamage().Attack != 0 ||
attacker.GetDamage().AttackVsArmor != 0 ||
attacker.GetDamage().Range != 0 ||
attacker.GetDamage().MinRange != 0))
{
attacker.HiddenDamage = false;
CombatSubject.Report(String.Format(/*ss.Get*/(Resources.CohAttacker_AttackPiece__0__damage_is_revealed___1_), attacker.GetName(), attacker.GetDamage().Name));
}
}

// roll on flying text
FlyingTextManager.AddFloatFade(gameTime, String.Format(Resources.CohAttacker_AttackPiece_Roll___0_, baseRoll),
Color.White, attacker, new Vector2(0, -30.0f * attackNo), roll1, roll2);

// get roll result
if (modfRoll >= def)
{
// hit
// give damage marker
bool instantKill = (modfRoll >= def + 4);
CohDamage damage;
instantKill |= GiveDamage(defender, out damage);

// is defender dead
bool defenderIsDead = instantKill || defender.Hp() <= 0;

// hey controller
context.GameScene.Controller.AddAttackSequence(attacker, defender, defender.MapPos,
defenderIsDead ? CohController.HitResult.Destroy : CohController.HitResult.Hit,
new Vector2(0, -30.0f * attackNo),
damage.Name);

// reveal hit piece
defender.Hider.Unhide();

// destroy if necessary
if (defenderIsDead)
{
PerformCombatKill(context, attacker, defender);
}
else
{
HeadlineSubject.Report(String.Format(/*ss.Get*/(Resources.CohAttacker_AttackPiece__0__is_damaged), defender.GetName()));
}
}
else
{
if (!defender.Hider.Hidden)
{
// miss
context.GameScene.Controller.AddAttackSequence(attacker, defender, defender.MapPos, CohController.HitResult.Miss,
new Vector2(0, -30.0f * attackNo), null);
HeadlineSubject.Report(String.Format(/*ss.Get*/(Resources.CohAttacker_AttackPiece__0__misses), attacker.GetName()));
}
}

// call event
if (PieceAttackingHandler != null)
PieceAttackingHandler(gameTime, attacker, defender, defender.MapPos);
}

and the code for generating the attack roll:

private static int MakeAttackRoll(Application.HexGame game, Random rand, Player player, out int roll1, out int roll2)
{
if (PreferenceManager.Instance.AreUsingDiceCamera && player.IsHuman && !NetworkFacade.Game.IsActiveGame)
{
try
{
game.SuspendUpdate = true;
_DiceForm = new DiceForm
{
TopMost = true
};
_DiceForm.ShowDialog();
roll1 = 0;
roll2 = 0;
game.SuspendUpdate = false;
return _DiceForm.RollResult;
}
catch (Exception)
{
CombatSubject.Report(Resources.CohAttacker_MakeAttackRoll_Dice_Camera_failed_to_initialize_);
game.SuspendUpdate = false;
return Random2D6(rand, out roll1, out roll2);
}
}
else
return Random2D6(rand, out roll1, out roll2);
}

Here is the code to generate Random2D6:

private static int Random2D6(Random rand, out int roll1, out int roll2)
{
roll1 = rand.Next(6) + 1;
roll2 = rand.Next(6) + 1;
return roll1 + roll2;
}



< Message edited by ericbabe -- 5/13/2012 4:26:24 PM >


_____________________________



(in reply to Erik Rutins)
Post #: 4
RE: Even rolls? - 5/13/2012 4:26:08 PM   
ericbabe


Posts: 11927
Joined: 3/23/2005
Status: offline
Here is the code for our pseudorandom number generator. Note that it derives from System.Random and it is an instance of this class we pass as a parameter to Random2D6:

namespace HexGame.WCS.RandomNumbers
{
public class MersenneTwister : System.Random
{
// number generated since last reseed
private int NumberGenerated;

/* Period parameters */
private const int N = 624;
private const int M = 397;
private const uint MATRIX_A = 0x9908b0df; /* constant vector a */
private const uint UPPER_MASK = 0x80000000; /* most significant w-r bits */
private const uint LOWER_MASK = 0x7fffffff; /* least significant r bits */

/* Tempering parameters */
private const uint TEMPERING_MASK_B = 0x9d2c5680;
private const uint TEMPERING_MASK_C = 0xefc60000;

private static uint TEMPERING_SHIFT_U(uint y) { return (y >> 11); }
private static uint TEMPERING_SHIFT_S(uint y) { return (y << 7); }
private static uint TEMPERING_SHIFT_T(uint y) { return (y << 15); }
private static uint TEMPERING_SHIFT_L(uint y) { return (y >> 18); }

private uint[] mt = new uint[N]; /* the array for the state vector */

private short mti;

private static uint[] mag01 = { 0x0, MATRIX_A };

/* initializing the array with a NONZERO seed */
public MersenneTwister(uint seed)
{
/* setting initial seeds to mt[N] using */
/* the generator Line 25 of Table 1 in */
/* [KNUTH 1981, The Art of Computer Programming */
/* Vol. 2 (2nd Ed.), pp102] */
mt[0] = seed & 0xffffffffU;
for (mti = 1; mti < N; ++mti)
{
mt[mti] = (69069 * mt[mti - 1]) & 0xffffffffU;
}

// reset number generated
NumberGenerated = 0;
}
public MersenneTwister()
: this(4357) /* a default initial seed is used */
{
}

public String GetCurrentState()
{
return string.Format(@"{0}.{1}", mt[0].ToString(), NumberGenerated);
}

protected uint GenerateUInt()
{
uint y;

/* mag01[x] = x * MATRIX_A for x=0,1 */
if (mti >= N) /* generate N words at one time */
{
short kk = 0;

for (; kk < N - M; ++kk)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1];
}

for (; kk < N - 1; ++kk)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1];
}

y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1];

mti = 0;
}

y = mt[mti++];
y ^= TEMPERING_SHIFT_U(y);
y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
y ^= TEMPERING_SHIFT_L(y);

// remember we generated another one
NumberGenerated++;

return y;
}

public virtual uint NextUInt()
{
return this.GenerateUInt();
}

public virtual uint NextUInt(uint maxValue)
{
return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / maxValue));
}

public virtual uint NextUInt(uint minValue, uint maxValue) /* throws ArgumentOutOfRangeException */
{
if (minValue >= maxValue)
{
throw new ArgumentOutOfRangeException();
}

return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / (maxValue - minValue)) + minValue);
}

public override int Next()
{
return this.Next(int.MaxValue);
}

public override int Next(int maxValue) /* throws ArgumentOutOfRangeException */
{
if (maxValue <= 1)
{
if (maxValue < 0)
{
throw new ArgumentOutOfRangeException();
}

return 0;
}

return (int)(this.NextDouble() * maxValue);
}

public override int Next(int minValue, int maxValue)
{
if (maxValue < minValue)
{
throw new ArgumentOutOfRangeException();
}
else if (maxValue == minValue)
{
return minValue;
}
else
{
return this.Next(maxValue - minValue) + minValue;
}
}

public override void NextBytes(byte[] buffer) /* throws ArgumentNullException*/
{
int bufLen = buffer.Length;

if (buffer == null)
{
throw new ArgumentNullException();
}

for (int idx = 0; idx < bufLen; ++idx)
{
buffer[idx] = (byte)this.Next(256);
}
}

public override double NextDouble()
{
return (double)this.GenerateUInt() / ((ulong)uint.MaxValue + 1);
}
}
}

< Message edited by ericbabe -- 5/13/2012 4:27:54 PM >


_____________________________



(in reply to ericbabe)
Post #: 5
Page:   [1]
All Forums >> [New Releases from Matrix Games] >> Conflict of Heroes Series >> Even rolls? Page: [1]
Jump to:





New Messages No New Messages
Hot Topic w/ New Messages Hot Topic w/o New Messages
Locked w/ New Messages Locked w/o New Messages
 Post New Thread
 Reply to Message
 Post New Poll
 Submit Vote
 Delete My Own Post
 Delete My Own Thread
 Rate Posts


Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI

0.842