Browse Source

[experiments2] Moar. And that'll be it.

Michał W. Urbańczyk 12 years ago
parent
commit
0242f0d580

+ 44 - 4
AI/BattleAI/BattleAI.cpp

@@ -557,17 +557,44 @@ std::vector<BattleHex> CBattleAI::getTargetsToConsider( const CSpell *spell ) co
 
 boost::optional<BattleAction> CBattleAI::considerFleeingOrSurrendering()
 {
+	if(tacticInfo->expectedLength() >= 2  || tacticInfo->totalValue() > 0)
+		return boost::none;
+
+	BattleAction ba;
+	ba.side = cb->battleGetMySide();
+	ba.stackNumber = cb->battleActiveStack()->ID;
+
 	if(cb->battleCanSurrender(playerID))
 	{
+		double armyValue = 0;
+		BOOST_FOREACH(auto stack, cb->battleGetStacks(CBattleInfoEssentials::ONLY_MINE))
+		{
+			armyValue += stack->count*stack->MaxHealth()*priorities.stackEvaluator(stack);
+		}
 
+		double cost = cb->battleGetSurrenderCost() * priorities.generalResourceValueModifier * priorities.resourceTypeBaseValues[Res::GOLD];
+		if(armyValue + priorities.heroValue > cost + tacticInfo->ourPotential)
+		{
+			ba.actionType = Battle::SURRENDER;
+			return ba;
+		}
 	}
 	if(cb->battleCanFlee())
 	{
-
+		if(priorities.heroValue > tacticInfo->ourPotential)
+		{
+			ba.actionType = Battle::RETREAT;
+			return ba;
+		}
 	}
 	return boost::none;
 }
 
+void CBattleAI::setPriorities(const Priorities &priorities)
+{
+	this->priorities = priorities;
+}
+
 ThreatMap::ThreatMap(const CStack *Endangered) : endangered(Endangered)
 {
 	sufferedDamage.fill(0);
@@ -634,8 +661,8 @@ const TBonusListPtr StackWithBonuses::getAllBonuses(const CSelector &selector, c
 
 int AttackPossibility::damageDiff() const
 {
-	const auto dealtDmgValue = priorities.stackEvaluator(enemy) * damageDealt;
-	const auto receivedDmgValue = priorities.stackEvaluator(attack.attacker) * damageReceived;
+	const auto dealtDmgValue = ai->priorities.stackEvaluator(enemy) * damageDealt;
+	const auto receivedDmgValue = ai->priorities.stackEvaluator(attack.attacker) * damageReceived;
 	return dealtDmgValue - receivedDmgValue;
 }
 
@@ -675,7 +702,9 @@ AttackPossibility AttackPossibility::evaluate(const BattleAttackInfo &AttackInfo
 		//TODO what about defender? should we break? but in pessimistic scenario defender might be alive
 	}
 
-	//TODO LUCK!!!!!!!!!!!!
+	double luck = curBai.attackerBonuses->LuckVal();
+	if(luck > 0)
+		ap.damageDealt *= (1 + luck/12.0);
 
 	//TODO other damage related to attack (eg. fire shield and other abilities)
 
@@ -770,6 +799,17 @@ TacticInfo::TacticInfo(const HypotheticChangesToBattleState &state /*= Hypotheti
 		enemyPotential += targets[enemyStack].bestActionValue();
 		enemyhealth += (enemyStack->count-1) * enemyStack->MaxHealth() + enemyStack->firstHPleft;
 	}
+
+	if(ourPotential < 0)
+	{
+		enemyPotential -= ourPotential;
+		ourPotential = 0;
+	}
+	if(enemyPotential < 0)
+	{
+		ourPotential -= enemyPotential;
+		enemyPotential = 0;
+	}
 }
 
 double TacticInfo::totalValue() const

+ 5 - 1
AI/BattleAI/BattleAI.h

@@ -132,11 +132,13 @@ class CBattleAI : public CBattleGameInterface
 	
 	//Previous setting of cb 
 	bool wasWaitingForRealize, wasUnlockingGs;
-
 	unique_ptr<TacticInfo> tacticInfo;
 
 	void print(const std::string &text) const;
 public:
+	Priorities priorities;
+
+
 	CBattleAI(void);
 	~CBattleAI(void);
 
@@ -145,6 +147,8 @@ public:
 	void actionStarted(const BattleAction &action) OVERRIDE;//occurs BEFORE every action taken by any stack or by the hero
 	BattleAction activeStack(const CStack * stack) OVERRIDE; //called when it's turn of that stack
 
+	void setPriorities(const Priorities &priorities) OVERRIDE;
+
 	void battleAttack(const BattleAttack *ba) OVERRIDE; //called when stack is performing attack
 	void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE; //called when stack receives damage (after battleAttack())
 	void battleEnd(const BattleResult *br) OVERRIDE;

+ 0 - 3
AI/BattleAI/BattleAI.vcxproj

@@ -144,9 +144,6 @@
     <ClInclude Include="BattleAI.h" />
     <ClInclude Include="..\..\Global.h" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="ClassDiagram.cd" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>

+ 0 - 5
AI/BattleAI/main.cpp

@@ -9,11 +9,6 @@
 
 const char *g_cszAiName = "Battle AI";
 
-extern "C" DLL_EXPORT int GetGlobalAiVersion()
-{
-	return AI_INTERFACE_VER;
-}
-
 extern "C" DLL_EXPORT void GetAiName(char* name)
 {
 	strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);

+ 40 - 0
Runner/ReadMe.txt

@@ -0,0 +1,40 @@
+========================================================================
+    CONSOLE APPLICATION : Runner Project Overview
+========================================================================
+
+AppWizard has created this Runner application for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your Runner application.
+
+
+Runner.vcxproj
+    This is the main project file for VC++ projects generated using an Application Wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+Runner.vcxproj.filters
+    This is the filters file for VC++ projects generated using an Application Wizard. 
+    It contains information about the association between the files in your project 
+    and the filters. This association is used in the IDE to show grouping of files with
+    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+    "Source Files" filter).
+
+Runner.cpp
+    This is the main application source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named Runner.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////

+ 47 - 0
Runner/Runner.cpp

@@ -0,0 +1,47 @@
+// Runner.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+using namespace std;
+
+void runBattle(string battle, string left, string right)
+{
+	string command = "VCMI_client -b" + battle + " --ai=" + left + " --ai=" + right + " --noGUI";
+	system(command.c_str());
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+	const int N = 5;
+
+	std::vector<std::string> ais;
+	ais.push_back("StupidAI");
+	ais.push_back("BattleAI");
+
+	std::vector<std::string> battles;
+	battles.push_back("bitwa1.json");
+	battles.push_back("bitwa2.json");
+	battles.push_back("bitwa3.json");
+	battles.push_back("bitwa4.json");
+	battles.push_back("bitwa5.json");
+	battles.push_back("bitwa6.json");
+
+	for(auto &battle : battles)
+	{
+		auto runN = [&](string left, string right)
+		{
+			for(int i  =0; i < N; i++)
+				runBattle(battle, left, right);
+		};
+
+		runN(ais[0], ais[0]);
+		runN(ais[0], ais[1]);
+		runN(ais[1], ais[0]);
+		runN(ais[1], ais[1]);
+	}
+
+
+	return 0;
+}
+

+ 100 - 0
Runner/Runner.vcxproj

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{D80625BB-FD36-4089-8CD2-E0489B19EED5}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>Runner</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\VCMI_global_debug.props" />
+    <Import Project="..\VCMI_global.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\VCMI_global_release.props" />
+    <Import Project="..\VCMI_global.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(VCMI_Out)</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(VCMI_Out)</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions>/Zm130 %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Runner.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 36 - 0
Runner/Runner.vcxproj.filters

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Runner.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 8 - 0
Runner/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// Runner.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file

+ 15 - 0
Runner/stdafx.h

@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+#include "../Global.h"
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: reference additional headers your program requires here

+ 8 - 0
Runner/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>

+ 11 - 0
VCMI_VS11.sln

@@ -45,6 +45,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisitObjects", "AI\VisitObj
 		{B952FFC5-3039-4DE1-9F08-90ACDA483D8F} = {B952FFC5-3039-4DE1-9F08-90ACDA483D8F}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner\Runner.vcxproj", "{D80625BB-FD36-4089-8CD2-E0489B19EED5}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -180,6 +182,15 @@ Global
 		{D3126B35-650E-46C8-A336-1D6640FBFFD0}.Release|Win32.Build.0 = RD|Win32
 		{D3126B35-650E-46C8-A336-1D6640FBFFD0}.Release|x64.ActiveCfg = RD|x64
 		{D3126B35-650E-46C8-A336-1D6640FBFFD0}.Release|x64.Build.0 = RD|x64
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Debug|Win32.Build.0 = Debug|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Debug|x64.ActiveCfg = Debug|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.RD|Win32.ActiveCfg = Release|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.RD|Win32.Build.0 = Release|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.RD|x64.ActiveCfg = Release|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Release|Win32.ActiveCfg = Release|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Release|Win32.Build.0 = Release|Win32
+		{D80625BB-FD36-4089-8CD2-E0489B19EED5}.Release|x64.ActiveCfg = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 37 - 0
bitwy/bitwa1.json

@@ -0,0 +1,37 @@
+{
+	"terType" : 1,
+	"bfieldType" : 0,
+	"obstacles" : [155], //vector of positions or vectored pairs [type, pos]
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[0, 1], [1, 1]],
+			"heroid" : 0,
+		},
+		{
+			"side" : 1,
+			"army" : [[6, 1], [6, 1]],
+		}
+	],
+	
+	"creatures" : 
+	[
+		{
+			"id" : 0,
+			"dmg" : 500,
+			"speed" : 7
+		},
+		{
+			"id" : 1,
+			"dmg" : 500,
+			"speed" : 5
+		},
+		{
+			"id" : 6,
+			"dmg" : 500,
+			"speed" : 6
+		},
+	]
+}

+ 34 - 0
bitwy/bitwa2.json

@@ -0,0 +1,34 @@
+{
+	"terType" : 1,
+	"bfieldType" : 0,
+	"obstacles" : [111, [28, 7], 88, 122, 139, 156, 173], //vector of positions or vectored pairs [type, pos]
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[95, 1]],
+			"heroid" : 0,			
+			"heroPrimSkills" : [4, 4, 5, 10],
+			"spells" : [28,61,15, 27, 54, 53, 44, 41, 42]
+		},
+		{
+			"side" : 1,
+			"army" : [[111, 1]]
+		}
+	],
+	
+	"creatures" : 
+	[
+		{
+			"id" : 95,
+			"shoots" : 1000,
+			"HP" : 1
+		},
+		
+		{
+			"id" : 111,
+			"speed" : 2
+		}
+	]
+}

+ 23 - 0
bitwy/bitwa3.json

@@ -0,0 +1,23 @@
+{
+	"terType" : 1,
+	"bfieldType" : 1,
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[90, 1],[90, 50],[1, 200],[17, 100], [60, 75], [19, 1],[19, 100]],
+			"heroid" : 0,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+			"spells" : [28,61,15, 27, 41, 42, 15]
+		},
+		{
+			"side" : 1,
+			"army" : [[90, 1],[90, 50],[1, 200],[17, 100], [60, 75], [19, 1],[19, 100]],
+			"heroid" : 1,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+			"heroSecSkills" : [[15,2]],
+			"spells" : [28,61,15, 27, 41, 42, 15, 20]
+		},
+	],
+}

+ 20 - 0
bitwy/bitwa4.json

@@ -0,0 +1,20 @@
+{
+	"terType" : 1,
+	"bfieldType" : 1,
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[90, 1],[90, 50],[1, 200],[17, 100], [60, 75], [19, 1],[19, 100]],
+			"heroid" : 0,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+		},
+		{
+			"side" : 1,
+			"army" : [[90, 1],[90, 50],[1, 200],[17, 100], [60, 75], [19, 1],[19, 100]],
+			"heroid" : 1,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+		},
+	],
+}

+ 23 - 0
bitwy/bitwa5.json

@@ -0,0 +1,23 @@
+{
+	"terType" : 1,
+	"bfieldType" : 1,
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[1, 128],[3, 64],[5, 32],[7, 16], [9, 8], [11, 4],[13, 2]],
+			"heroid" : 0,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+			"spells" : [28,61,15, 27, 41, 42, 15, 23, 46]
+
+		},
+		{
+			"side" : 1,
+			"army" : [[1, 128],[3, 64],[5, 32],[7, 16], [9, 8], [11, 4],[13, 2]],
+			"heroid" : 1,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+			"spells" : [28,61,15, 27, 41, 42, 15, 23, 46]
+		},
+	],
+}

+ 21 - 0
bitwy/bitwa6.json

@@ -0,0 +1,21 @@
+{
+	"terType" : 1,
+	"bfieldType" : 1,
+	
+	"sides" : 
+	[
+		{
+			"side" : 0,
+			"army" : [[1, 128],[3, 64],[5, 32],[7, 16], [9, 8], [11, 4],[13, 2]],
+			"heroid" : 0,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+
+		},
+		{
+			"side" : 1,
+			"army" : [[1, 128],[3, 64],[5, 32],[7, 16], [9, 8], [11, 4],[13, 2]],
+			"heroid" : 1,			
+			"heroPrimSkills" : [4, 4, 10, 10],
+		},
+	],
+}

+ 3 - 0
client/battle/CBattleInterfaceClasses.cpp

@@ -596,6 +596,9 @@ void CClickableHex::clickRight(tribool down, bool previousState)
 void CStackQueue::update()
 {
 	stacksSorted.clear();
+	if(!owner->curInt)
+		return;
+
 	owner->curInt->cb->battleGetStackQueue(stacksSorted, stackBoxes.size());
 	if(stacksSorted.size())
 	{

+ 2 - 0
lib/CGameInterface.cpp

@@ -11,6 +11,7 @@
 	#include <dlfcn.h>
 #endif
 #include "Connection.h"
+#include "VCMI_Lib.h"
 
 /*
  * CGameInterface.cpp, part of VCMI engine
@@ -303,4 +304,5 @@ Priorities::Priorities()
 	generalResourceValueModifier = 1.;
 	range::copy(VLC->objh->resVals, std::back_inserter(resourceTypeBaseValues));
 	stackEvaluator = [](const CStack*){ return 1.0; };
+	heroValue = 50;
 }

+ 1 - 1
lib/CGameInterface.h

@@ -82,7 +82,7 @@ struct DLL_LINKAGE Priorities
 	double generalResourceValueModifier;
 	std::vector<double> resourceTypeBaseValues;
 	std::function<double(const CStack *)> stackEvaluator;
-
+	double heroValue;
 
 	Priorities();
 };

+ 0 - 3
lib/VCMI_lib.vcxproj

@@ -291,9 +291,6 @@
     <ClInclude Include="VCMI_Lib.h" />
     <ClInclude Include="VCMIDirs.h" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="ClassDiagram1.cd" />
-  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>

+ 21 - 3
server/CGameHandler.cpp

@@ -6193,6 +6193,16 @@ void CGameHandler::duelFinished()
 	logGlobal->debugStream() << boost::format("Winner side %d\nWinner casualties:") 
 		% (int)battleResult.data->winner;
 
+
+	double initialHP = 0;
+	BOOST_FOREACH(auto &stack, gs->curB->belligerents[battleResult.data->winner]->stacks)
+	{
+		initialHP += stack.second->count * stack.second->type->AIValue;
+	}
+
+
+	logGlobal->debugStream() << boost::format("Total army value points: %lf") % initialHP;
+
 	for(auto i = battleResult.data->casualties[battleResult.data->winner].begin(); i != battleResult.data->casualties[battleResult.data->winner].end(); i++)
 	{
 		const CCreature *c = VLC->creh->creatures[i->first];
@@ -6205,12 +6215,20 @@ void CGameHandler::duelFinished()
 	time_t timeNow;
 	time(&timeNow);
 
+	double casualtiesRatio = (1 - casualtiesPoints/initialHP);
+	
+	if(battleResult.data->winner)
+	{
+		casualtiesPoints = -casualtiesPoints;
+		casualtiesRatio = -casualtiesRatio;
+	}
+
 	std::ofstream out(cmdLineOptions["resultsFile"].as<std::string>(), std::ios::app);
 	if(out)
 	{
-		out << boost::format("%s\t%s\t%s\t%d\t%d\t%d\t%s\n") % si->mapname % getName(0) % getName(1)
-			% battleResult.data->winner % battleResult.data->result % casualtiesPoints 
-			% asctime(localtime(&timeNow));
+		out << boost::format("%s\t%s\t%s\t%d\t%d\t%d\t%lf\t%s") % si->mapname % getName(0) % getName(1)
+			% (int)battleResult.data->winner % (int)battleResult.data->result % casualtiesPoints 
+			% casualtiesRatio % asctime(localtime(&timeNow));
 	}
 	else
 	{