Skip to content

Instantly share code, notes, and snippets.

@ZeroStride
Created April 25, 2010 06:09
Show Gist options
  • Save ZeroStride/378195 to your computer and use it in GitHub Desktop.
Save ZeroStride/378195 to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace MonsterTest
{
class MainClass
{
public static void Main (string[] args)
{
// Open a file for the results.
Monster.Rng = new Random();
const int numDudes = 100;
using(FileStream resStream = File.Open("outdata.csv", FileMode.OpenOrCreate))
{
AppendValue(resStream, "Strength, Mojo, Soak, Willpower, Reflex, Intelligence\r\n");
// Create some monsters
List<Monster> monsters = new List<Monster>();
for (int m = 0; m < numDudes; m++)
{
monsters.Add(new Monster());
}
// Round robin the monsters
List<int> wins = new List<int>();
for (int i = 0; i < numDudes; i++)
{
wins.Add(0);
for (int j = 0; j < numDudes; j++)
{
// Don't fight ourselves
if (i == j)
continue;
wins[i] += monsters[i].Fight(monsters[j]) ? 1 : 0;
}
}
List<KeyValuePair<int, int>> kvp = new List<KeyValuePair<int, int>>();
for (int i = 0; i < wins.Count; i++)
kvp.Add(new KeyValuePair<int, int>(i, wins[i]));
// Sort
kvp.Sort(delegate(KeyValuePair<int, int> x, KeyValuePair<int, int> y) { return x.Value.CompareTo(y.Value); });
for (int w = wins.Count - 1; w > wins.Count - 6; w--)
AppendMonster(resStream, monsters[kvp[w].Key]);
}
Console.WriteLine ("Hello World!");
}
private static void AppendValue(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
}
private static void AppendMonster(FileStream fs, Monster value)
{
string monsterString =
value.Strength.ToString() + ", " +
value.Mojo.ToString() + ", " +
value.Soak.ToString() + ", " +
value.Willpower.ToString() + ", " +
value.Reflex.ToString() + ", " +
value.Intelligence.ToString() + "\r\n";
AppendValue(fs, monsterString);
}
}
}
using System;
namespace MonsterTest
{
public class Monster
{
static public Random Rng { get; set; }
#region Attributes
public float Strength
{
get
{
return _strength;
}
}
public float Mojo
{
get
{
return _mojo;
}
}
public float Soak
{
get
{
return _soak;
}
}
public float Willpower
{
get
{
return _willpower;
}
}
public float Reflex
{
get
{
return _reflex;
}
}
public float Intelligence
{
get
{
return _intelligence;
}
}
#endregion
#region Skill Check
public float AvoidPhysical
{
get
{
return (Reflex * 0.5f + Soak * 0.5f);
}
}
public float AvoidMental
{
get
{
return (Reflex * 0.5f + Willpower * 0.5f);
}
}
public float TakePhysical
{
get
{
return (Soak * 0.75f + Strength * 0.25f);
}
}
public float TakeMental
{
get
{
return (Willpower * 0.75f + Mojo * 0.25f);
}
}
public float CausePhysical
{
get
{
return (Strength * 0.75f + Intelligence * 0.25f);
}
}
public float CauseMental
{
get
{
return (Mojo * 0.75f + Intelligence * 0.25f);
}
}
public float HitPhysical
{
get
{
return (Strength * 0.5f + Reflex * 0.5f);
}
}
public float HitMental
{
get
{
return (Mojo * 0.5f + Reflex * 0.5f);
}
}
#endregion
// This is super hacky don't implement it like this or anything
public bool Fight(Monster otherGuy)
{
bool weFacePunch = (HitPhysical > HitMental);
bool theyFacePunch = (otherGuy.HitPhysical > otherGuy.HitMental);
int won = 0;
int lost = 0;
float myLife = 1000.0f;
float otherLife = 1000.0f;
for (int i = 0; i < 5; i++)
{
while (myLife > 0.0f && otherLife > 0.0f)
{
// Our attack
if (weFacePunch)
{
// Can we hit him?
if ((HitPhysical + (float)Rng.NextDouble() * 1000.0f) >
(otherGuy.AvoidPhysical + (float)Rng.NextDouble() * 1000.0f))
{
otherLife -= Math.Max(1.0f, CausePhysical - otherGuy.TakePhysical);
}
}
else
{
if ((HitMental + (float)Rng.NextDouble() * 1000.0f) >
(otherGuy.AvoidMental + (float)Rng.NextDouble() * 1000.0f))
{
otherLife -= Math.Max(1.0f, CauseMental - otherGuy.TakeMental);
}
}
// Their attack
if (theyFacePunch)
{
if ((otherGuy.HitPhysical + (float)Rng.NextDouble() * 1000.0f) >
(AvoidPhysical + (float)Rng.NextDouble() * 1000.0f))
{
myLife -= Math.Max(1.0f, otherGuy.CausePhysical - TakePhysical);
}
}
else
{
if ((otherGuy.HitMental + (float)Rng.NextDouble() * 1000.0f) >
(AvoidMental + (float)Rng.NextDouble() * 1000.0f))
{
myLife -= Math.Max(1.0f, otherGuy.CauseMental - TakeMental);
}
}
}
// Victory?
if (myLife > otherLife)
won++;
else
lost++;
}
return won > lost;
}
public Monster(int abilityScale = 200)
{
// Figure out if this is a physical monster or a mental monster
bool isPhysical = (Rng.NextDouble() > 0.5);
_strength = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 1.0 : 0.3));
_mojo = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 0.3 : 1.0));
_soak = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 1.0 : 0.6));
_willpower = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 0.6 : 1.0));
_reflex = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 1.0 : 0.5));
_intelligence = (float)(abilityScale * Rng.NextDouble() * (isPhysical ? 0.5 : 1.0));
}
float _strength;
float _mojo;
float _soak;
float _willpower;
float _reflex;
float _intelligence;
}
}
@noonat
Copy link

noonat commented Apr 25, 2010

weFacePunch and theyFacePunch -- hall of fame variable names.

@ZeroStride
Copy link
Author

This is a total braindead simulation, but it seems to kind of work. I am impressed with it, hehe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment